From 93cdf2b090ca1bd6b2cd77e7e15b41f3d0f8f5aa Mon Sep 17 00:00:00 2001 From: Muhammad Saffi Ullah <42832684+saffiullah200@users.noreply.github.com> Date: Mon, 5 Aug 2024 20:55:44 +0200 Subject: [PATCH 01/67] library upgrade --- eslint.config.mjs | 15 + package-lock.json | 17900 +++++++++++--------- package.json | 78 +- src/helpers/constants.js | 258 +- src/helpers/db-connector.js | 203 +- src/helpers/index.js | 215 +- src/helpers/venue-review-summary.js | 55 +- src/index.js | 162 +- src/models/activation-ticket.js | 96 +- src/models/event.js | 282 +- src/models/password-ticket.js | 52 +- src/models/petition.js | 118 +- src/models/photo.js | 132 +- src/models/refresh-token.js | 54 +- src/models/review.js | 244 +- src/models/team.js | 124 +- src/models/user.js | 386 +- src/models/venue.js | 630 +- src/routes/auth/activate-account.js | 278 +- src/routes/auth/facebook-sign-in.js | 401 +- src/routes/auth/forgotten-password.js | 176 +- src/routes/auth/generate-token.js | 110 +- src/routes/auth/google-sign-in.js | 377 +- src/routes/auth/index.js | 54 +- src/routes/auth/reset-password.js | 266 +- src/routes/auth/sign-in.js | 139 +- src/routes/auth/sign-out.js | 68 +- src/routes/auth/sign-up.js | 316 +- src/routes/auth/validations.js | 310 +- src/routes/events/create-event.js | 374 +- src/routes/events/delete-event.js | 260 +- src/routes/events/edit-event.js | 764 +- src/routes/events/get-event.js | 414 +- src/routes/events/index.js | 62 +- src/routes/events/join-event.js | 268 +- src/routes/events/leave-event.js | 138 +- src/routes/events/list-events.js | 183 +- src/routes/events/validations.js | 956 +- src/routes/index.js | 50 +- src/routes/others/contact.js | 74 +- src/routes/others/index.js | 22 +- src/routes/others/migrate-scores.js | 61 +- src/routes/others/validations.js | 74 +- src/routes/petitions/create-petition.js | 948 +- src/routes/petitions/edit-petition.js | 1112 +- src/routes/petitions/index.js | 38 +- src/routes/petitions/list-petitions.js | 554 +- src/routes/petitions/validations.js | 158 +- src/routes/photos/create-photo.js | 230 +- src/routes/photos/delete-photo.js | 94 +- src/routes/photos/index.js | 34 +- src/routes/reviews/ban-review.js | 78 +- src/routes/reviews/create-review.js | 1112 +- src/routes/reviews/edit-review.js | 434 +- src/routes/reviews/flag-review.js | 100 +- src/routes/reviews/index.js | 58 +- src/routes/reviews/list-reviews.js | 368 +- src/routes/reviews/validations.js | 752 +- src/routes/reviews/vote-review.js | 98 +- src/routes/teams/create-team.js | 186 +- src/routes/teams/delete-team.js | 230 +- src/routes/teams/edit-team.js | 410 +- src/routes/teams/get-team.js | 288 +- src/routes/teams/index.js | 46 +- src/routes/teams/join-team.js | 196 +- src/routes/teams/leave-team.js | 118 +- src/routes/teams/list-teams.js | 208 +- src/routes/teams/validations.js | 268 +- src/routes/users/archive-user.js | 202 +- src/routes/users/block-user.js | 78 +- src/routes/users/change-password.js | 128 +- src/routes/users/create-user.js | 303 +- src/routes/users/delete-user.js | 72 +- src/routes/users/edit-user.js | 320 +- src/routes/users/get-profile.js | 186 +- src/routes/users/get-user.js | 254 +- src/routes/users/index.js | 86 +- src/routes/users/list-users.js | 150 +- src/routes/users/unblock-user.js | 82 +- src/routes/users/validations.js | 598 +- src/routes/venues/archive-venue.js | 78 +- src/routes/venues/get-venue.js | 695 +- src/routes/venues/index.js | 38 +- src/routes/venues/list-venues.js | 1272 +- src/routes/venues/validations.js | 308 +- src/scripts/db/import-events.js | 308 +- src/scripts/db/import-reviews.js | 298 +- src/scripts/db/import-teams.js | 540 +- src/scripts/db/import-users.js | 550 +- src/scripts/db/import-venues.js | 364 +- src/scripts/db/old-schemas/event.js | 166 +- src/scripts/db/old-schemas/photo.js | 74 +- src/scripts/db/old-schemas/review.js | 162 +- src/scripts/db/old-schemas/team.js | 98 +- src/scripts/db/old-schemas/user.js | 250 +- src/scripts/db/old-schemas/venue.js | 238 +- src/scripts/db/update-events-locations.js | 300 +- src/scripts/db/update-events-posters.js | 320 +- src/scripts/db/update-events-reviews.js | 208 +- src/scripts/db/update-users-avatars.js | 412 +- 100 files changed, 22983 insertions(+), 21472 deletions(-) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..902e474 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,15 @@ +import globals from "globals"; +import pluginJs from "@eslint/js"; + +export default [ + { files: ["**/*.js"], languageOptions: { sourceType: "commonjs" } }, + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + }, + }, + pluginJs.configs.recommended, +]; diff --git a/package-lock.json b/package-lock.json index 93eead2..860e757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6530 +1,7825 @@ { "name": "api", - "version": "1.0.0", - "lockfileVersion": 1, + "version": "2.0.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@samverschueren/stream-to-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", - "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "packages": { + "": { + "name": "api", + "version": "2.0.0", + "dependencies": { + "aws-sdk": "2.1660.0", + "axios": "1.7.2", + "bcrypt-nodejs": "0.0.3", + "body-parser": "1.20.2", + "cors": "2.8.5", + "dotenv": "16.4.5", + "express": "4.19.2", + "form-data": "4.0.0", + "freemail": "1.7.0", + "google-auth-library": "9.11.0", + "helmet": "7.1.0", + "ip": "2.0.1", + "jimp": "0.22.12", + "jsonwebtoken": "9.0.2", + "lodash": "4.17.21", + "moment": "2.30.1", + "moment-timezone": "0.5.45", + "mongodb-uri": "0.9.7", + "mongoose": "8.5.1", + "morgan": "1.10.0", + "multer": "1.3.0", + "nodemailer": "6.9.14", + "now": "11.4.6", + "randomstring": "1.3.0", + "raven": "2.6.0", + "speakingurl": "14.0.1", + "validator": "13.12.0" + }, + "devDependencies": { + "@eslint/js": "^9.7.0", + "commitizen": "4.3.0", + "cross-env": "7.0.3", + "cz-conventional-changelog": "3.3.0", + "eslint": "^9.7.0", + "globals": "^15.8.0", + "gulp": "5.0.0", + "gulp-eslint-new": "^2.2.0", + "gulp-nodemon": "^2.2.1", + "husky": "9.1.1", + "lint-staged": "15.2.7", + "prettier": "3.3.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, - "requires": { - "any-observable": "^0.3.0" + "optional": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6.9.0" } }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, - "requires": { - "acorn": "^3.0.4" + "optional": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", + "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", + "dev": true, + "optional": true, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "@commitlint/types": "^19.0.3", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" } }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "node_modules/@commitlint/execute-rule": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", + "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=v18" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true + "node_modules/@commitlint/load": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", + "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", + "dev": true, + "optional": true, + "dependencies": { + "@commitlint/config-validator": "^19.0.3", + "@commitlint/execute-rule": "^19.0.0", + "@commitlint/resolve-extends": "^19.1.0", + "@commitlint/types": "^19.0.3", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^5.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "node_modules/@commitlint/load/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, - "requires": { - "string-width": "^2.0.0" + "optional": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", + "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", + "dev": true, + "optional": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "@commitlint/config-validator": "^19.0.3", + "@commitlint/types": "^19.0.3", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" } }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true + "node_modules/@commitlint/types": { + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", + "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", + "dev": true, + "optional": true, + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "node_modules/@commitlint/types/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, - "requires": { - "ansi-wrap": "0.1.0" + "optional": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "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" + } }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "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" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } }, - "any-observable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", - "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", - "dev": true + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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" }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "append-field": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", - "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "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" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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 }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@eslint/js": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true, - "requires": { - "arr-flatten": "^1.0.1" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "arr-flatten": { + "node_modules/@gulpjs/messages": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", + "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true + "node_modules/@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "dev": true, + "dependencies": { + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0" + } }, - "array-each": { + "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true + "node_modules/@jimp/bmp": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", + "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "bmp-js": "^0.1.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "array-uniq": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", - "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=" + "node_modules/@jimp/core": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", + "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "exif-parser": "^0.1.12", + "file-type": "^16.5.4", + "isomorphic-fetch": "^3.0.0", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.6.0" + } }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true + "node_modules/@jimp/core/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" + "node_modules/@jimp/custom": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", + "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", + "dependencies": { + "@jimp/core": "^0.22.12" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "node_modules/@jimp/gif": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz", + "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "gifwrap": "^0.10.1", + "omggif": "^1.0.9" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "node_modules/@jimp/jpeg": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz", + "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "jpeg-js": "^0.4.4" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" + "node_modules/@jimp/plugin-blit": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz", + "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==", + "dependencies": { + "@jimp/utils": "^0.22.12" }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-blur": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz", + "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==", "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - } + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" } }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true + "node_modules/@jimp/plugin-circle": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz", + "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "node_modules/@jimp/plugin-color": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz", + "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "tinycolor2": "^1.6.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "node_modules/@jimp/plugin-contain": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz", + "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5", + "@jimp/plugin-scale": ">=0.3.5" + } }, - "aws-sdk": { - "version": "2.94.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.94.0.tgz", - "integrity": "sha1-cEPePvjCTLarS/I18I2H2EFz4XQ=", - "requires": { - "buffer": "4.9.1", - "crypto-browserify": "1.0.9", - "events": "^1.1.1", - "jmespath": "0.15.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "uuid": "3.0.1", - "xml2js": "0.4.17", - "xmlbuilder": "4.2.1" + "node_modules/@jimp/plugin-cover": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz", + "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-crop": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5", + "@jimp/plugin-scale": ">=0.3.5" } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "node_modules/@jimp/plugin-crop": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz", + "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" + "node_modules/@jimp/plugin-displace": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz", + "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "axios": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz", - "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", - "requires": { - "follow-redirects": "^1.3.0", - "is-buffer": "^1.1.5" + "node_modules/@jimp/plugin-dither": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz", + "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "node_modules/@jimp/plugin-fisheye": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz", + "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" } }, - "babel-polyfill": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz", - "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=", - "dev": true, - "requires": { - "babel-runtime": "^6.22.0", - "core-js": "^2.4.0", - "regenerator-runtime": "^0.10.0" + "node_modules/@jimp/plugin-flip": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz", + "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-rotate": ">=0.3.5" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "node_modules/@jimp/plugin-gaussian": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz", + "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==", + "dependencies": { + "@jimp/utils": "^0.22.12" }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-invert": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz", + "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==", "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "node_modules/@jimp/plugin-mask": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz", + "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "node_modules/@jimp/plugin-normalize": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz", + "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==", + "dependencies": { + "@jimp/utils": "^0.22.12" }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/plugin-print": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz", + "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==", "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "@jimp/utils": "^0.22.12", + "load-bmfont": "^1.4.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5" } }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + "node_modules/@jimp/plugin-resize": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz", + "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + "node_modules/@jimp/plugin-rotate": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz", + "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blit": ">=0.3.5", + "@jimp/plugin-crop": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" + } }, - "bcrypt-nodejs": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", - "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=" + "node_modules/@jimp/plugin-scale": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz", + "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" + } }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" + "node_modules/@jimp/plugin-shadow": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz", + "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-blur": ">=0.3.5", + "@jimp/plugin-resize": ">=0.3.5" } }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true + "node_modules/@jimp/plugin-threshold": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz", + "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==", + "dependencies": { + "@jimp/utils": "^0.22.12" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5", + "@jimp/plugin-color": ">=0.8.0", + "@jimp/plugin-resize": ">=0.8.0" + } }, - "bignumber.js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.4.0.tgz", - "integrity": "sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=" + "node_modules/@jimp/plugins": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz", + "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==", + "dependencies": { + "@jimp/plugin-blit": "^0.22.12", + "@jimp/plugin-blur": "^0.22.12", + "@jimp/plugin-circle": "^0.22.12", + "@jimp/plugin-color": "^0.22.12", + "@jimp/plugin-contain": "^0.22.12", + "@jimp/plugin-cover": "^0.22.12", + "@jimp/plugin-crop": "^0.22.12", + "@jimp/plugin-displace": "^0.22.12", + "@jimp/plugin-dither": "^0.22.12", + "@jimp/plugin-fisheye": "^0.22.12", + "@jimp/plugin-flip": "^0.22.12", + "@jimp/plugin-gaussian": "^0.22.12", + "@jimp/plugin-invert": "^0.22.12", + "@jimp/plugin-mask": "^0.22.12", + "@jimp/plugin-normalize": "^0.22.12", + "@jimp/plugin-print": "^0.22.12", + "@jimp/plugin-resize": "^0.22.12", + "@jimp/plugin-rotate": "^0.22.12", + "@jimp/plugin-scale": "^0.22.12", + "@jimp/plugin-shadow": "^0.22.12", + "@jimp/plugin-threshold": "^0.22.12", + "timm": "^1.6.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true + "node_modules/@jimp/png": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz", + "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==", + "dependencies": { + "@jimp/utils": "^0.22.12", + "pngjs": "^6.0.0" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "node_modules/@jimp/tiff": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz", + "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==", + "dependencies": { + "utif2": "^4.0.1" + }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } }, - "bmp-js": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.0.3.tgz", - "integrity": "sha1-ZBE+nHzxICs3btYHvzBibr5XsYo=" - }, - "body-parser": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", - "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", - "requires": { - "bytes": "2.4.0", - "content-type": "~1.0.2", - "debug": "2.6.7", - "depd": "~1.1.0", - "http-errors": "~1.6.1", - "iconv-lite": "0.4.15", - "on-finished": "~2.3.0", - "qs": "6.4.0", - "raw-body": "~2.2.0", - "type-is": "~1.6.15" + "node_modules/@jimp/types": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz", + "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==", + "dependencies": { + "@jimp/bmp": "^0.22.12", + "@jimp/gif": "^0.22.12", + "@jimp/jpeg": "^0.22.12", + "@jimp/png": "^0.22.12", + "@jimp/tiff": "^0.22.12", + "timm": "^1.6.1" }, + "peerDependencies": { + "@jimp/custom": ">=0.3.5" + } + }, + "node_modules/@jimp/utils": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", + "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } + "regenerator-runtime": "^0.13.3" } }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", + "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==", + "dependencies": { + "sparse-bitfield": "^3.0.3" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "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, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "engines": { + "node": ">= 8" } }, - "bson": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" + "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" } }, - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "node_modules/@types/eslint": { + "version": "8.56.11", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", + "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", - "requires": { - "dicer": "0.2.5", - "readable-stream": "1.1.x" + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" } }, - "bytes": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", - "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "@types/webidl-conversions": "*" } }, - "cachedir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", - "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", - "dev": true, - "requires": { - "os-homedir": "^1.0.1" + "node_modules/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==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, - "requires": { - "callsites": "^2.0.0" + "bin": { + "acorn": "bin/acorn" }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } + "engines": { + "node": ">=0.4.0" } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "node_modules/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": { - "callsites": "^0.2.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } }, - "capture-stack-trace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", - "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", - "dev": true + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "optional": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "node_modules/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + "node_modules/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, + "engines": { + "node": ">=8" + } }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, "dependencies": { - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.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-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", - "dev": true + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cli-cursor": { + "node_modules/append-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", "dev": true, - "requires": { - "restore-cursor": "^1.0.1" + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "node_modules/append-buffer/node_modules/buffer-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", + "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" + "engines": { + "node": ">=0.4" }, - "dependencies": { - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true + "node_modules/append-field": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", + "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", "dev": true }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "node_modules/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 }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "engines": { + "node": ">=0.10.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", "dev": true, - "requires": { - "color-name": "1.1.3" + "dependencies": { + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "~1.0.0" + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "node_modules/arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", + "dev": true, + "dependencies": { + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "commitizen": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-2.10.1.tgz", - "integrity": "sha1-jDld7zSolfTpSVLC78PJ60w2g70=", - "dev": true, - "requires": { - "cachedir": "^1.1.0", - "chalk": "1.1.3", - "cz-conventional-changelog": "2.0.0", - "dedent": "0.6.0", - "detect-indent": "4.0.0", - "find-node-modules": "1.0.4", - "find-root": "1.0.0", - "fs-extra": "^1.0.0", - "glob": "7.1.1", - "inquirer": "1.2.3", - "lodash": "4.17.5", - "minimist": "1.2.0", - "opencollective": "1.0.3", - "path-exists": "2.1.0", - "shelljs": "0.7.6", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "cz-conventional-changelog": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.0.0.tgz", - "integrity": "sha1-Val5r9/pXnAkh50qD1kkYwFwtTM=", - "dev": true, - "requires": { - "conventional-commit-types": "^2.0.0", - "lodash.map": "^4.5.1", - "longest": "^1.0.1", - "pad-right": "^0.2.2", - "right-pad": "^1.0.1", - "word-wrap": "^1.0.3" - } - }, - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "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/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, + "node_modules/array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", + "dev": true, "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "node_modules/array-initial/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "engines": { + "node": ">=0.10.0" } }, - "connect": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.2.tgz", - "integrity": "sha1-aU6NIGgb/kkCgsiriGvpjwn0L+c=", - "requires": { - "debug": "2.6.7", - "finalhandler": "1.0.3", - "parseurl": "~1.3.1", - "utils-merge": "1.0.0" - }, + "node_modules/array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz", - "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=", - "requires": { - "debug": "2.6.7", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.1", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - } + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + "node_modules/array-last/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "content-security-policy-builder": { + "node_modules/array-slice": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-1.1.0.tgz", - "integrity": "sha1-2R8bB2I2wRmFDH3umSS/VeBXcrM=", - "requires": { - "dashify": "^0.2.0" + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "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==" - }, - "conventional-commit-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.3.0.tgz", - "integrity": "sha512-6iB39PrcGYdz0n3z31kj6/Km6mK9hm9oMRhwcLnKxE7WNoeRKZbTAobliKrbYZ5jqyCvtcVEfjCiaEzhL3AVmQ==", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "node_modules/array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "dependencies": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "requires": { - "object-assign": "^4", - "vary": "^1" + "node_modules/array-sort/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" + "engines": { + "node": ">=0.10.0" } }, - "cross-env": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.0.5.tgz", - "integrity": "sha1-Q4PTZNlmCHPdGFs5ivO/717//vM=", + "node_modules/async-done": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", + "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", "dev": true, - "requires": { - "cross-spawn": "^5.1.0", - "is-windows": "^1.0.0" - }, "dependencies": { - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - } + "end-of-stream": "^1.4.4", + "once": "^1.4.0", + "stream-exhaust": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "node_modules/async-each": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + "node_modules/async-settle": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", + "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } }, - "crypto-browserify": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz", - "integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA=" + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "crypto-random-string": { + "node_modules/at-least-node": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "cz-conventional-changelog": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz", - "integrity": "sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q=", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true, - "requires": { - "conventional-commit-types": "^2.0.0", - "lodash.map": "^4.5.1", - "longest": "^1.0.1", - "right-pad": "^1.0.1", - "word-wrap": "^1.0.3" + "engines": { + "node": ">= 4.0.0" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" } }, - "dasherize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", - "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" - }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=" - }, - "date-fns": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", - "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", - "dev": true + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true + "node_modules/aws-sdk": { + "version": "2.1660.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1660.0.tgz", + "integrity": "sha512-nyCEm6J4exq4gxeK5/LB5Q9unQTzFy6fbFHnrrmJZvp1KnRbJ10W2UtwQmeibPAz9b4w+RTKJMe6QEZ38eXeqA==", + "hasInstallScript": true, + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.6.2" + }, + "engines": { + "node": ">= 10.0.0" + } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true }, - "dedent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", - "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=", - "dev": true + "node_modules/bach": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", + "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0", + "async-settle": "^2.0.0", + "now-and-later": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "requires": { - "clone": "^1.0.2" + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "node_modules/bcrypt-nodejs": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", + "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=", + "deprecated": "bcrypt-nodejs is no longer actively maintained. Please use bcrypt or bcryptjs. See https://github.com/kelektiv/node.bcrypt.js/wiki/bcrypt-vs-brypt.js to learn more about these two options" }, - "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "^0.1.0" + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" } }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "requires": { - "repeating": "^2.0.0" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "dicer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", - "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", - "requires": { - "readable-stream": "1.1.x", - "streamsearch": "0.1.2" + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" } }, - "dns-prefetch-control": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", - "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, - "requires": { - "esutils": "^2.0.2" + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, - "dont-sniff-mimetype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", - "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "requires": { - "is-obj": "^1.0.0" + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + "node_modules/bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true + "node_modules/body-parser": { + "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.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.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "node_modules/body-parser/node_modules/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==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { - "readable-stream": "~1.1.9" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "node_modules/bson": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "engines": { + "node": ">=16.20.1" } }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "node_modules/buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", + "engines": { + "node": ">=0.4.0" + } }, - "elegant-spinner": { + "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, - "requires": { - "iconv-lite": "~0.4.13" + "node_modules/busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==", + "dependencies": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" } }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, - "requires": { - "once": "~1.3.0" - }, "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true, - "requires": { - "wrappy": "1" - } - } + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/cachedir": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">=6" } }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "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" + } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/centra": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", + "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", + "dependencies": { + "follow-redirects": "^1.15.6" + } }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "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" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - } + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "eslint-config-semistandard": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-semistandard/-/eslint-config-semistandard-12.0.1.tgz", - "integrity": "sha512-4zaPW5uRFasf2uRZkE19Y+W84KBV3q+oyWYOsgUN+5DQXE5HCsh7ZxeWDXxozk7NPycGm0kXcsJzLe5GZ1jCeg==", + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "eslint-config-standard": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz", - "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=", - "dev": true + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "engines": { + "node": "*" + } }, - "eslint-import-resolver-node": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.5.0" + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "eslint-module-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", - "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "requires": { - "debug": "^2.6.8", - "pkg-dir": "^2.0.0" + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "eslint-plugin-import": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.10.0.tgz", - "integrity": "sha1-+gkIPVp1KI35xsfQn+EiVZhWVec=", + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, - "requires": { - "builtin-modules": "^1.1.1", - "contains-path": "^0.1.0", - "debug": "^2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.2.0", - "has": "^1.0.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0" + "engines": { + "node": ">=6" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "eslint-plugin-node": { + "node_modules/cli-truncate/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", - "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "ignore": "^3.3.6", - "minimatch": "^3.0.4", - "resolve": "^1.3.3", - "semver": "^5.4.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "eslint-plugin-promise": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.7.0.tgz", - "integrity": "sha512-2WO+ZFh7vxUKRfR0cOIMrWgYKdR6S1AlOezw6pC52B6oYpd5WFghN+QHxvrRdZMtbo8h3dfUZ2o1rWb0UPbKtg==", + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", "dev": true }, - "eslint-plugin-standard": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", - "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", - "dev": true - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/cli-truncate/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, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "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, - "requires": { - "estraverse": "^4.0.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, - "requires": { - "estraverse": "^4.1.0" + "engines": { + "node": ">=0.8" } }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", "dev": true }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", "dev": true, - "requires": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" } }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "node_modules/cloneable-readable/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "node_modules/cloneable-readable/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "node_modules/cloneable-readable/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true, - "requires": { - "fill-range": "^2.1.0" + "engines": { + "node": ">=0.10.0" } }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "node_modules/collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", "dev": true, - "requires": { - "os-homedir": "^1.0.1" - } - }, - "expect-ct": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.1.0.tgz", - "integrity": "sha1-UnNWeN4YUwiQ2Ne5XwrGNkCVgJQ=" - }, - "express": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.3.tgz", - "integrity": "sha1-urZdDwOqgMNYQIly/HAPkWlEtmI=", - "requires": { - "accepts": "~1.3.3", - "array-flatten": "1.1.1", - "content-disposition": "0.5.2", - "content-type": "~1.0.2", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.7", - "depd": "~1.1.0", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "etag": "~1.8.0", - "finalhandler": "~1.0.3", - "fresh": "0.5.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.1", - "path-to-regexp": "0.1.7", - "proxy-addr": "~1.1.4", - "qs": "6.4.0", - "range-parser": "~1.2.0", - "send": "0.15.3", - "serve-static": "1.12.3", - "setprototypeof": "1.0.3", - "statuses": "~1.3.1", - "type-is": "~1.6.15", - "utils-merge": "1.0.0", - "vary": "~1.1.1" - }, "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - } + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "external-editor": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", - "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { - "extend": "^3.0.0", - "spawn-sync": "^1.0.15", - "tmp": "^0.0.29" + "dependencies": { + "color-name": "1.1.3" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, - "requires": { - "is-extglob": "^1.0.0" + "bin": { + "color-support": "bin.js" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" + "engines": { + "node": ">=0.1.90" } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } }, - "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 + "node_modules/commitizen": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.0.tgz", + "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==", + "dev": true, + "dependencies": { + "cachedir": "2.3.0", + "cz-conventional-changelog": "3.3.0", + "dedent": "0.7.0", + "detect-indent": "6.1.0", + "find-node-modules": "^2.1.2", + "find-root": "1.1.0", + "fs-extra": "9.1.0", + "glob": "7.2.3", + "inquirer": "8.2.5", + "is-utf8": "^0.2.1", + "lodash": "4.17.21", + "minimist": "1.2.7", + "strip-bom": "4.0.0", + "strip-json-comments": "3.1.1" + }, + "bin": { + "commitizen": "bin/commitizen", + "cz": "bin/git-cz", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 12" + } }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "node_modules/commitizen/node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "node_modules/commitizen/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "engines": { + "node": ">=8" } }, - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "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 }, - "fill-range": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", - "dev": true, - "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "finalhandler": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", - "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dependencies": { - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - } + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "find-node-modules": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-1.0.4.tgz", - "integrity": "sha1-tt6zzMtpnIcDdne87eLF9YYrJVA=", - "dev": true, - "requires": { - "findup-sync": "0.4.2", - "merge": "^1.2.0" + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "find-parent-dir": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", - "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "node_modules/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==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "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/conventional-commit-types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", + "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", "dev": true }, - "find-root": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.0.0.tgz", - "integrity": "sha1-li/yEaqyXGUg/u641ih/j26VgHo=", + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" + "node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "engines": { + "node": ">= 0.6" } }, - "findup-sync": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.2.tgz", - "integrity": "sha1-qBF9D3MST1pFRoOVef5S1xKfteU=", + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "dev": true, - "requires": { - "detect-file": "^0.1.0", - "is-glob": "^2.0.1", - "micromatch": "^2.3.7", - "resolve-dir": "^0.1.0" + "engines": { + "node": ">=0.10.0" } }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "node_modules/copy-props": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", + "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - } + "each-props": "^3.0.0", + "is-plain-object": "^5.0.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true + "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" + } }, - "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, - "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "optional": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "follow-redirects": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", - "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", - "requires": { - "debug": "^3.0.0" + "node_modules/cosmiconfig-typescript-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", + "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "dev": true, + "optional": true, + "dependencies": { + "jiti": "^1.19.1" + }, + "engines": { + "node": ">=v16" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=8.2", + "typescript": ">=4" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "optional": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, - "requires": { - "for-in": "^1.0.1" + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "node_modules/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, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "engines": { + "node": "*" } }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "node_modules/cz-conventional-changelog": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", + "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "commitizen": "^4.0.3", + "conventional-commit-types": "^3.0.0", + "lodash.map": "^4.5.1", + "longest": "^2.0.1", + "word-wrap": "^1.0.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@commitlint/load": ">6.1.1" + } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "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, - "requires": { - "map-cache": "^0.2.2" + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" } }, - "frameguard": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.0.0.tgz", - "integrity": "sha1-e8rUae57lukdEs6zlZx4I1qScuk=" + "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" + } }, - "freemail": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/freemail/-/freemail-1.5.0.tgz", - "integrity": "sha1-k7sPZ8SYcUO0eLQH6Y4ybq2O1OA=", - "requires": { - "tldjs": "^1.5.2" + "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/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "fresh": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", - "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=" + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "node_modules/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 }, - "fs-extra": { + "node_modules/default-compare": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" + "dependencies": { + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "node_modules/default-compare/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "node_modules/default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "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 - }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, - "requires": { - "globule": "~0.1.0" + "engines": { + "node": ">=0.8" } }, - "get-own-enumerable-property-symbols": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz", - "integrity": "sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA==", - "dev": true - }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" + "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" } }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" } }, - "glob-parent": { + "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "^4.3.1", - "glob2base": "^0.0.12", - "minimatch": "^2.0.1", - "ordered-read-streams": "^0.1.0", - "through2": "^0.6.1", - "unique-stream": "^1.0.0" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^2.0.1", - "once": "^1.3.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "^1.0.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" } }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", "dev": true, - "requires": { - "gaze": "^0.5.1" + "engines": { + "node": ">=0.10.0" } }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, - "requires": { - "find-index": "^0.1.1" + "engines": { + "node": ">=8" } }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" + "node_modules/dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==", + "dependencies": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=0.8.0" } }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", - "dev": true, - "requires": { - "ini": "^1.3.4" + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "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" } }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dev": true, - "requires": { - "global-prefix": "^0.1.4", - "is-windows": "^0.2.0" + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" } }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "requires": { - "homedir-polyfill": "^1.0.0", - "ini": "^1.3.4", - "is-windows": "^0.2.0", - "which": "^1.2.12" + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "~3.1.21", - "lodash": "~1.0.1", - "minimatch": "~0.2.11" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "~1.2.0", - "inherits": "1", - "minimatch": "~0.2.11" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" - } - } + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "node_modules/each-props": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", + "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", "dev": true, - "requires": { - "sparkles": "^1.0.0" + "dependencies": { + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "google-auth-library": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-0.10.0.tgz", - "integrity": "sha1-bhW6vuhf0d0U2NEoopW2g41SE24=", - "requires": { - "gtoken": "^1.2.1", - "jws": "^3.1.4", - "lodash.noop": "^3.0.1", - "request": "^2.74.0" + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" } }, - "google-p12-pem": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-0.1.2.tgz", - "integrity": "sha1-M8RqsCGqc0+gMys5YKmj/8svMXc=", - "requires": { - "node-forge": "^0.7.1" - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "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 }, - "gtoken": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-1.2.3.tgz", - "integrity": "sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w==", - "requires": { - "google-p12-pem": "^0.1.0", - "jws": "^3.0.0", - "mime": "^1.4.1", - "request": "^2.72.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - } + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" } }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "requires": { - "archy": "^1.0.0", - "chalk": "^1.0.0", - "deprecated": "^0.0.1", - "gulp-util": "^3.0.0", - "interpret": "^1.0.0", - "liftoff": "^2.1.0", - "minimist": "^1.1.0", - "orchestrator": "^0.3.0", - "pretty-hrtime": "^1.0.0", - "semver": "^4.1.0", - "tildify": "^1.0.0", - "v8flags": "^2.0.2", - "vinyl-fs": "^0.3.0" - }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - } + "once": "^1.4.0" } }, - "gulp-eslint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.0.tgz", - "integrity": "sha512-+qsePo04v1O3JshpNvww9+bOgZEJ6Cc2/w3mEktfKz0NL0zsh1SWzjyIL2FIM2zzy6IYQYv+j8REZORF8dKX4g==", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "requires": { - "eslint": "^4.0.0", - "gulp-util": "^3.0.8" + "optional": true, + "engines": { + "node": ">=6" } }, - "gulp-nodemon": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.2.1.tgz", - "integrity": "sha1-2b8Zn1WFRYFZ09KZFT5gtGhotvQ=", - "dev": true, - "requires": { - "colors": "^1.0.3", - "event-stream": "^3.2.1", - "gulp": "^3.9.1", - "nodemon": "^1.10.2" - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } + "is-arrayish": "^0.2.1" } }, - "gulplog": { + "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^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" } }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "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" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "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, - "requires": { - "function-bind": "^1.1.1" + "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" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "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, - "requires": { - "ansi-regex": "^2.0.0" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "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, - "requires": { - "sparkles": "^1.0.0" + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" } }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "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, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "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, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "engines": { + "node": ">=6" } }, - "helmet": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.8.1.tgz", - "integrity": "sha512-HzcpQ74kE1gNFvTd8fI/Nz2N0b0Aa/38dSiSVt/ijkwjc50tUp5siXTE9lTBibQ4JlRzp/35Qf+j2bZgHYwg1g==", - "requires": { - "connect": "3.6.2", - "dns-prefetch-control": "0.1.0", - "dont-sniff-mimetype": "1.0.0", - "expect-ct": "0.1.0", - "frameguard": "3.0.0", - "helmet-csp": "2.5.1", - "hide-powered-by": "1.0.0", - "hpkp": "2.0.0", - "hsts": "2.1.0", - "ienoopen": "1.0.0", - "nocache": "2.0.0", - "referrer-policy": "1.1.0", - "x-xss-protection": "1.0.0" - } - }, - "helmet-csp": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.5.1.tgz", - "integrity": "sha512-PLLch8wVcVF2+ViTtSGHIvXqQVjcwGRtBwrNPggC+j28J7eSoPHxbJBr9SvLgh9V3HZa0C1zZFZ6gYVLIrPD0Q==", - "requires": { - "camelize": "1.0.0", - "content-security-policy-builder": "1.1.0", - "dasherize": "2.0.0", - "lodash.reduce": "4.6.0", - "platform": "1.3.4" - } - }, - "hide-powered-by": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", - "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" - }, - "homedir-polyfill": { + "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "requires": { - "parse-passwd": "^1.0.0" + "engines": { + "node": ">=0.8.0" } }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, - "hpkp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", - "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" - }, - "hsts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", - "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" + "node_modules/eslint": { + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz", + "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.7.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "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.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "node_modules/eslint-scope": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "husky": { - "version": "1.0.0-rc.13", - "resolved": "https://registry.npmjs.org/husky/-/husky-1.0.0-rc.13.tgz", - "integrity": "sha512-ZNNoaBgfOHRA05UHS/etBoWFDu65mjPoohPYQwOqb5155KOovBp8LMkMoNK0kn3VYdsm+HWdtuHbD4XjfzlfpQ==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.2", - "execa": "^0.9.0", - "find-up": "^3.0.0", - "get-stdin": "^6.0.0", - "is-ci": "^1.1.0", - "pkg-dir": "^3.0.0", - "please-upgrade-node": "^3.1.1", - "read-pkg": "^4.0.1", - "run-node": "^1.0.0", - "slash": "^2.0.0" - }, - "dependencies": { - "execa": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", - "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "read-pkg": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", - "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", - "dev": true, - "requires": { - "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" - } - } + "node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "node_modules/eslint/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "ienoopen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.0.0.tgz", - "integrity": "sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms=" + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "dependencies": { - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "node_modules/eslint/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/eslint/node_modules/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, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "inquirer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz", - "integrity": "sha1-TexvMvN+97sLLtPx0aXD9UUHSRg=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "external-editor": "^1.1.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "mute-stream": "0.0.6", - "pinkie-promise": "^2.0.0", - "run-async": "^2.2.0", - "rx": "^4.1.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" + "node_modules/eslint/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" } }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "ip-regex": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", - "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=" - }, - "ipaddr.js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", - "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "node_modules/eslint/node_modules/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, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "dependencies": { - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - } + "engines": { + "node": ">=8" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "engines": { + "node": ">= 4" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "node_modules/eslint/node_modules/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 }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "node_modules/eslint/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, - "requires": { - "binary-extensions": "^1.0.0" + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "node_modules/eslint/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, - "requires": { - "ci-info": "^1.5.0" + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/eslint/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, - "requires": { - "kind-of": "^3.0.2" + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/eslint/node_modules/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": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "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, - "requires": { - "is-primitive": "^2.0.0" + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, - "requires": { - "number-is-nan": "^1.0.0" + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, - "requires": { - "number-is-nan": "^1.0.0" + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" } }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" + "node_modules/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, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "requires": { - "is-extglob": "^1.0.0" + "engines": { + "node": ">=4.0" } }, - "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "engines": { + "node": ">=0.10.0" } }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "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, - "requires": { - "kind-of": "^3.0.2" + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" } }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true }, - "is-observable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", - "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", - "dev": true, - "requires": { - "symbol-observable": "^1.1.0" + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" } }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "requires": { - "path-is-inside": "^1.0.1" + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/execa/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "requires": { - "isobject": "^3.0.1" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true + "node_modules/express": { + "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.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true + "node_modules/express/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "node_modules/express/node_modules/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==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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, - "requires": { - "is-unc-path": "^1.0.0" + "dependencies": { + "type": "^2.7.2" } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", - "dev": true + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-unc-path": { + "node_modules/extglob/node_modules/define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/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 }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" + "node_modules/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 }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", "dev": true, - "requires": { - "isarray": "1.0.0" + "optional": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "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" + } }, - "jest-get-type": { - "version": "22.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", - "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", - "dev": true + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "jest-validate": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", - "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-get-type": "^22.1.0", - "leven": "^2.1.0", - "pretty-format": "^23.6.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" } }, - "jimp": { - "version": "0.2.28", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.2.28.tgz", - "integrity": "sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=", - "requires": { - "bignumber.js": "^2.1.0", - "bmp-js": "0.0.3", - "es6-promise": "^3.0.2", - "exif-parser": "^0.1.9", - "file-type": "^3.1.0", - "jpeg-js": "^0.2.0", - "load-bmfont": "^1.2.3", - "mime": "^1.3.4", - "mkdirp": "0.5.1", - "pixelmatch": "^4.0.0", - "pngjs": "^3.0.0", - "read-chunk": "^1.0.1", - "request": "^2.65.0", - "stream-to-buffer": "^0.1.0", - "tinycolor2": "^1.1.2", - "url-regex": "^3.0.0" - } - }, - "jmespath": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" - }, - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.x.x", - "isemail": "1.x.x", - "moment": "2.x.x", - "topo": "1.x.x" - } - }, - "jpeg-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.2.0.tgz", - "integrity": "sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII=" + "node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "node_modules/finalhandler/node_modules/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==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } }, - "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==" + "node_modules/find-node-modules": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", + "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", + "dev": true, + "dependencies": { + "findup-sync": "^4.0.0", + "merge": "^2.1.1" + } }, - "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=", + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", "dev": true, - "requires": { - "graceful-fs": "^4.1.6" + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "jsonwebtoken": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.1.tgz", - "integrity": "sha1-fKMk9SFfi+A5zTWmxFu4y3SkSPs=", - "requires": { - "joi": "^6.10.1", - "jws": "^3.1.4", - "lodash.once": "^4.0.0", - "ms": "^2.0.0", - "xtend": "^4.0.1" + "node_modules/find-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "node_modules/findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 8" } }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "node_modules/fined": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", + "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0", + "object.pick": "^1.3.0", + "parse-filepath": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" } }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" + "node_modules/flagged-respawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", + "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", + "dev": true, + "engines": { + "node": ">= 10.13.0" } }, - "kareem": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", - "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "requires": { - "is-buffer": "^1.1.5" + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" } }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, - "requires": { - "graceful-fs": "^4.1.9" + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" } }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "node_modules/flush-write-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "requires": { - "package-json": "^4.0.0" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "node_modules/flush-write-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/flush-write-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^2.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, + "peerDependenciesMeta": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.3" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "1.0.2", - "is-windows": "1.0.2", - "resolve-dir": "1.0.1" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "homedir-polyfill": "1.0.3", - "ini": "1.3.5", - "is-windows": "1.0.2", - "which": "1.3.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" - } - }, - "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-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "global-modules": "1.0.0" - } + "optional": true } } }, - "lint-staged": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-7.2.2.tgz", - "integrity": "sha512-BWT3kx242hq5oaKJ8QiazPeHwJnEXImvjmgZfjljMI5HX6RrTxI3cTJXywre6GNafMONCD/suFnEiFmC69Gscg==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", + "integrity": "sha512-Pqq5NnT78ehvUnAk/We/Jr22vSvanRlFTpAmQ88xBY/M1TlHe+P0ILuEyXS595ysdGfaj22634LBkGMA2GTcpA==", + "dev": true + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/freemail": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/freemail/-/freemail-1.7.0.tgz", + "integrity": "sha512-XzEdol9AxxwDN5ISi+J560MgQRKTiGOTRFakRQLUQDEjr48hBMzU5Eo7c2U13zzz3IwcaD+54jWHJrg6/wqRNA==", + "dependencies": { + "tldjs": "^1.5.2" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "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-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "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/gaxios": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", + "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^10.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "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-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "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" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gifwrap": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", + "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", + "dependencies": { + "image-q": "^4.0.0", + "omggif": "^1.0.10" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "dev": true, + "dependencies": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-watcher": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", + "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", + "dev": true, + "dependencies": { + "async-done": "^2.0.0", + "chokidar": "^3.5.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "optional": true, + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/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/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glogg": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", + "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", + "dev": true, + "dependencies": { + "sparkles": "^2.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/google-auth-library": { + "version": "9.11.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.11.0.tgz", + "integrity": "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "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/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gtoken/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gulp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", + "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", + "dev": true, + "dependencies": { + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", + "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "dev": true, + "dependencies": { + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.0", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/gulp-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/gulp-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/gulp-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/gulp-cli/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/gulp-cli/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gulp-eslint-new": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulp-eslint-new/-/gulp-eslint-new-2.2.0.tgz", + "integrity": "sha512-B9sBfILAW563MQM81vxWOMeeNbkZTgZEYiwEVmv3fndB5zmGINlA4wbc4qjgPd4kTCtq0sTlFZJV0fpxl8b5kg==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.10", + "@types/node": ">=12", + "eslint": "8 || 9", + "fancy-log": "^2.0.0", + "plugin-error": "^2.0.1", + "semver": "^7.6.2", + "ternary-stream": "^3.0.0", + "vinyl-fs": "^4.0.0" + }, + "engines": { + "node": "^12.20 || ^14.13 || >=16" + } + }, + "node_modules/gulp-eslint-new/node_modules/fancy-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", + "dev": true, + "dependencies": { + "color-support": "^1.1.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-eslint-new/node_modules/plugin-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.1.tgz", + "integrity": "sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-eslint-new/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulp-nodemon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz", + "integrity": "sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q==", + "dev": true, + "dependencies": { + "colors": "^1.2.1", + "gulp": "^4.0.0", + "nodemon": "^2.0.2" + } + }, + "node_modules/gulp-nodemon/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/gulp-nodemon/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", + "dev": true, + "dependencies": { + "async-done": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", + "dev": true, + "dependencies": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/gulp-nodemon/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/gulp-nodemon/node_modules/copy-props": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", + "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", + "dev": true, + "dependencies": { + "each-props": "^1.3.2", + "is-plain-object": "^5.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "node_modules/gulp-nodemon/node_modules/each-props/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/fast-levenshtein": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", + "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", + "dev": true + }, + "node_modules/gulp-nodemon/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/fined/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/gulp-nodemon/node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "node_modules/gulp-nodemon/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-watcher": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", + "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "normalize-path": "^3.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "dependencies": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", + "dev": true, + "dependencies": { + "glogg": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gulp-nodemon/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-extendable/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", + "dev": true, + "dependencies": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", + "dev": true, + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/gulp-nodemon/node_modules/liftoff/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/micromatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/gulp-nodemon/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", + "dev": true, + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/gulp-nodemon/node_modules/semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", + "dev": true, + "dependencies": { + "sver-compat": "^1.5.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/gulp-nodemon/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", + "dev": true, + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/undertaker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", + "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "fast-levenshtein": "^1.0.0", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", + "dev": true, + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl-sourcemap/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "node_modules/gulp-nodemon/node_modules/yargs": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", + "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.1" + } + }, + "node_modules/gulp-nodemon/node_modules/yargs-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", + "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" + } + }, + "node_modules/gulplog": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", + "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", + "dev": true, + "dependencies": { + "glogg": "^2.2.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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-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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/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==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.1.tgz", + "integrity": "sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true + }, + "node_modules/image-q": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", + "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "dependencies": { + "@types/node": "16.9.1" + } + }, + "node_modules/image-q/node_modules/@types/node": { + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + }, + "node_modules/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, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "optional": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "optional": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/inquirer/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/inquirer/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/inquirer/node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/inquirer/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" + }, + "node_modules/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==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", + "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", + "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", + "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.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-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/jimp": { + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz", + "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==", + "dependencies": { + "@jimp/custom": "^0.22.12", + "@jimp/plugins": "^0.22.12", + "@jimp/types": "^0.22.12", + "regenerator-runtime": "^0.13.3" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "optional": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "optional": 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==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, - "requires": { - "chalk": "^2.3.1", - "commander": "^2.14.1", - "cosmiconfig": "^5.0.2", - "debug": "^3.1.0", - "dedent": "^0.7.0", - "execa": "^0.9.0", - "find-parent-dir": "^0.3.0", - "is-glob": "^4.0.0", - "is-windows": "^1.0.2", - "jest-validate": "^23.5.0", - "listr": "^0.14.1", - "lodash": "^4.17.5", - "log-symbols": "^2.2.0", - "micromatch": "^3.1.8", - "npm-which": "^3.0.1", - "p-map": "^1.1.1", - "path-is-inside": "^1.0.2", - "pify": "^3.0.0", - "please-upgrade-node": "^3.0.2", - "staged-git-files": "1.1.1", - "string-argv": "^0.0.2", - "stringify-object": "^3.2.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "execa": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", - "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "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-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, + "optional": true + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "optional": true + }, + "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=", + "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/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/just-debounce": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", + "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", + "dev": true + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "engines": { + "node": ">=12.0.0" + } + }, + "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/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/last-run": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", + "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/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, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftoff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", + "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", + "dev": true, + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^5.0.0", + "fined": "^2.0.0", + "flagged-respawn": "^2.0.0", + "is-plain-object": "^5.0.0", + "rechoir": "^0.8.0", + "resolve": "^1.20.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/liftoff/node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "optional": true + }, + "node_modules/lint-staged": { + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", + "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/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/lint-staged/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "optional": true } } }, - "listr": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", - "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", - "dev": true, - "requires": { - "@samverschueren/stream-to-observable": "^0.3.0", - "is-observable": "^1.1.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.5.0", - "listr-verbose-renderer": "^0.5.0", - "p-map": "^2.0.0", - "rxjs": "^6.3.3" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } + "node_modules/listr2": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", + "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/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/listr2/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/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/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/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/load-bmfont": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", + "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", + "dependencies": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^3.7.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.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.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, + "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/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "optional": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "optional": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", - "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^2.3.0", - "strip-ansi": "^3.0.1" - }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "^1.0.0" - } - } + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "listr-verbose-renderer": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", - "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/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, - "requires": { - "chalk": "^2.4.1", - "cli-cursor": "^2.1.0", - "date-fns": "^1.27.2", - "figures": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "engines": { + "node": ">=8" } }, - "load-bmfont": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", - "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==", - "requires": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" + "node_modules/log-symbols/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "engines": { + "node": ">=14.16" }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true + "node_modules/log-update/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" + } }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true + "node_modules/log-update/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" + } }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", "dev": true }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true + "node_modules/log-update/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true + "node_modules/log-update/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "node_modules/log-update/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, - "requires": { - "lodash._root": "^3.0.0" + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true + "node_modules/log-update/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" + } }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "node_modules/longest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", + "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" + "engines": { + "node": ">=0.10.0" } }, - "lodash.map": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.noop": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-3.0.1.tgz", - "integrity": "sha1-OBiPTWUKOkdCWEObluxFsyYXEzw=" + "node_modules/make-iterator/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true + "node_modules/matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", + "dev": true, + "dependencies": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "engines": { + "node": ">= 0.10.0" + } }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "node_modules/matchdep/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "node_modules/matchdep/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, - "requires": { - "chalk": "^2.0.1" + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "log-update": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", - "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "node_modules/matchdep/node_modules/findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "cli-cursor": "^2.0.0", - "wrap-ansi": "^3.0.1" + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/matchdep/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - } + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "longest": { + "node_modules/matchdep/node_modules/is-extendable": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true + "node_modules/matchdep/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "node_modules/matchdep/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "node_modules/matchdep/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, - "requires": { - "pify": "^3.0.0" + "dependencies": { + "is-buffer": "^1.1.5" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "node_modules/matchdep/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "requires": { - "kind-of": "^6.0.2" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/micromatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/matchdep/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, - "requires": { - "object-visit": "^1.0.0" + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "math-random": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", - "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", - "dev": true - }, - "md5": { + "node_modules/md5": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", - "requires": { + "dependencies": { "charenc": "~0.0.1", "crypt": "~0.0.1", "is-buffer": "~1.1.1" } }, - "media-typer": { + "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": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } }, - "memory-pager": { + "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" }, - "merge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", - "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "node_modules/merge": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", + "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", "dev": true }, - "merge-descriptors": { + "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=" }, - "methods": { + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "requires": { - "mime-db": "1.42.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "min-document": { + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dependencies": { "dom-walk": "^0.1.0" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "mixin-deep": { + "node_modules/mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, - "requires": { + "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" + "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": "*" } }, - "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" + "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": "*" + } }, - "moment-timezone": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.21.tgz", - "integrity": "sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A==", - "requires": { - "moment": ">= 2.9.0" + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" } }, - "mongodb": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.6.tgz", - "integrity": "sha512-E5QJuXQoMlT7KyCYqNNMfAkhfQD79AT4F8Xd+6x37OX+8BL17GyXyWvfm6wuyx4wnzCCPoCSLeMeUN2S7dU9yw==", - "requires": { - "mongodb-core": "3.1.5", - "safe-buffer": "^5.1.2" + "node_modules/mongodb-connection-string-url/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" } }, - "mongodb-core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.5.tgz", - "integrity": "sha512-emT/tM4ZBinqd6RZok+EzDdtN4LjYJIckv71qQVOEFmvXgT5cperZegVmTgox/1cx4XQu6LJ5ZuIwipP/eKdQg==", - "requires": { - "bson": "^1.1.0", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "dependencies": { + "punycode": "^2.3.0" }, + "engines": { + "node": ">=14" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", "dependencies": { - "bson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", - "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" - } + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" } }, - "mongodb-uri": { + "node_modules/mongodb-uri": { "version": "0.9.7", "resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz", - "integrity": "sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE=" + "integrity": "sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE=", + "engines": { + "node": ">= 0.6.0" + } }, - "mongoose": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.3.2.tgz", - "integrity": "sha512-07fpCMqvCiSdKXIygt3aAeNFJYjQPjDXILbwBEmF0e8gy2hSKMNuP5QG4J6L8m9BhjVxcvoLiPzaGKN7I/7lLg==", - "requires": { - "async": "2.6.1", - "bson": "~1.0.5", - "kareem": "2.3.0", - "lodash.get": "4.4.2", - "mongodb": "3.1.6", - "mongodb-core": "3.1.5", - "mongoose-legacy-pluralize": "1.0.2", - "mpath": "0.5.1", - "mquery": "3.2.0", - "ms": "2.0.0", - "regexp-clone": "0.0.1", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } + "node_modules/mongoose": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", + "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "6.7.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" } }, - "mongoose-legacy-pluralize": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", - "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" - }, - "morgan": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz", - "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc=", - "requires": { - "basic-auth": "~1.1.0", - "debug": "2.6.8", - "depd": "~1.1.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.1" + "node_modules/mongoose/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4" }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/mongoose/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "optional": true, + "peer": true, "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "mpath": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", - "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" + "node_modules/mongoose/node_modules/debug/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==", + "optional": true, + "peer": true }, - "mquery": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", - "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", - "requires": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "0.0.1", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" + "node_modules/mongoose/node_modules/gaxios": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", + "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "optional": true, + "peer": true, + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongoose/node_modules/gcp-metadata": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", + "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "optional": true, + "peer": true, "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } + "gaxios": "^5.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongoose/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", + "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "socks": { + "optional": true + } + } + }, + "node_modules/mongoose/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/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/mquery/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } } }, - "ms": { + "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==" }, - "multer": { + "node_modules/multer": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", - "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", - "requires": { + "integrity": "sha512-wbAkTsh0QXkvqvHCU2qSLEXLuRN7IKMEe80+JrXfJzANniPNgrNcDOMKfGgR1EhL7y7MHIbODVwT7uaVY20ggw==", + "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "dependencies": { "append-field": "^0.1.0", "busboy": "^0.2.11", "concat-stream": "^1.5.0", @@ -6534,42 +7829,46 @@ "type-is": "^1.6.4", "xtend": "^4.0.0" }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - } + "engines": { + "node": ">= 0.10.0" } }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "node_modules/multer/node_modules/object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mute-stdout": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", + "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", "dev": true, - "requires": { - "duplexer2": "0.0.2" + "engines": { + "node": ">= 10.13.0" } }, - "mute-stream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz", - "integrity": "sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s=", + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "node_modules/nan": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "dev": true, "optional": true }, - "nanomatch": { + "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, - "requires": { + "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", "define-property": "^2.0.2", @@ -6582,1904 +7881,1872 @@ "snapdragon": "^0.8.1", "to-regex": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "natives": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", - "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==", - "dev": true + "node_modules/nanomatch/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/nanomatch/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "natural-compare": { + "node_modules/nanomatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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=", "dev": true }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } }, - "nocache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", - "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" + "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-fetch": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", - "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=", - "dev": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, - "node-forge": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", - "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==" - }, - "nodemailer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.0.1.tgz", - "integrity": "sha1-uVhksH+s7oKH6CMu/9bx1W7HWrI=" + "node_modules/nodemailer": { + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", + "integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==", + "engines": { + "node": ">=6.0.0" + } }, - "nodemon": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz", - "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==", + "node_modules/nodemon": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", + "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", "dev": true, - "requires": { - "chokidar": "^2.1.8", - "debug": "^3.2.6", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^3.2.7", "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.7", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", "semver": "^5.7.1", + "simple-update-notifier": "^1.0.7", "supports-color": "^5.5.0", "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^2.5.0" + "undefsafe": "^2.0.5" }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" } }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "requires": { - "abbrev": "1" + "dependencies": { + "ms": "^2.1.1" } }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { + "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" + "engines": { + "node": ">=0.10.0" } }, - "now": { + "node_modules/now": { "version": "11.4.6", "resolved": "https://registry.npmjs.org/now/-/now-11.4.6.tgz", - "integrity": "sha512-5SMS8lVuCzqD55CPQlGcjvOJJJPuDSLoqKIIGR4uEooCbDhHl//dHZmBpT1uLSwT1MYvhYUMf9OpFQRwXG4KEg==" + "integrity": "sha512-5SMS8lVuCzqD55CPQlGcjvOJJJPuDSLoqKIIGR4uEooCbDhHl//dHZmBpT1uLSwT1MYvhYUMf9OpFQRwXG4KEg==", + "deprecated": "\"now\" is deprecated and will stop receiving updates on December 31, 2020. Please use \"vercel\" instead.", + "hasInstallScript": true, + "bin": { + "now": "download/dist/now" + } }, - "npm-path": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", - "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", + "node_modules/now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, - "requires": { - "which": "^1.2.10" + "dependencies": { + "once": "^1.4.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, - "requires": { - "path-key": "^2.0.0" + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "npm-which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", - "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "requires": { - "commander": "^2.9.0", - "npm-path": "^2.0.2", - "which": "^1.2.10" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "number-is-nan": { + "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "object-assign": { + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } }, - "object-copy": { + "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, - "requires": { + "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", "kind-of": "^3.0.3" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" } }, - "object-visit": { + "node_modules/object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, - "requires": { + "dependencies": { "isobject": "^3.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.defaults": { + "node_modules/object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", "dev": true, - "requires": { + "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", "for-own": "^1.0.0", "isobject": "^3.0.0" }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "engines": { + "node": ">=0.10.0" } }, - "object.map": { + "node_modules/object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", "dev": true, - "requires": { + "dependencies": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "engines": { + "node": ">=0.10.0" } }, - "object.pick": { + "node_modules/object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, - "requires": { + "dependencies": { "isobject": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", + "dev": true, "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "on-finished": { + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, + "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { + "dependencies": { "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "on-headers": { + "node_modules/on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } }, - "once": { + "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==", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "opencollective": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz", - "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=", - "dev": true, - "requires": { - "babel-polyfill": "6.23.0", - "chalk": "1.1.3", - "inquirer": "3.0.6", - "minimist": "1.2.0", - "node-fetch": "1.6.3", - "opn": "4.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "inquirer": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz", - "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "chalk": "^1.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.1", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx": "^4.1.0", - "string-width": "^2.0.0", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - } + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" + "dependencies": { + "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.5" + }, + "engines": { + "node": ">= 0.8.0" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "node_modules/ora/node_modules/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": { - "end-of-stream": "~0.1.5", - "sequencify": "~0.0.7", - "stream-consume": "~0.1.0" + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "os-shim": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "node_modules/ora/node_modules/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, + "engines": { + "node": ">=8" + } }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "node_modules/ora/node_modules/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", "dev": true, - "requires": { - "p-try": "^1.0.0" + "dependencies": { + "readable-stream": "^2.0.1" } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/ordered-read-streams/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, - "requires": { - "p-limit": "^1.1.0" + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "node_modules/ordered-read-streams/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "node_modules/ordered-read-streams/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", "dev": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pad-right": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", - "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/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": { - "repeat-string": "^1.5.2" + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-bmfont-ascii": { + "node_modules/parse-bmfont-ascii": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" }, - "parse-bmfont-binary": { + "node_modules/parse-bmfont-binary": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" }, - "parse-bmfont-xml": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", - "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", - "requires": { + "node_modules/parse-bmfont-xml": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", + "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", + "dependencies": { "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" + "xml2js": "^0.5.0" + } + }, + "node_modules/parse-bmfont-xml/node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "parse-filepath": { + "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, - "requires": { + "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - } - }, - "parse-headers": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", - "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" + "node_modules/parse-headers": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" }, - "parse-json": { + "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, - "requires": { + "dependencies": { "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "parse-node-version": { + "node_modules/parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "parse-passwd": { + "node_modules/parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "parseurl": { + "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "pascalcase": { + "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-dirname": { + "node_modules/path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", "dev": true }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "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, - "requires": { - "pinkie-promise": "^2.0.0" + "engines": { + "node": ">=8" } }, - "path-is-absolute": { + "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=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "node_modules/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, + "engines": { + "node": ">=8" + } }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "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 }, - "path-root": { + "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, - "requires": { + "dependencies": { "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "path-root-regex": { + "node_modules/path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-to-regexp": { + "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=" }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, - "requires": { - "pify": "^2.0.0" + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "~2.3" + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "node_modules/phin": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.1.tgz", + "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", + "dependencies": { + "centra": "^2.7.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "optional": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, - "phin": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } }, - "pify": { + "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pinkie": { + "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pinkie-promise": { + "node_modules/pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, - "requires": { + "dependencies": { "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "pixelmatch": { + "node_modules/pixelmatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", - "requires": { + "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "dependencies": { "pngjs": "^3.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "platform": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", - "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" - }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, - "pngjs": { + "node_modules/pixelmatch/node_modules/pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "engines": { + "node": ">=4.0.0" + } }, - "posix-character-classes": { + "node_modules/pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } }, - "prettier": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.2.tgz", - "integrity": "sha512-McHPg0n1pIke+A/4VcaS2en+pTNjy4xF+Uuq86u/5dyDO59/TtFZtQ708QIRkEZ3qwKz3GVkVa6mpxK/CpB8Rg==", - "dev": true + "node_modules/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, + "engines": { + "node": ">= 0.8.0" + } }, - "pretty-format": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" + "bin": { + "prettier": "bin/prettier.cjs" }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "pretty-hrtime": { + "node_modules/pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true + "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } }, - "process-nextick-args": { + "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/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==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, - "proxy-addr": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", - "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", - "requires": { - "forwarded": "~0.1.0", - "ipaddr.js": "1.4.0" + "node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } }, - "psl": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.5.0.tgz", - "integrity": "sha512-4vqUjKi2huMu1OJiLhi3jN6jeeKvMZdI1tYgi/njW5zV52jNLgSAZSdN16m9bJFe61/cT8ulmw4qFitV9QRsEA==" + "node_modules/pumpify/node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/pumpify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } }, - "pstree.remy": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", - "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==", + "node_modules/pumpify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "punycode": { + "node_modules/pumpify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + "node_modules/qs": { + "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" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "querystring": { + "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } }, - "randomatic": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", - "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "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, - "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + { + "type": "consulting", + "url": "https://feross.org/support" } - } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", + "integrity": "sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==" }, - "randomstring": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", - "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", - "requires": { - "array-uniq": "1.0.2" + "node_modules/randomstring": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.3.0.tgz", + "integrity": "sha512-gY7aQ4i1BgwZ8I1Op4YseITAyiDiajeZOPQUbIq9TPGPhUm5FX59izIaOpmKbME1nmnEiABf28d9K2VSii6BBg==", + "dependencies": { + "randombytes": "2.0.3" + }, + "bin": { + "randomstring": "bin/randomstring" + }, + "engines": { + "node": "*" } }, - "range-parser": { + "node_modules/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==" + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } }, - "raven": { + "node_modules/raven": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.0.tgz", "integrity": "sha1-OAaoLJ7ozT51w7fqe7GTWq0JLQw=", - "requires": { + "deprecated": "Please upgrade to @sentry/node. See the migration guide https://bit.ly/3ybOlo7", + "dependencies": { "cookie": "0.3.1", "md5": "^2.2.1", "stack-trace": "0.0.10", "timed-out": "4.0.1", "uuid": "3.0.0" }, - "dependencies": { - "uuid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" - } + "bin": { + "raven": "bin/raven" + }, + "engines": { + "node": ">= 4.0.0" } }, - "raw-body": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", - "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", - "requires": { - "bytes": "2.4.0", - "iconv-lite": "0.4.15", - "unpipe": "1.0.0" + "node_modules/raven/node_modules/uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", + "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, + "node_modules/raw-body": { + "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": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "read-chunk": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-1.0.1.tgz", - "integrity": "sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=" - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, - "requires": { - "load-json-file": "^2.0.0", + "dependencies": { + "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "readable-stream": { + "node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { + "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" - }, + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - } + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "safe-buffer": "~5.2.0" } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "requires": { - "resolve": "^1.1.6" + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" } }, - "referrer-policy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz", - "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, - "requires": { - "is-equal-shallow": "^0.1.3" + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" } }, - "regex-not": { + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, - "requires": { + "dependencies": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "regexp-clone": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", - "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + "node_modules/regex-not/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true + "node_modules/regex-not/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } }, - "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "node_modules/regex-not/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", "dev": true, - "requires": { - "rc": "^1.0.1" + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" } }, - "remove-trailing-separator": { + "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", "dev": true }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "repeat-string": { + "node_modules/repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", "dev": true, - "requires": { - "is-finite": "^1.0.0" + "engines": { + "node": ">= 10" } }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true + "node_modules/replace-homedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", + "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" - } + "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" } }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } + "optional": true, + "engines": { + "node": ">=0.10.0" } }, - "require_optional": { + "node_modules/require-main-filename": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "^2.0.0", - "semver": "^5.1.0" + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "dev": true + }, + "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" } }, - "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", "dev": true, - "requires": { - "path-parse": "^1.0.6" + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "requires": { - "expand-tilde": "^1.2.2", - "global-modules": "^0.2.3" + "optional": true, + "engines": { + "node": ">=8" } }, - "resolve-from": { + "node_modules/resolve-options": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", + "dev": true, + "dependencies": { + "value-or-function": "^4.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } }, - "resolve-url": { + "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", "dev": true }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ret": { + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "right-pad": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", - "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "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" - } - } + "dev": true, + "engines": { + "node": ">=0.12" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "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, - "requires": { - "is-promise": "^2.1.0" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "run-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", - "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", - "dev": true - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "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, - "requires": { - "rx-lite": "*" + "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" } }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", "dev": true, - "requires": { - "tslib": "^1.9.0" + "dependencies": { + "tslib": "^2.1.0" } }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + "node_modules/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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "safe-regex": { + "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": true, - "requires": { + "dependencies": { "ret": "~0.1.10" } }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "saslprep": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", - "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", - "optional": true, - "requires": { - "sparse-bitfield": "^3.0.3" - } - }, - "sax": { + "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true + "node_modules/semver-greatest-satisfied-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", + "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", + "dev": true, + "dependencies": { + "sver": "^1.8.3" + }, + "engines": { + "node": ">= 10.13.0" + } }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "^5.0.3" - } - }, - "send": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.3.tgz", - "integrity": "sha1-UBP5+ZAj31DRvZiSwZ4979HVMwk=", - "requires": { - "debug": "2.6.7", - "depd": "~1.1.0", - "destroy": "~1.0.4", - "encodeurl": "~1.0.1", + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "etag": "~1.8.0", - "fresh": "0.5.0", - "http-errors": "~1.6.1", - "mime": "1.3.4", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.3.1" + "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" }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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/send/node_modules/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==", "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - } + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "serve-static": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.3.tgz", - "integrity": "sha1-n0uhni8wMMVH+K+ZEHg47DjVseI=", - "requires": { - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "parseurl": "~1.3.1", - "send": "0.15.3" + "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" } }, - "set-value": { + "node_modules/set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, - "requires": { + "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", "is-plain-object": "^2.0.3", "split-string": "^3.0.1" }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "engines": { + "node": ">=0.10.0" } }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "node_modules/set-value/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "shebang-command": { + "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/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": "^1.0.0" + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz", - "integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=", + "node_modules/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, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "engines": { + "node": ">=8" } }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true + "node_modules/side-channel": { + "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.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" + } }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "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" + } }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "node_modules/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" + "dependencies": { + "semver": "~7.0.0" }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + "node_modules/slice-ansi/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" + } }, - "snapdragon": { + "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, - "requires": { + "dependencies": { "base": "^0.11.1", "debug": "^2.2.0", "define-property": "^0.2.5", @@ -8489,1269 +9756,1558 @@ "source-map-resolve": "^0.5.0", "use": "^3.1.0" }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "engines": { + "node": ">=0.10.0" } }, - "snapdragon-node": { + "node_modules/snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, - "requires": { + "dependencies": { "define-property": "^1.0.0", "isobject": "^3.0.0", "snapdragon-util": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "snapdragon-util": { + "node_modules/snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, - "requires": { + "dependencies": { "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "source-map": { + "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, - "requires": { - "atob": "^2.1.1", + "dependencies": { + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", "urix": "^0.1.0" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", "dev": true }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true + "node_modules/sparkles": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", + "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } }, - "sparse-bitfield": { + "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", - "optional": true, - "requires": { + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "dependencies": { "memory-pager": "^1.0.2" } }, - "spawn-sync": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "dev": true, + "dependencies": { + "streamx": "^2.13.2" + } + }, + "node_modules/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "dev": true + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", "dev": true, - "requires": { - "concat-stream": "^1.4.7", - "os-shim": "^0.1.2" + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" } }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=0.6.19" } }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true + "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" + } }, - "spdx-expression-parse": { + "node_modules/string-width/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "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, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">=8" } }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "speakingurl": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.0.tgz", - "integrity": "sha512-70UD8Mm2cMkufkiUJ6tt7DLdLytYxTc1OwzXYJ9LVutfIoNx/Dmuj6vj/x0qAbUEFdyYKaHza1K/B1sI4hEk1A==" - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "node_modules/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": { - "through": "2" + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", "dev": true, - "requires": { - "extend-shallow": "^3.0.0" + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "staged-git-files": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.1.1.tgz", - "integrity": "sha512-H89UNKr1rQJvI1c/PIR3kiAMBV23yvR7LItZiV74HWZwzt7f3YHuujJ9nJZlt58WlFox7XQsOahexwk7nTe69A==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "engines": { + "node": ">=12" }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "node_modules/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, - "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "stream-consume": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", - "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==", - "dev": true - }, - "stream-to": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-to/-/stream-to-0.2.2.tgz", - "integrity": "sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0=" - }, - "stream-to-buffer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz", - "integrity": "sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=", - "requires": { - "stream-to": "~0.2.0" + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "string-argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz", - "integrity": "sha1-2sMECGkMIfPDYwo/86BYd73L1zY=", - "dev": true + "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" + } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "node_modules/sver": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", + "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "optionalDependencies": { + "semver": "^6.3.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "node_modules/sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", + "dev": true, + "dependencies": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } }, - "stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "node_modules/sver/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "requires": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" + "optional": true, + "bin": { + "semver": "bin/semver.js" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "dependencies": { + "streamx": "^2.12.5" } }, - "strip-bom": { + "node_modules/ternary-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz", + "integrity": "sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==", + "dev": true, + "dependencies": { + "duplexify": "^4.1.1", + "fork-stream": "^0.0.4", + "merge-stream": "^2.0.0", + "through2": "^3.0.1" + } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "node_modules/ternary-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", - "dev": true + "node_modules/ternary-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", - "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "node_modules/ternary-stream/node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" } }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "node_modules/text-decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", "dev": true, - "requires": { - "execa": "^0.7.0" + "dependencies": { + "b4a": "^1.6.4" } }, - "text-table": { + "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 }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "through2": { + "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "requires": { + "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" - }, + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "through2": "~2.0.0", + "xtend": "~4.0.0" } }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "os-homedir": "^1.0.0" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "time-stamp": { + "node_modules/time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true + "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "timed-out": { + "node_modules/timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "engines": { + "node": ">=0.10.0" + } }, - "tinycolor2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", - "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" + "node_modules/timm": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, - "tldjs": { + "node_modules/tldjs": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/tldjs/-/tldjs-1.8.0.tgz", "integrity": "sha1-ucFr1t41e1X/y+fVvkH2s8p24/o=", - "requires": { + "hasInstallScript": true, + "dependencies": { "punycode": "^1.4.1" }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/tldjs/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" } }, - "tmp": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", - "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", "dev": true, - "requires": { - "os-tmpdir": "~1.0.1" + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "to-object-path": { + "node_modules/to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dev": true, - "requires": { + "dependencies": { "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "to-regex": { + "node_modules/to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, - "requires": { + "dependencies": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", "regex-not": "^1.0.2", "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "dependencies": { + "is-number": "^7.0.0" }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-regex/node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", - "requires": { - "hoek": "2.x.x" + "node_modules/to-regex/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "node_modules/to-regex/node_modules/is-descriptor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", + "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, - "requires": { - "nopt": "~1.0.10" + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" + "node_modules/to-regex/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/token-types/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "bin": { + "nodetouch": "bin/nodetouch.js" } }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", "dev": true }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" + "node_modules/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, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "type-is": { + "node_modules/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": { + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "typedarray": { + "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, - "unc-path-regex": { + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, - "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "node_modules/undertaker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", + "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", "dev": true, - "requires": { - "debug": "^2.2.0" + "dependencies": { + "bach": "^2.0.1", + "fast-levenshtein": "^3.0.0", + "last-run": "^2.0.0", + "undertaker-registry": "^2.0.0" }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/undertaker-registry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", + "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/undertaker/node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "fastest-levenshtein": "^1.0.7" } }, - "union-value": { + "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==", + "dev": true + }, + "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, - "requires": { + "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "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, - "requires": { - "crypto-random-string": "^1.0.0" + "engines": { + "node": ">= 10.0.0" } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } }, - "unset-value": { + "node_modules/unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, - "requires": { + "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "upath": { + "node_modules/upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", - "dev": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" } }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - } + "punycode": "^2.1.0" } }, - "urix": { + "node_modules/uri-js/node_modules/punycode": { + "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/urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, - "url": { + "node_modules/url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { + "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true, - "requires": { - "prepend-http": "^1.0.1" + "engines": { + "node": ">=0.10.0" } }, - "url-regex": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz", - "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=", - "requires": { - "ip-regex": "^1.0.1" + "node_modules/utif2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", + "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", + "dependencies": { + "pako": "^1.0.11" } }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } }, - "uuid": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz", - "integrity": "sha1-ZUS7ot/ajBzxfmKaOjBeK7H+5sE=" + "node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" + } }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "node_modules/v8flags": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", + "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", "dev": true, - "requires": { - "user-home": "^1.1.1" + "engines": { + "node": ">= 10.13.0" } }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "validator": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/validator/-/validator-9.4.1.tgz", - "integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA==" + "node_modules/validator": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", + "dev": true, + "engines": { + "node": ">= 10.13.0" + } }, - "vary": { + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" } }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true, - "requires": { - "defaults": "^1.0.0", - "glob-stream": "^3.1.5", - "glob-watcher": "^0.0.6", - "graceful-fs": "^3.0.0", - "mkdirp": "^0.5.0", - "strip-bom": "^1.0.0", - "through2": "^0.6.1", - "vinyl": "^0.4.0" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "graceful-fs": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.12.tgz", - "integrity": "sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg==", - "dev": true, - "requires": { - "natives": "^1.1.3" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "node_modules/vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "dev": true, + "dependencies": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-contents/node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/vinyl-contents/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "dev": true, - "requires": { - "first-chunk-stream": "^1.0.0", - "is-utf8": "^0.2.0" - } + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/vinyl-contents/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } + { + "type": "patreon", + "url": "https://www.patreon.com/feross" }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "^0.2.0", - "clone-stats": "^0.0.1" - } + { + "type": "consulting", + "url": "https://feross.org/support" } + ] + }, + "node_modules/vinyl-contents/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/vinyl-contents/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "requires": { - "isexe": "^2.0.0" + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "node_modules/vinyl-fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs/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==", "dev": true, - "requires": { - "string-width": "^2.1.1" + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" } }, - "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 + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } }, - "wrap-ansi": { + "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", - "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0" - }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", "dev": true }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "requires": { - "mkdirp": "^0.5.1" + "engines": { + "node": ">=0.10.0" } }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "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, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "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" } }, - "x-xss-protection": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.0.0.tgz", - "integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk=" + "node_modules/wrap-ansi/node_modules/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "xhr": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", - "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", - "requires": { - "global": "~4.3.0", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dependencies": { + "global": "~4.4.0", "is-function": "^1.0.1", "parse-headers": "^2.0.0", "xtend": "^4.0.0" } }, - "xml-parse-from-string": { + "node_modules/xml-parse-from-string": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" }, - "xml2js": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", - "requires": { + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dependencies": { "sax": ">=0.6.0", - "xmlbuilder": "^4.1.0" + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "xmlbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", - "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", - "requires": { - "lodash": "^4.0.0" + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" } }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "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/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "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" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index 392caf0..4f2f5df 100644 --- a/package.json +++ b/package.json @@ -10,54 +10,51 @@ "cmt": "git-cz", "deploy": "now && now alias", "serve": "cross-env NODE_ENV=development gulp", - "start": "node src/index.js" + "start": "node src/index.js", + "format": "prettier --single-quote --trailing-comma none --tab-width=2 --write \"src/**/*.js\"" }, "devDependencies": { - "commitizen": "2.10.1", - "cross-env": "5.0.5", - "cz-conventional-changelog": "2.1.0", - "eslint": "4.19.1", - "eslint-config-semistandard": "12.0.1", - "eslint-config-standard": "10.2.1", - "eslint-plugin-import": "2.10.0", - "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.7.0", - "eslint-plugin-standard": "3.1.0", - "gulp": "3.9.1", - "gulp-eslint": "4.0.0", - "gulp-nodemon": "2.2.1", - "husky": "1.0.0-rc.13", - "lint-staged": "7.2.2", - "prettier": "1.14.2" + "@eslint/js": "^9.7.0", + "commitizen": "4.3.0", + "cross-env": "7.0.3", + "cz-conventional-changelog": "3.3.0", + "eslint": "^9.7.0", + "globals": "^15.8.0", + "gulp": "5.0.0", + "gulp-eslint-new": "^2.2.0", + "gulp-nodemon": "^2.2.1", + "husky": "9.1.1", + "lint-staged": "15.2.7", + "prettier": "3.3.3" }, "dependencies": { - "aws-sdk": "2.94.0", - "axios": "0.18.0", + "aws-sdk": "2.1660.0", + "axios": "1.7.2", "bcrypt-nodejs": "0.0.3", - "body-parser": "1.17.2", - "cors": "2.8.4", - "dotenv": "4.0.0", - "express": "4.15.3", - "form-data": "2.3.2", - "freemail": "1.5.0", - "google-auth-library": "0.10.0", - "helmet": "3.8.1", - "ip": "1.1.5", - "jimp": "0.2.28", - "jsonwebtoken": "7.4.1", - "lodash": "4.17.4", - "moment": "2.18.1", - "moment-timezone": "0.5.21", + "body-parser": "1.20.2", + "cors": "2.8.5", + "dotenv": "16.4.5", + "express": "4.19.2", + "form-data": "4.0.0", + "freemail": "1.7.0", + "google-auth-library": "9.11.0", + "helmet": "7.1.0", + "ip": "2.0.1", + "jimp": "0.22.12", + "jsonwebtoken": "9.0.2", + "lodash": "4.17.21", + "moment": "2.30.1", + "moment-timezone": "0.5.45", "mongodb-uri": "0.9.7", - "mongoose": "5.3.2", - "morgan": "1.8.2", + "mongoose": "8.5.1", + "morgan": "1.10.0", "multer": "1.3.0", - "nodemailer": "4.0.1", + "nodemailer": "6.9.14", "now": "11.4.6", - "randomstring": "1.1.5", + "randomstring": "1.3.0", "raven": "2.6.0", - "speakingurl": "14.0.0", - "validator": "9.4.1" + "speakingurl": "14.0.1", + "validator": "13.12.0" }, "lint-staged": { "src/**/*.{js}": [ @@ -78,5 +75,8 @@ "hooks": { "pre-commit": "lint-staged" } + }, + "overrides": { + "graceful-fs": "^4.2.11" } } diff --git a/src/helpers/constants.js b/src/helpers/constants.js index 53eeef5..72f82c7 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -1,129 +1,129 @@ -module.exports = { - languages: ['en', 'es'], - placesTypes: [ - 'accounting', - 'airport', - 'amusement_park', - 'aquarium', - 'art_gallery', - 'atm', - 'bakery', - 'bank', - 'bar', - 'beauty_salon', - 'bicycle_store', - 'book_store', - 'bowling_alley', - 'bus_station', - 'cafe', - 'campground', - 'car_dealer', - 'car_rental', - 'car_repair', - 'car_wash', - 'casino', - 'cemetery', - 'church', - 'city_hall', - 'clothing_store', - 'convenience_store', - 'courthouse', - 'dentist', - 'department_store', - 'doctor', - 'electrician', - 'electronics_store', - 'embassy', - 'establishment', - 'fire_station', - 'florist', - 'funeral_home', - 'furniture_store', - 'gas_station', - 'gym', - 'hair_care', - 'hardware_store', - 'hindu_temple', - 'home_goods_store', - 'hospital', - 'insurance_agency', - 'jewelry_store', - 'laundry', - 'lawyer', - 'library', - 'liquor_store', - 'local_government_office', - 'locksmith', - 'lodging', - 'meal_delivery', - 'meal_takeaway', - 'mosque', - 'movie_rental', - 'movie_theater', - 'moving_company', - 'museum', - 'night_club', - 'painter', - 'park', - 'parking', - 'pet_store', - 'pharmacy', - 'physiotherapist', - 'plumber', - 'police', - 'post_office', - 'real_estate_agency', - 'restaurant', - 'roofing_contractor', - 'rv_park', - 'school', - 'shoe_store', - 'shopping_mall', - 'spa', - 'stadium', - 'storage', - 'store', - 'subway_station', - 'synagogue', - 'taxi_stand', - 'train_station', - 'transit_station', - 'travel_agency', - 'university', - 'veterinary_care', - 'zoo' - ], - directionsTypes: [ - 'administrative_area_level_1', - 'administrative_area_level_2', - 'administrative_area_level_3', - 'administrative_area_level_4', - 'administrative_area_level_5', - 'colloquial_area', - 'country', - 'finance', - 'floor', - 'geocode', - 'intersection', - 'locality', - 'natural_feature', - 'neighborhood', - 'place_of_worship', - 'political', - 'postal_code', - 'postal_code_prefix', - 'postal_code_suffix', - 'postal_town', - 'premise', - 'route', - 'street_address', - 'street_number', - 'sublocality', - 'sublocality_level_5', - 'sublocality_level_4', - 'sublocality_level_3', - 'sublocality_level_2', - 'sublocality_level_1', - 'subpremise' - ] -}; +module.exports = { + languages: ['en', 'es'], + placesTypes: [ + 'accounting', + 'airport', + 'amusement_park', + 'aquarium', + 'art_gallery', + 'atm', + 'bakery', + 'bank', + 'bar', + 'beauty_salon', + 'bicycle_store', + 'book_store', + 'bowling_alley', + 'bus_station', + 'cafe', + 'campground', + 'car_dealer', + 'car_rental', + 'car_repair', + 'car_wash', + 'casino', + 'cemetery', + 'church', + 'city_hall', + 'clothing_store', + 'convenience_store', + 'courthouse', + 'dentist', + 'department_store', + 'doctor', + 'electrician', + 'electronics_store', + 'embassy', + 'establishment', + 'fire_station', + 'florist', + 'funeral_home', + 'furniture_store', + 'gas_station', + 'gym', + 'hair_care', + 'hardware_store', + 'hindu_temple', + 'home_goods_store', + 'hospital', + 'insurance_agency', + 'jewelry_store', + 'laundry', + 'lawyer', + 'library', + 'liquor_store', + 'local_government_office', + 'locksmith', + 'lodging', + 'meal_delivery', + 'meal_takeaway', + 'mosque', + 'movie_rental', + 'movie_theater', + 'moving_company', + 'museum', + 'night_club', + 'painter', + 'park', + 'parking', + 'pet_store', + 'pharmacy', + 'physiotherapist', + 'plumber', + 'police', + 'post_office', + 'real_estate_agency', + 'restaurant', + 'roofing_contractor', + 'rv_park', + 'school', + 'shoe_store', + 'shopping_mall', + 'spa', + 'stadium', + 'storage', + 'store', + 'subway_station', + 'synagogue', + 'taxi_stand', + 'train_station', + 'transit_station', + 'travel_agency', + 'university', + 'veterinary_care', + 'zoo' + ], + directionsTypes: [ + 'administrative_area_level_1', + 'administrative_area_level_2', + 'administrative_area_level_3', + 'administrative_area_level_4', + 'administrative_area_level_5', + 'colloquial_area', + 'country', + 'finance', + 'floor', + 'geocode', + 'intersection', + 'locality', + 'natural_feature', + 'neighborhood', + 'place_of_worship', + 'political', + 'postal_code', + 'postal_code_prefix', + 'postal_code_suffix', + 'postal_town', + 'premise', + 'route', + 'street_address', + 'street_number', + 'sublocality', + 'sublocality_level_5', + 'sublocality_level_4', + 'sublocality_level_3', + 'sublocality_level_2', + 'sublocality_level_1', + 'subpremise' + ] +}; diff --git a/src/helpers/db-connector.js b/src/helpers/db-connector.js index 9ee3db3..183145d 100644 --- a/src/helpers/db-connector.js +++ b/src/helpers/db-connector.js @@ -1,106 +1,97 @@ -const mongoose = require('mongoose'); -const mongoUri = require('mongodb-uri'); - -mongoose.Promise = global.Promise; - -const delayToReconnect = 1000; -let disconnecting; -let initialized = false; -const mongodbURI = process.env.MONGODB_URI; -const dbName = mongoUri.parse(mongodbURI).database; -const options = { - connectTimeoutMS: 30000, - keepAlive: 120, - useCreateIndex: true, - useNewUrlParser: true -}; - -function logging(db) { - db.on('connected', () => - console.log(`Database connection to ${dbName} established`) - ); - db.on('open', () => console.log(`Database connection to ${dbName} opened`)); - db.on('disconnected', () => { - if (disconnecting !== true) { - console.log(`Database connection to ${dbName} lost`); - } - }); - db.on('error', err => { - console.log(`Database connection to ${dbName} error`); - throw err; - }); -} - -function open() { - console.log(`Opening database connection to ${dbName}...`); - mongoose.connect( - mongodbURI, - options - ); -} - -function reconnection(db) { - let timer; - - function reconnect() { - timer = false; - open(db); - } - - function clear() { - if (timer) { - clearTimeout(timer); - } - timer = false; - } - - function schedule() { - if (disconnecting) { - console.log(`Database connection to ${dbName} explicitly shut down`); - return; - } - - if (timer) { - clearTimeout(timer); - } - timer = setTimeout(reconnect, delayToReconnect); - } - - db.on('disconnected', schedule); - db.on('connected', clear); -} - -function connect(done) { - const db = mongoose.connection; - - if (initialized === false) { - initialized = true; - logging(db); - reconnection(db); - } - - open(); - - db.once('connected', done); -} - -function disconnect(done) { - const db = mongoose.connection; - - function disconnected() { - disconnecting = false; - if (done) { - done(); - } - } - - if (db.readyState !== 0) { - disconnecting = true; - db.once('disconnected', disconnected); - db.close(); - } -} - -connect.disconnect = disconnect; - -module.exports = connect; +const mongoose = require('mongoose'); +const mongoUri = require('mongodb-uri'); + +mongoose.Promise = global.Promise; + +const delayToReconnect = 1000; +let disconnecting; +let initialized = false; +const mongodbURI = process.env.MONGODB_URI; +const dbName = mongoUri.parse(mongodbURI).database; + +function logging(db) { + db.on('connected', () => + console.log(`Database connection to ${dbName} established`) + ); + db.on('open', () => console.log(`Database connection to ${dbName} opened`)); + db.on('disconnected', () => { + if (disconnecting !== true) { + console.log(`Database connection to ${dbName} lost`); + } + }); + db.on('error', (err) => { + console.log(`Database connection to ${dbName} error`); + throw err; + }); +} + +function open() { + console.log(`Opening database connection to ${dbName}...`); + mongoose.connect(mongodbURI); +} + +function reconnection(db) { + let timer; + + function reconnect() { + timer = false; + open(db); + } + + function clear() { + if (timer) { + clearTimeout(timer); + } + timer = false; + } + + function schedule() { + if (disconnecting) { + console.log(`Database connection to ${dbName} explicitly shut down`); + return; + } + + if (timer) { + clearTimeout(timer); + } + timer = setTimeout(reconnect, delayToReconnect); + } + + db.on('disconnected', schedule); + db.on('connected', clear); +} + +function connect(done) { + const db = mongoose.connection; + + if (initialized === false) { + initialized = true; + logging(db); + reconnection(db); + } + + open(); + + db.once('connected', done); +} + +function disconnect(done) { + const db = mongoose.connection; + + function disconnected() { + disconnecting = false; + if (done) { + done(); + } + } + + if (db.readyState !== 0) { + disconnecting = true; + db.once('disconnected', disconnected); + db.close(); + } +} + +connect.disconnect = disconnect; + +module.exports = connect; diff --git a/src/helpers/index.js b/src/helpers/index.js index 3445d7f..94f26fc 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -1,106 +1,109 @@ -const aws = require('aws-sdk'); -const { camelCase } = require('lodash'); -const jwt = require('jsonwebtoken'); -const { mapKeys, pickBy } = require('lodash'); -const nodemailer = require('nodemailer'); -const { snakeCase } = require('lodash'); - -const { User } = require('../models/user'); - -module.exports = { - cleanSpaces(string) { - return string.replace(/\s+/g, ' ').trim(); - }, - deleteUnusedProperties(obj) { - return pickBy(obj, prop => prop); - }, - isAuthenticated: ({ isOptional }) => async (req, res, next) => { - const authorizationHeader = req.headers.authorization; - let token; - - if (authorizationHeader) { - token = authorizationHeader.split(' ')[1]; - } - - if (token) { - let decoded; - try { - decoded = await jwt.verify(token, process.env.JWT_SECRET); - } catch (err) { - return res.status(401).json({ general: 'Failed to authenticate' }); - } - - let user; - try { - user = await User.findOne({ - _id: decoded.userId, - isArchived: false - }).select( - '-__v -createdAt -isAdmin -isArchived -isBlocked -hashedPassword -updatedAt' - ); - } catch (err) { - console.log( - `User ${decoded.userId} failed to be found at authenticate` - ); - return next(err); - } - - if (user) { - req.user = user; - - if ( - (isOptional && req.user && req.user.isBlocked) || - (!isOptional && req.user.isBlocked) - ) { - return res.status(423).json({ general: 'You are blocked' }); - } - - return next(); - } - - return res.status(404).json({ general: 'User not found' }); - } - - if (isOptional) { - return next(); - } - - return res.status(401).json({ general: 'No token provided' }); - }, - isNumber(number) { - return !isNaN(parseFloat(number)) && isFinite(number); - }, - mapCamelCaseKeys(obj) { - return mapKeys(obj, (value, key) => camelCase(key)); - }, - mapSnakeCaseKeys(obj) { - return mapKeys(obj, (value, key) => snakeCase(key)); - }, - removeSpaces(string) { - return string.replace(/\s/g, ''); - }, - sendEmail({ - senderEmail = process.env.SENDER_EMAIL, - receiversEmails, - subject, - htmlContent, - textContent - }) { - const transporter = nodemailer.createTransport({ - SES: new aws.SES({ - apiVersion: '2010-12-01' - }) - }); - - return transporter.sendMail({ - from: `"AXS Map" <${senderEmail}>`, - to: receiversEmails.join(', '), - subject, - text: textContent, - html: htmlContent - }); - }, - toJSON(obj) { - return JSON.parse(JSON.stringify(obj)); - } -}; +const aws = require('aws-sdk'); +const { camelCase } = require('lodash'); +const jwt = require('jsonwebtoken'); +const { mapKeys, pickBy } = require('lodash'); +const nodemailer = require('nodemailer'); +const { snakeCase } = require('lodash'); + +const { User } = require('../models/user'); + +module.exports = { + cleanSpaces(string) { + return string.replace(/\s+/g, ' ').trim(); + }, + deleteUnusedProperties(obj) { + return pickBy(obj, (prop) => prop); + }, + isAuthenticated: + ({ isOptional }) => + async (req, res, next) => { + const authorizationHeader = req.headers.authorization; + let token; + + if (authorizationHeader) { + token = authorizationHeader.split(' ')[1]; + } + + if (token) { + let decoded; + try { + decoded = await jwt.verify(token, process.env.JWT_SECRET); + } catch (err) { + console.log(err); + return res.status(401).json({ general: 'Failed to authenticate' }); + } + + let user; + try { + user = await User.findOne({ + _id: decoded.userId, + isArchived: false + }).select( + '-__v -createdAt -isAdmin -isArchived -isBlocked -hashedPassword -updatedAt' + ); + } catch (err) { + console.log( + `User ${decoded.userId} failed to be found at authenticate` + ); + return next(err); + } + + if (user) { + req.user = user; + + if ( + (isOptional && req.user && req.user.isBlocked) || + (!isOptional && req.user.isBlocked) + ) { + return res.status(423).json({ general: 'You are blocked' }); + } + + return next(); + } + + return res.status(404).json({ general: 'User not found' }); + } + + if (isOptional) { + return next(); + } + + return res.status(401).json({ general: 'No token provided' }); + }, + isNumber(number) { + return !isNaN(parseFloat(number)) && isFinite(number); + }, + mapCamelCaseKeys(obj) { + return mapKeys(obj, (value, key) => camelCase(key)); + }, + mapSnakeCaseKeys(obj) { + return mapKeys(obj, (value, key) => snakeCase(key)); + }, + removeSpaces(string) { + return string.replace(/\s/g, ''); + }, + sendEmail({ + senderEmail = process.env.SENDER_EMAIL, + receiversEmails, + subject, + htmlContent, + textContent + }) { + const transporter = nodemailer.createTransport({ + SES: new aws.SES({ + apiVersion: '2010-12-01' + }) + }); + + return transporter.sendMail({ + from: `"AXS Map" <${senderEmail}>`, + to: receiversEmails.join(', '), + subject, + text: textContent, + html: htmlContent + }); + }, + toJSON(obj) { + return JSON.parse(JSON.stringify(obj)); + } +}; diff --git a/src/helpers/venue-review-summary.js b/src/helpers/venue-review-summary.js index e752584..6fc30b5 100644 --- a/src/helpers/venue-review-summary.js +++ b/src/helpers/venue-review-summary.js @@ -8,8 +8,8 @@ function assignFromYesNo(venueField) { // Mongoose hasOwnProperty test issues if ( venueField && - venueField.hasOwnProperty('yes') && - venueField.hasOwnProperty('no') && + 'yes' in venueField && + 'no' in venueField && !(venueField.yes === 0 && venueField.no === 0) ) { if (venueField.yes >= venueField.no) { @@ -23,12 +23,10 @@ function assignFromYesNo(venueField) { } function assignFromSteps(stepField) { - let moreThanTwo = stepField.hasOwnProperty('moreThanTwo') - ? stepField.moreThanTwo - : 0; - let two = stepField.hasOwnProperty('two') ? stepField.two : 0; - let one = stepField.hasOwnProperty('one') ? stepField.one : 0; - let zero = stepField.hasOwnProperty('zero') ? stepField.zero : 0; + let moreThanTwo = 'moreThanTwo' in stepField ? stepField.moreThanTwo : 0; + let two = 'two' in stepField ? stepField.two : 0; + let one = 'one' in stepField ? stepField.one : 0; + let zero = 'zero' in stepField ? stepField.zero : 0; if (moreThanTwo === 0 && two === 0 && one === 0 && zero === 0) { return null; @@ -95,7 +93,7 @@ module.exports = { //console.log('in calculateRatingLevel, select venue data: ', venueData); let sectionLogic, ratingDefinition; - if (reviewSummaryLogic.hasOwnProperty(sectionName)) { + if (sectionName in reviewSummaryLogic) { //valid values: entrance, restroom, interior sectionLogic = reviewSummaryLogic[sectionName]; } else { @@ -108,37 +106,37 @@ module.exports = { let ratingLevel, ratingGlyphs; const ratingLevels = ['alert', 'caution', 'accessible']; - for (rl = 0; rl < ratingLevels.length; rl++) { + for (let rl = 0; rl < ratingLevels.length; rl++) { if ( - sectionLogic.hasOwnProperty(ratingLevels[rl]) && + ratingLevels[rl] in sectionLogic && sectionLogic[ratingLevels[rl]].length > 0 ) { //level loop - for (idx = 0; idx < sectionLogic[ratingLevels[rl]].length; idx++) { + for (let idx = 0; idx < sectionLogic[ratingLevels[rl]].length; idx++) { ratingDefinition = sectionLogic[ratingLevels[rl]][idx]; let ratingDefinitionMatch = false; if ( - ratingDefinition.hasOwnProperty('field') && - venueData.hasOwnProperty(ratingDefinition.field) + 'field' in ratingDefinition && + ratingDefinition.field in venueData ) { if ( - (ratingDefinition.hasOwnProperty('matchValue') && + ('matchValue' in ratingDefinition && venueData[ratingDefinition.field] === ratingDefinition.matchValue) || - (ratingDefinition.hasOwnProperty('notMatchValue') && + ('notMatchValue' in ratingDefinition && venueData[ratingDefinition.field] !== ratingDefinition.notMatchValue) ) { ratingDefinitionMatch = true; } - } else if (ratingDefinition.hasOwnProperty('fields')) { + } else if ('fields' in ratingDefinition) { let fieldMatchCount = 0; - for (field of ratingDefinition.fields) { + for (let field of ratingDefinition.fields) { if ( - (ratingDefinition.hasOwnProperty('matchValue') && + ('matchValue' in ratingDefinition && venueData[field] === ratingDefinition.matchValue) || - (ratingDefinition.hasOwnProperty('notMatchValue') && + ('notMatchValue' in ratingDefinition && venueData[field] !== ratingDefinition.notMatchValue) ) { fieldMatchCount++; @@ -150,21 +148,18 @@ module.exports = { } } - if ( - ratingDefinitionMatch === true && - ratingDefinition.hasOwnProperty('and') - ) { + if (ratingDefinitionMatch === true && 'and' in ratingDefinition) { //console.log('Evaluate AND condition in ' + sectionName); if ( - ratingDefinition.and.hasOwnProperty('field') && - venueData.hasOwnProperty(ratingDefinition.and.field) + 'field' in ratingDefinition.and && + ratingDefinition.and.field in venueData ) { //evaluate 'and' condition depending on match or noMatch value - if (ratingDefinition.and.hasOwnProperty('matchValue')) { + if ('matchValue' in ratingDefinition.and) { ratingDefinitionMatch = venueData[ratingDefinition.and.field] == ratingDefinition.and.matchValue; - } else if (ratingDefinition.and.hasOwnProperty('notMatchValue')) { + } else if ('notMatchValue' in ratingDefinition.and) { ratingDefinitionMatch = venueData[ratingDefinition.and.field] !== ratingDefinition.and.notMatchValue; @@ -202,9 +197,9 @@ module.exports = { //console.log('ratingLevel not set: ', sectionLogic); ratingLevel = 0; ratingGlyphs = - sectionLogic.hasOwnProperty('default') && + 'default' in sectionLogic && sectionLogic.default.length > 0 && - sectionLogic.default[0].hasOwnProperty('showGlyph') + 'showGlyph' in sectionLogic.default[0] ? sectionLogic.default[0].showGlyph : ''; } diff --git a/src/index.js b/src/index.js index f75263b..6c650e1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,81 +1,81 @@ -const fs = require('fs'); -const https = require('https'); - -const bodyParser = require('body-parser'); -const cors = require('cors'); -const express = require('express'); -const helmet = require('helmet'); -const ip = require('ip'); -const morgan = require('morgan'); -const raven = require('raven'); - -// Fill process.env with environment variables -require('dotenv').config(); -//console.log(process.env) - -const port = process.env.PORT || 8000; - -const connectToDB = require('./helpers/db-connector'); -const routes = require('./routes'); - -function connectedToDB() { - const app = express(); - - raven - .config(process.env.SENTRY_URL, { - captureUnhandledRejections: true - }) - .install(); - - // Middlewares - app.use(raven.requestHandler()); - app.use(cors()); - app.use(morgan('dev')); - app.use(bodyParser.json()); - app.use(helmet()); - - // Routes - app.set('strict routing', true); - app.use('/', routes); - - // Error handling - app.use(raven.errorHandler()); - app.use((req, res, _next) => res.status(404).json({ general: 'Not found' })); - app.use((err, req, res, _next) => { - if (err instanceof SyntaxError) { - return res.status(400).json({ general: 'Invalid JSON format' }); - } - - console.error(err.stack); - return res.status(500).json({ general: 'Something went wrong' }); - }); - - process.on('uncaughtException', err => { - console.error(err); - raven.captureException(err); - }); - process.on('unhandledRejection', err => { - console.error(err); - raven.captureException(err); - }); - - // App Initialization - if (process.env.NODE_ENV === 'production') { - console.log(`Listening on http://${ip.address()}:${port}`); - app.listen(port); - } else { - https - .createServer( - { - key: fs.readFileSync('./certificates/server.key'), - cert: fs.readFileSync('./certificates/server.crt') - }, - app - ) - .listen(port, () => - console.log(`Listening on https://${ip.address()}:${port}`) - ); - } -} - -connectToDB(connectedToDB); +const fs = require('fs'); +const https = require('https'); + +const bodyParser = require('body-parser'); +const cors = require('cors'); +const express = require('express'); +const helmet = require('helmet'); +const ip = require('ip'); +const morgan = require('morgan'); +const raven = require('raven'); + +// Fill process.env with environment variables +require('dotenv').config(); +//console.log(process.env) + +const port = process.env.PORT || 8000; + +const connectToDB = require('./helpers/db-connector'); +const routes = require('./routes'); + +function connectedToDB() { + const app = express(); + + raven + .config(process.env.SENTRY_URL, { + captureUnhandledRejections: true + }) + .install(); + + // Middlewares + app.use(raven.requestHandler()); + app.use(cors()); + app.use(morgan('dev')); + app.use(bodyParser.json()); + app.use(helmet()); + + // Routes + app.set('strict routing', true); + app.use('/', routes); + + // Error handling + app.use(raven.errorHandler()); + app.use((req, res) => res.status(404).json({ general: 'Not found' })); + app.use((err, req, res) => { + if (err instanceof SyntaxError) { + return res.status(400).json({ general: 'Invalid JSON format' }); + } + + console.error(err.stack); + return res.status(500).json({ general: 'Something went wrong' }); + }); + + process.on('uncaughtException', (err) => { + console.error(err); + raven.captureException(err); + }); + process.on('unhandledRejection', (err) => { + console.error(err); + raven.captureException(err); + }); + + // App Initialization + if (process.env.NODE_ENV === 'production') { + console.log(`Listening on http://${ip.address()}:${port}`); + app.listen(port); + } else { + https + .createServer( + { + key: fs.readFileSync('./certificates/server.key'), + cert: fs.readFileSync('./certificates/server.crt') + }, + app + ) + .listen(port, () => + console.log(`Listening on https://${ip.address()}:${port}`) + ); + } +} + +connectToDB(connectedToDB); diff --git a/src/models/activation-ticket.js b/src/models/activation-ticket.js index 621d2c0..1fa8760 100644 --- a/src/models/activation-ticket.js +++ b/src/models/activation-ticket.js @@ -1,48 +1,48 @@ -const mongoose = require('mongoose'); - -const activationTicketSchema = new mongoose.Schema( - { - email: { - type: String, - maxlength: [254, 'Should have less than 255 characters'], - required: [true, 'Is required'] - }, - expiresAt: { - type: Date, - required: [true, 'Is required'] - }, - key: { - type: String, - maxlength: [75, 'Should have less than 76 characters'], - required: [true, 'Is required'] - }, - userData: { - firstName: { - type: String, - maxlength: [24, 'Should have less than 25 characters'] - }, - isSubscribed: { - type: Boolean - }, - lastName: { - type: String, - maxlength: [36, 'Should have less than 37 characters'] - }, - password: { - type: String, - maxlength: [30, 'Should have less than 31 characters'], - minlength: [8, 'Should have more than 7 characters'] - }, - username: { - type: String, - maxlength: [67, 'Should have less than 68 characters'] - } - } - }, - { timestamps: true } -); - -module.exports = { - ActivationTicket: mongoose.model('ActivationTicket', activationTicketSchema), - activationTicketSchema -}; +const mongoose = require('mongoose'); + +const activationTicketSchema = new mongoose.Schema( + { + email: { + type: String, + maxlength: [254, 'Should have less than 255 characters'], + required: [true, 'Is required'] + }, + expiresAt: { + type: Date, + required: [true, 'Is required'] + }, + key: { + type: String, + maxlength: [75, 'Should have less than 76 characters'], + required: [true, 'Is required'] + }, + userData: { + firstName: { + type: String, + maxlength: [24, 'Should have less than 25 characters'] + }, + isSubscribed: { + type: Boolean + }, + lastName: { + type: String, + maxlength: [36, 'Should have less than 37 characters'] + }, + password: { + type: String, + maxlength: [30, 'Should have less than 31 characters'], + minlength: [8, 'Should have more than 7 characters'] + }, + username: { + type: String, + maxlength: [67, 'Should have less than 68 characters'] + } + } + }, + { timestamps: true } +); + +module.exports = { + ActivationTicket: mongoose.model('ActivationTicket', activationTicketSchema), + activationTicketSchema +}; diff --git a/src/models/event.js b/src/models/event.js index a767260..8c4b586 100644 --- a/src/models/event.js +++ b/src/models/event.js @@ -1,141 +1,141 @@ -const mongoose = require('mongoose'); - -const eventSchema = new mongoose.Schema( - { - address: { - type: String, - maxlength: [200, 'Should be less than 201 characters'], - required: [true, 'Is required'] - }, - description: { - type: String, - maxlength: [300, 'Should be less than 301 characters'] - }, - donationAmounts: { - type: [ - { - value: { - type: Number, - default: 5, - max: [10000, 'Should be less than 10001'], - min: [5, 'Should be greater than 4'] - } - } - ] - }, - donationEnabled: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - donationGoal: { - type: Number, - default: 10, - max: [100000, 'Should be less than 100001'], - min: [10, 'Should be greater than 9'] - }, - donationId: { - type: String, - default: '' - }, - endDate: { - type: Date, - required: [true, 'Is required'] - }, - isArchived: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isOpen: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - location: { - type: { - type: String, - default: 'Point' - }, - coordinates: [Number] - }, - managers: { - type: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ], - required: [true, 'Is required'] - }, - name: { - type: String, - maxlength: [100, 'Should be less than 101 characters'], - required: [true, 'Is required'] - }, - participants: { - type: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ] - }, - participantsGoal: { - type: Number, - max: [1000, 'Should be less than 1001'], - min: [1, 'Should be greater than 0'], - required: [true, 'Is required'] - }, - poster: { - type: String, - default: `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/events/posters/default.png`, - maxlength: [2000, 'Should be less than 2001 characters'], - required: [true, 'Is required'] - }, - reviewsAmount: { - type: Number, - default: 0, - required: [true, 'Is required'] - }, - reviewsGoal: { - type: Number, - max: [10000, 'Should be less than 10001'], - min: [1, 'Should be greater than 0'] - }, - startDate: { - type: Date, - required: [true, 'Is required'] - }, - teamManager: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - }, - teams: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - } - ], - venue: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Venue' - } - }, - { timestamps: true } -); - -eventSchema.index({ - address: 'text', - name: 'text', - endDate: 1, - reviewsAmount: 1, - startDate: 1 -}); - -module.exports = { - Event: mongoose.model('Event', eventSchema), - eventSchema -}; +const mongoose = require('mongoose'); + +const eventSchema = new mongoose.Schema( + { + address: { + type: String, + maxlength: [200, 'Should be less than 201 characters'], + required: [true, 'Is required'] + }, + description: { + type: String, + maxlength: [300, 'Should be less than 301 characters'] + }, + donationAmounts: { + type: [ + { + value: { + type: Number, + default: 5, + max: [10000, 'Should be less than 10001'], + min: [5, 'Should be greater than 4'] + } + } + ] + }, + donationEnabled: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + donationGoal: { + type: Number, + default: 10, + max: [100000, 'Should be less than 100001'], + min: [10, 'Should be greater than 9'] + }, + donationId: { + type: String, + default: '' + }, + endDate: { + type: Date, + required: [true, 'Is required'] + }, + isArchived: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isOpen: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + location: { + type: { + type: String, + default: 'Point' + }, + coordinates: [Number] + }, + managers: { + type: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + ], + required: [true, 'Is required'] + }, + name: { + type: String, + maxlength: [100, 'Should be less than 101 characters'], + required: [true, 'Is required'] + }, + participants: { + type: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + ] + }, + participantsGoal: { + type: Number, + max: [1000, 'Should be less than 1001'], + min: [1, 'Should be greater than 0'], + required: [true, 'Is required'] + }, + poster: { + type: String, + default: `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/events/posters/default.png`, + maxlength: [2000, 'Should be less than 2001 characters'], + required: [true, 'Is required'] + }, + reviewsAmount: { + type: Number, + default: 0, + required: [true, 'Is required'] + }, + reviewsGoal: { + type: Number, + max: [10000, 'Should be less than 10001'], + min: [1, 'Should be greater than 0'] + }, + startDate: { + type: Date, + required: [true, 'Is required'] + }, + teamManager: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Team' + }, + teams: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'Team' + } + ], + venue: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Venue' + } + }, + { timestamps: true } +); + +eventSchema.index({ + address: 'text', + name: 'text', + endDate: 1, + reviewsAmount: 1, + startDate: 1 +}); + +module.exports = { + Event: mongoose.model('Event', eventSchema), + eventSchema +}; diff --git a/src/models/password-ticket.js b/src/models/password-ticket.js index 00a4ced..ca98254 100644 --- a/src/models/password-ticket.js +++ b/src/models/password-ticket.js @@ -1,26 +1,26 @@ -const mongoose = require('mongoose'); - -const passwordTicketSchema = new mongoose.Schema( - { - email: { - type: String, - maxlength: [254, 'Should have less than 255 characters'], - required: [true, 'Is required'] - }, - expiresAt: { - type: Date, - required: [true, 'Is required'] - }, - key: { - type: String, - maxlength: [75, 'Should have less than 76 characters'], - required: [true, 'Is required'] - } - }, - { timestamps: true } -); - -module.exports = { - PasswordTicket: mongoose.model('PasswordTicket', passwordTicketSchema), - passwordTicketSchema -}; +const mongoose = require('mongoose'); + +const passwordTicketSchema = new mongoose.Schema( + { + email: { + type: String, + maxlength: [254, 'Should have less than 255 characters'], + required: [true, 'Is required'] + }, + expiresAt: { + type: Date, + required: [true, 'Is required'] + }, + key: { + type: String, + maxlength: [75, 'Should have less than 76 characters'], + required: [true, 'Is required'] + } + }, + { timestamps: true } +); + +module.exports = { + PasswordTicket: mongoose.model('PasswordTicket', passwordTicketSchema), + passwordTicketSchema +}; diff --git a/src/models/petition.js b/src/models/petition.js index af49041..01f3423 100644 --- a/src/models/petition.js +++ b/src/models/petition.js @@ -1,59 +1,59 @@ -const mongoose = require('mongoose'); - -const petitionSchema = new mongoose.Schema( - { - event: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Event' - }, - message: { - type: String, - maxlength: [300, 'Should be less than 301 characters'] - }, - sender: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - }, - state: { - type: String, - default: 'pending', - enum: { - values: ['accepted', 'canceled', 'pending', 'rejected'], - message: 'Should be a valid state' - }, - required: [true, 'Is required'] - }, - team: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - }, - type: { - type: String, - enum: { - values: [ - 'invite-team-event', - 'invite-user-event', - 'invite-user-team', - 'request-team-event', - 'request-user-event', - 'request-user-team' - ], - message: 'Should be a valid type' - }, - required: [true, 'Is required'] - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - }, - { timestamps: true } -); - -petitionSchema.index({ createdAt: -1 }); - -module.exports = { - Petition: mongoose.model('Petition', petitionSchema), - petitionSchema -}; +const mongoose = require('mongoose'); + +const petitionSchema = new mongoose.Schema( + { + event: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Event' + }, + message: { + type: String, + maxlength: [300, 'Should be less than 301 characters'] + }, + sender: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: [true, 'Is required'] + }, + state: { + type: String, + default: 'pending', + enum: { + values: ['accepted', 'canceled', 'pending', 'rejected'], + message: 'Should be a valid state' + }, + required: [true, 'Is required'] + }, + team: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Team' + }, + type: { + type: String, + enum: { + values: [ + 'invite-team-event', + 'invite-user-event', + 'invite-user-team', + 'request-team-event', + 'request-user-event', + 'request-user-team' + ], + message: 'Should be a valid type' + }, + required: [true, 'Is required'] + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + }, + { timestamps: true } +); + +petitionSchema.index({ createdAt: -1 }); + +module.exports = { + Petition: mongoose.model('Petition', petitionSchema), + petitionSchema +}; diff --git a/src/models/photo.js b/src/models/photo.js index 6a277a8..37d7049 100644 --- a/src/models/photo.js +++ b/src/models/photo.js @@ -1,66 +1,66 @@ -const mongoose = require('mongoose'); - -const photoSchema = new mongoose.Schema( - { - complaints: [ - { - comments: { - type: String, - maxlength: [300, 'Should be less than 301 characters'] - }, - createdAt: { - type: Date, - default: Date.now, - required: [true, 'Is required'] - }, - type: { - type: String, - enum: { - values: [ - 'biased', - 'copyright', - 'inconsistent', - 'offensive', - 'offtopic', - 'other', - 'spam' - ], - general: 'Invalid type of complaint' - }, - required: [true, 'Is required'] - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - } - } - ], - fileName: { - type: String, - maxlength: [25, 'Should be less than 26 characters'], - required: [true, 'Is required'] - }, - isAllowed: { - type: Boolean, - default: true, - required: [true, 'Is required'] - }, - url: { - type: String, - maxlength: [2000, 'Should be less than 2001 characters'], - required: [true, 'Is required'] - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - } - }, - { timestamps: true } -); - -module.exports = { - Photo: mongoose.model('Photo', photoSchema), - photoSchema -}; +const mongoose = require('mongoose'); + +const photoSchema = new mongoose.Schema( + { + complaints: [ + { + comments: { + type: String, + maxlength: [300, 'Should be less than 301 characters'] + }, + createdAt: { + type: Date, + default: Date.now, + required: [true, 'Is required'] + }, + type: { + type: String, + enum: { + values: [ + 'biased', + 'copyright', + 'inconsistent', + 'offensive', + 'offtopic', + 'other', + 'spam' + ], + general: 'Invalid type of complaint' + }, + required: [true, 'Is required'] + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: [true, 'Is required'] + } + } + ], + fileName: { + type: String, + maxlength: [25, 'Should be less than 26 characters'], + required: [true, 'Is required'] + }, + isAllowed: { + type: Boolean, + default: true, + required: [true, 'Is required'] + }, + url: { + type: String, + maxlength: [2000, 'Should be less than 2001 characters'], + required: [true, 'Is required'] + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: [true, 'Is required'] + } + }, + { timestamps: true } +); + +module.exports = { + Photo: mongoose.model('Photo', photoSchema), + photoSchema +}; diff --git a/src/models/refresh-token.js b/src/models/refresh-token.js index ac74a06..3ddeffe 100644 --- a/src/models/refresh-token.js +++ b/src/models/refresh-token.js @@ -1,27 +1,27 @@ -const mongoose = require('mongoose'); - -const refreshTokenSchema = new mongoose.Schema( - { - expiresAt: { - type: Date, - required: [true, 'Is required'] - }, - key: { - type: String, - maxlength: [80, 'Should have less than 81 characters'], - required: [true, 'Is required'], - unique: true - }, - userId: { - type: String, - maxlength: [24, 'Should have less than 25 characters'], - required: [true, 'Is required'] - } - }, - { timestamps: true } -); - -module.exports = { - RefreshToken: mongoose.model('RefreshToken', refreshTokenSchema), - refreshTokenSchema -}; +const mongoose = require('mongoose'); + +const refreshTokenSchema = new mongoose.Schema( + { + expiresAt: { + type: Date, + required: [true, 'Is required'] + }, + key: { + type: String, + maxlength: [80, 'Should have less than 81 characters'], + required: [true, 'Is required'], + unique: true + }, + userId: { + type: String, + maxlength: [24, 'Should have less than 25 characters'], + required: [true, 'Is required'] + } + }, + { timestamps: true } +); + +module.exports = { + RefreshToken: mongoose.model('RefreshToken', refreshTokenSchema), + refreshTokenSchema +}; diff --git a/src/models/review.js b/src/models/review.js index 7ed9617..f719643 100644 --- a/src/models/review.js +++ b/src/models/review.js @@ -1,122 +1,122 @@ -const mongoose = require('mongoose'); - -const reviewSchema = new mongoose.Schema( - { - //new expanded fields - hasPermanentRamp: Boolean, - hasPortableRamp: Boolean, - hasWideEntrance: Boolean, - hasAccessibleTableHeight: Boolean, - hasAccessibleElevator: Boolean, - hasInteriorRamp: Boolean, - hasSwingOutDoor: Boolean, - hasLargeStall: Boolean, - hasSupportAroundToilet: Boolean, - hasLoweredSinks: Boolean, - - //original fields - allowsGuideDog: Boolean, - comments: { - type: String, - maxlength: [300, 'Should be less than 301 characters'] - }, - complaints: [ - { - comments: { - type: String, - maxlength: [300, 'Should be less than 30 characters'] - }, - createdAt: { - type: Date, - default: Date.now, - required: [true, 'Is required'] - }, - type: { - type: String, - enum: { - values: [ - 'biased', - 'copyright', - 'inconsistent', - 'offensive', - 'offtopic', - 'other', - 'spam' - ], - general: 'Invalid type of complaint' - }, - required: [true, 'Is required'] - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - } - } - ], - - /* - * deprecated 5-star scoring - */ - _entryScore: { - type: Number - //max: [9, 'Should be less than 10'], - //min: [1, 'Should be more than 0'] - }, - _bathroomScore: { - type: Number - //max: [4, 'Should be less than 5'], - //min: [1, 'Should be more than 0'] - }, - _isScoreConverted: { - type: Boolean, - default: false - }, - - event: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Event' - }, - hasParking: Boolean, - hasSecondEntry: Boolean, - hasWellLit: Boolean, - isBanned: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isQuiet: Boolean, - isSpacious: Boolean, - steps: { - type: Number, - max: [3, 'Should be less than 4'], - min: [0, 'Should be more than -1'] - }, - team: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - }, - user: { - type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - }, - venue: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Venue', - required: [true, 'Is required'] - }, - voters: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ] - }, - { timestamps: true } -); - -module.exports = { - Review: mongoose.model('Review', reviewSchema), - reviewSchema -}; +const mongoose = require('mongoose'); + +const reviewSchema = new mongoose.Schema( + { + //new expanded fields + hasPermanentRamp: Boolean, + hasPortableRamp: Boolean, + hasWideEntrance: Boolean, + hasAccessibleTableHeight: Boolean, + hasAccessibleElevator: Boolean, + hasInteriorRamp: Boolean, + hasSwingOutDoor: Boolean, + hasLargeStall: Boolean, + hasSupportAroundToilet: Boolean, + hasLoweredSinks: Boolean, + + //original fields + allowsGuideDog: Boolean, + comments: { + type: String, + maxlength: [300, 'Should be less than 301 characters'] + }, + complaints: [ + { + comments: { + type: String, + maxlength: [300, 'Should be less than 30 characters'] + }, + createdAt: { + type: Date, + default: Date.now, + required: [true, 'Is required'] + }, + type: { + type: String, + enum: { + values: [ + 'biased', + 'copyright', + 'inconsistent', + 'offensive', + 'offtopic', + 'other', + 'spam' + ], + general: 'Invalid type of complaint' + }, + required: [true, 'Is required'] + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: [true, 'Is required'] + } + } + ], + + /* + * deprecated 5-star scoring + */ + _entryScore: { + type: Number + //max: [9, 'Should be less than 10'], + //min: [1, 'Should be more than 0'] + }, + _bathroomScore: { + type: Number + //max: [4, 'Should be less than 5'], + //min: [1, 'Should be more than 0'] + }, + _isScoreConverted: { + type: Boolean, + default: false + }, + + event: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Event' + }, + hasParking: Boolean, + hasSecondEntry: Boolean, + hasWellLit: Boolean, + isBanned: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isQuiet: Boolean, + isSpacious: Boolean, + steps: { + type: Number, + max: [3, 'Should be less than 4'], + min: [0, 'Should be more than -1'] + }, + team: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Team' + }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: 'User', + required: [true, 'Is required'] + }, + venue: { + type: mongoose.Schema.Types.ObjectId, + ref: 'Venue', + required: [true, 'Is required'] + }, + voters: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + ] + }, + { timestamps: true } +); + +module.exports = { + Review: mongoose.model('Review', reviewSchema), + reviewSchema +}; diff --git a/src/models/team.js b/src/models/team.js index 0d61217..9d96722 100644 --- a/src/models/team.js +++ b/src/models/team.js @@ -1,62 +1,62 @@ -const mongoose = require('mongoose'); - -const teamSchema = new mongoose.Schema( - { - avatar: { - type: String, - default: `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/teams/avatars/default.png`, - maxlength: [2000, 'Should be less than 2001 characters'], - required: [true, 'Is required'] - }, - description: { - type: String, - maxlength: [300, 'Should be less than 301 characters'] - }, - events: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'Event' - } - ], - isArchived: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - managers: { - type: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ], - required: [true, 'Is required'] - }, - members: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ], - name: { - type: String, - maxlength: [35, 'Should be less than 36 characters'], - required: [true, 'Is required'] - }, - reviewsAmount: { - type: Number, - default: 0, - required: [true, 'Is required'] - } - }, - { timestamps: true } -); - -teamSchema.index({ name: 'text', reviewsAmount: 1 }); - -module.exports = { - Team: mongoose.model('Team', teamSchema), - teamSchema -}; +const mongoose = require('mongoose'); + +const teamSchema = new mongoose.Schema( + { + avatar: { + type: String, + default: `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/teams/avatars/default.png`, + maxlength: [2000, 'Should be less than 2001 characters'], + required: [true, 'Is required'] + }, + description: { + type: String, + maxlength: [300, 'Should be less than 301 characters'] + }, + events: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'Event' + } + ], + isArchived: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + managers: { + type: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + ], + required: [true, 'Is required'] + }, + members: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'User' + } + ], + name: { + type: String, + maxlength: [35, 'Should be less than 36 characters'], + required: [true, 'Is required'] + }, + reviewsAmount: { + type: Number, + default: 0, + required: [true, 'Is required'] + } + }, + { timestamps: true } +); + +teamSchema.index({ name: 'text', reviewsAmount: 1 }); + +module.exports = { + Team: mongoose.model('Team', teamSchema), + teamSchema +}; diff --git a/src/models/user.js b/src/models/user.js index e0c9cb9..949b077 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -1,193 +1,193 @@ -const bcrypt = require('bcrypt-nodejs'); -const mongoose = require('mongoose'); - -const userSchema = new mongoose.Schema( - { - avatar: { - type: String, - default: `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/users/avatars/default.png`, - maxlength: [2000, 'Should be less than 2001 characters'], - required: [true, 'Is required'] - }, - description: { - type: String, - maxlength: [2000, 'Should be less than 2001 characters'] - }, - disabilities: { - type: [String], - default: ['none'], - enum: { - values: [ - 'brain', - 'cognitive', - 'hearing', - 'invisible', - 'none', - 'other', - 'physical', - 'private', - 'psychological', - 'spinal-cord', - 'vision' - ], - general: 'Invalid type of disability' - }, - required: [true, 'Is required'] - }, - email: { - type: String, - maxlength: [254, 'Should be less than 255 characters'] - }, - events: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'Event' - } - ], - facebookId: String, - firstName: { - type: String, - maxlength: [24, 'Should be less than 25 characters'], - required: [true, 'Is required'] - }, - gender: { - type: String, - default: 'private', - enum: { - values: ['female', 'male', 'other', 'private', 'transgender'], - general: 'Invalid type of gender' - }, - required: [true, 'Is required'] - }, - googleId: String, - hashedPassword: { - type: String, - maxlength: [256, 'Should be less than 255 characters'] - }, - isAdmin: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isArchived: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isBlocked: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isSubscribed: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - lastName: { - type: String, - maxlength: [36, 'Should be less than 37 characters'], - required: [true, 'Is required'] - }, - language: { - type: String, - default: 'en', - enum: { - values: ['en', 'es'], - general: 'Invalid type of language' - }, - required: [true, 'Is required'] - }, - phone: { - type: String, - maxlength: [50, 'Should be less than 51 characters'] - }, - reviewFieldsAmount: { - type: Number, - default: 0, - required: [true, 'Is required'] - }, - reviewsAmount: { - type: Number, - default: 0, - required: [true, 'Is required'] - }, - showDisabilities: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - showEmail: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - showPhone: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - teams: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - } - ], - username: { - type: String, - maxlength: [67, 'Should be less than 68 characters'] - }, - zip: { - type: String, - maxlength: [32, 'Should be less than 33 characters'] - } - }, - { timestamps: true } -); - -userSchema.index( - { - email: 'text', - firstName: 'text', - lastName: 'text', - username: 'text', - reviewsAmount: 1 - }, - { weights: { email: 5, username: 5 } } -); - -function hashPassword(password) { - bcrypt.genSalt(10, (errorOnSaltGeneration, salt) => { - if (errorOnSaltGeneration) { - return false; - } - - bcrypt.hash( - password, - salt, - null, - (errorOnHashingPassword, hashedPassword) => { - if (errorOnHashingPassword) { - return false; - } - - this.hashedPassword = hashedPassword; - return true; - } - ); - }); -} - -function comparePassword(password) { - return bcrypt.compareSync(password, this.hashedPassword); -} - -userSchema.virtual('password').set(hashPassword); -userSchema.methods.comparePassword = comparePassword; - -module.exports = { - User: mongoose.model('User', userSchema), - userSchema -}; +const bcrypt = require('bcrypt-nodejs'); +const mongoose = require('mongoose'); + +const userSchema = new mongoose.Schema( + { + avatar: { + type: String, + default: `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/users/avatars/default.png`, + maxlength: [2000, 'Should be less than 2001 characters'], + required: [true, 'Is required'] + }, + description: { + type: String, + maxlength: [2000, 'Should be less than 2001 characters'] + }, + disabilities: { + type: [String], + default: ['none'], + enum: { + values: [ + 'brain', + 'cognitive', + 'hearing', + 'invisible', + 'none', + 'other', + 'physical', + 'private', + 'psychological', + 'spinal-cord', + 'vision' + ], + general: 'Invalid type of disability' + }, + required: [true, 'Is required'] + }, + email: { + type: String, + maxlength: [254, 'Should be less than 255 characters'] + }, + events: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'Event' + } + ], + facebookId: String, + firstName: { + type: String, + maxlength: [24, 'Should be less than 25 characters'], + required: [true, 'Is required'] + }, + gender: { + type: String, + default: 'private', + enum: { + values: ['female', 'male', 'other', 'private', 'transgender'], + general: 'Invalid type of gender' + }, + required: [true, 'Is required'] + }, + googleId: String, + hashedPassword: { + type: String, + maxlength: [256, 'Should be less than 255 characters'] + }, + isAdmin: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isArchived: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isBlocked: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isSubscribed: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + lastName: { + type: String, + maxlength: [36, 'Should be less than 37 characters'], + required: [true, 'Is required'] + }, + language: { + type: String, + default: 'en', + enum: { + values: ['en', 'es'], + general: 'Invalid type of language' + }, + required: [true, 'Is required'] + }, + phone: { + type: String, + maxlength: [50, 'Should be less than 51 characters'] + }, + reviewFieldsAmount: { + type: Number, + default: 0, + required: [true, 'Is required'] + }, + reviewsAmount: { + type: Number, + default: 0, + required: [true, 'Is required'] + }, + showDisabilities: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + showEmail: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + showPhone: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + teams: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'Team' + } + ], + username: { + type: String, + maxlength: [67, 'Should be less than 68 characters'] + }, + zip: { + type: String, + maxlength: [32, 'Should be less than 33 characters'] + } + }, + { timestamps: true } +); + +userSchema.index( + { + email: 'text', + firstName: 'text', + lastName: 'text', + username: 'text', + reviewsAmount: 1 + }, + { weights: { email: 5, username: 5 } } +); + +function hashPassword(password) { + bcrypt.genSalt(10, (errorOnSaltGeneration, salt) => { + if (errorOnSaltGeneration) { + return false; + } + + bcrypt.hash( + password, + salt, + null, + (errorOnHashingPassword, hashedPassword) => { + if (errorOnHashingPassword) { + return false; + } + + this.hashedPassword = hashedPassword; + return true; + } + ); + }); +} + +function comparePassword(password) { + return bcrypt.compareSync(password, this.hashedPassword); +} + +userSchema.virtual('password').set(hashPassword); +userSchema.methods.comparePassword = comparePassword; + +module.exports = { + User: mongoose.model('User', userSchema), + userSchema +}; diff --git a/src/models/venue.js b/src/models/venue.js index 9c473f4..e0c475d 100644 --- a/src/models/venue.js +++ b/src/models/venue.js @@ -1,315 +1,315 @@ -const mongoose = require('mongoose'); - -const venueSchema = new mongoose.Schema( - { - //new expanded fields - hasPermanentRamp: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasPortableRamp: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasWideEntrance: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasAccessibleTableHeight: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasAccessibleElevator: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasInteriorRamp: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasSwingOutDoor: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasLargeStall: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasSupportAroundToilet: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasLoweredSinks: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - entranceScore: { - //enum: ['alert', 'caution', 'accessible', 'default'], - //description: 'can only be one of the enum values and is required', - //default: 'default' - type: Number, - default: 0 - }, - entranceGlyphs: { - type: String, - maxlength: [32, 'Should be less than 256 characters'] - }, - interiorScore: { - //enum: ['alert', 'caution', 'accessible', 'default'], - //description: 'can only be one of the enum values and is required', - //: 'default' - type: Number, - default: 0 - }, - interiorGlyphs: { - type: String, - maxlength: [32, 'Should be less than 256 characters'] - }, - restroomScore: { - //enum: ['alert', 'caution', 'accessible', 'default'], - //: 'can only be one of the enum values and is required', - //default: 'default' - type: Number, - default: 0 - }, - restroomGlyphs: { - type: String, - maxlength: [32, 'Should be less than 256 characters'] - }, - mapMarkerScore: { - type: Number, - default: 0 - }, - - //original fields - address: { - type: String, - maxlength: [255, 'Should be less than 256 characters'] - }, - allowsGuideDog: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - - /* - * deprecated 5-star scoring - */ - _bathroomReviews: { - type: Number, - default: 0 - //min: [0, 'Should be more than 1'] - }, - _bathroomScore: { - type: Number - //max: [4, 'Should be less than 5'], - //min: [1, 'Should be more than 0'] - }, - _entryReviews: { - type: Number, - default: 0 - //min: [0, 'Should be more than -1'] - }, - _entryScore: { - type: Number - //max: [9, 'Should be less than 10'], - //min: [1, 'Should be more than 0'] - }, - _isScoreConverted: { - type: Boolean, - default: false - }, - - hasParking: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasSecondEntry: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - hasWellLit: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - isArchived: { - type: Boolean, - default: false, - required: [true, 'Is required'] - }, - isQuiet: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - isSpacious: { - yes: { - type: Number, - default: 0 - }, - no: { - type: Number, - default: 0 - } - }, - location: { - type: { - type: String, - default: 'Point' - }, - coordinates: [Number] - }, - name: { - type: String, - maxlength: [255, 'Should be less than 256 characters'] - }, - photos: [ - { - type: mongoose.Schema.ObjectId, - ref: 'Photo' - } - ], - placeId: { - type: String, - maxlength: [255, 'Should be less than 256 characters'], - required: [true, 'Is required'] - }, - reviews: [ - { - type: mongoose.Schema.ObjectId, - ref: 'Review' - } - ], - steps: { - zero: { - type: Number, - default: 0 - }, - one: { - type: Number, - default: 0 - }, - two: { - type: Number, - default: 0 - }, - moreThanTwo: { - type: Number, - default: 0 - } - }, - types: [ - { - type: String, - maxlength: [50, 'Should be less than 51 characters'] - } - ] - }, - { timestamps: true } -); - -venueSchema.index({ location: '2dsphere', placeId: 1 }); - -venueSchema.virtual('coordinates').get(function() { - return { - lat: this.location.coordinates[1], - lng: this.location.coordinates[0] - }; -}); - -venueSchema.virtual('photo').get(function() { - return undefined; -}); - -module.exports = { - Venue: mongoose.model('Venue', venueSchema), - venueSchema -}; +const mongoose = require('mongoose'); + +const venueSchema = new mongoose.Schema( + { + //new expanded fields + hasPermanentRamp: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasPortableRamp: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasWideEntrance: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasAccessibleTableHeight: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasAccessibleElevator: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasInteriorRamp: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasSwingOutDoor: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasLargeStall: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasSupportAroundToilet: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasLoweredSinks: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + entranceScore: { + //enum: ['alert', 'caution', 'accessible', 'default'], + //description: 'can only be one of the enum values and is required', + //default: 'default' + type: Number, + default: 0 + }, + entranceGlyphs: { + type: String, + maxlength: [32, 'Should be less than 256 characters'] + }, + interiorScore: { + //enum: ['alert', 'caution', 'accessible', 'default'], + //description: 'can only be one of the enum values and is required', + //: 'default' + type: Number, + default: 0 + }, + interiorGlyphs: { + type: String, + maxlength: [32, 'Should be less than 256 characters'] + }, + restroomScore: { + //enum: ['alert', 'caution', 'accessible', 'default'], + //: 'can only be one of the enum values and is required', + //default: 'default' + type: Number, + default: 0 + }, + restroomGlyphs: { + type: String, + maxlength: [32, 'Should be less than 256 characters'] + }, + mapMarkerScore: { + type: Number, + default: 0 + }, + + //original fields + address: { + type: String, + maxlength: [255, 'Should be less than 256 characters'] + }, + allowsGuideDog: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + + /* + * deprecated 5-star scoring + */ + _bathroomReviews: { + type: Number, + default: 0 + //min: [0, 'Should be more than 1'] + }, + _bathroomScore: { + type: Number + //max: [4, 'Should be less than 5'], + //min: [1, 'Should be more than 0'] + }, + _entryReviews: { + type: Number, + default: 0 + //min: [0, 'Should be more than -1'] + }, + _entryScore: { + type: Number + //max: [9, 'Should be less than 10'], + //min: [1, 'Should be more than 0'] + }, + _isScoreConverted: { + type: Boolean, + default: false + }, + + hasParking: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasSecondEntry: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasWellLit: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + isArchived: { + type: Boolean, + default: false, + required: [true, 'Is required'] + }, + isQuiet: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + isSpacious: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + location: { + type: { + type: String, + default: 'Point' + }, + coordinates: [Number] + }, + name: { + type: String, + maxlength: [255, 'Should be less than 256 characters'] + }, + photos: [ + { + type: mongoose.Schema.ObjectId, + ref: 'Photo' + } + ], + placeId: { + type: String, + maxlength: [255, 'Should be less than 256 characters'], + required: [true, 'Is required'] + }, + reviews: [ + { + type: mongoose.Schema.ObjectId, + ref: 'Review' + } + ], + steps: { + zero: { + type: Number, + default: 0 + }, + one: { + type: Number, + default: 0 + }, + two: { + type: Number, + default: 0 + }, + moreThanTwo: { + type: Number, + default: 0 + } + }, + types: [ + { + type: String, + maxlength: [50, 'Should be less than 51 characters'] + } + ] + }, + { timestamps: true } +); + +venueSchema.index({ location: '2dsphere', placeId: 1 }); + +venueSchema.virtual('coordinates').get(function () { + return { + lat: this.location.coordinates[1], + lng: this.location.coordinates[0] + }; +}); + +venueSchema.virtual('photo').get(function () { + return undefined; +}); + +module.exports = { + Venue: mongoose.model('Venue', venueSchema), + venueSchema +}; diff --git a/src/routes/auth/activate-account.js b/src/routes/auth/activate-account.js index b78caf7..e5a0655 100644 --- a/src/routes/auth/activate-account.js +++ b/src/routes/auth/activate-account.js @@ -1,139 +1,139 @@ -const crypto = require('crypto'); - -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -const { ActivationTicket } = require('../../models/activation-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - const key = req.params.key; - - let activationTicket; - try { - activationTicket = await ActivationTicket.findOne({ key }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Activation ticket not found' }); - } - - console.log( - `Activation ticket with key ${key} failed to be found at activate-account.` - ); - return next(err); - } - - if (!activationTicket) { - return res.status(404).json({ general: 'Activation ticket not found' }); - } - - let expiresAt = moment(activationTicket.expiresAt).utc(); - const now = moment.utc(); - if (expiresAt.isBefore(now)) { - try { - await activationTicket.remove(); - } catch (err) { - console.log( - `Activation ticket with key ${ - activationTicket.key - } failed to be deleted at activate-account.` - ); - return next(err); - } - - return res.status(400).json({ general: 'Activation ticket expired' }); - } - - const userData = Object.assign({}, activationTicket.userData, { - email: activationTicket.email - }); - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - $or: [{ email: userData.email }, { username: userData.username }], - isArchived: false - }); - } catch (err) { - console.log('Users failed to be found at activate-account.'); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - for (const user of repeatedUsers) { - if (user.email === userData.email) { - return res.status(400).json({ email: 'Is already taken' }); - } - - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}`; - - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at activate-account.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } - } - - let user; - try { - user = await User.create(userData); - } catch (err) { - console.log( - `User failed to be created at activate-account.\nData: ${JSON.stringify( - userData - )}` - ); - return next(err); - } - - const today = moment.utc(); - expiresAt = today.add(14, 'days').toDate(); - const refreshTokenData = { - expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id - }; - - try { - await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token failed to be created at activate-account.\nData: ${JSON.stringify( - refreshTokenData - )}` - ); - return next(err); - } - - try { - await activationTicket.remove(); - } catch (err) { - console.log( - `Activation ticket with key ${ - activationTicket.key - } failed to be deleted at activate-account.` - ); - return next(err); - } - - return res.redirect(`${process.env.APP_URL}/sign-in`); -}; +const crypto = require('crypto'); + +const moment = require('moment'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +const { ActivationTicket } = require('../../models/activation-ticket'); +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + const key = req.params.key; + + let activationTicket; + try { + activationTicket = await ActivationTicket.findOne({ key }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Activation ticket not found' }); + } + + console.log( + `Activation ticket with key ${key} failed to be found at activate-account.` + ); + return next(err); + } + + if (!activationTicket) { + return res.status(404).json({ general: 'Activation ticket not found' }); + } + + let expiresAt = moment(activationTicket.expiresAt).utc(); + const now = moment.utc(); + if (expiresAt.isBefore(now)) { + try { + await activationTicket.remove(); + } catch (err) { + console.log( + `Activation ticket with key ${ + activationTicket.key + } failed to be deleted at activate-account.` + ); + return next(err); + } + + return res.status(400).json({ general: 'Activation ticket expired' }); + } + + const userData = Object.assign({}, activationTicket.userData, { + email: activationTicket.email + }); + + let repeatedUsers; + try { + repeatedUsers = await User.find({ + $or: [{ email: userData.email }, { username: userData.username }], + isArchived: false + }); + } catch (err) { + console.log('Users failed to be found at activate-account.'); + return next(err); + } + + if (repeatedUsers && repeatedUsers.length > 0) { + for (const user of repeatedUsers) { + if (user.email === userData.email) { + return res.status(400).json({ email: 'Is already taken' }); + } + + let repeatedUser; + do { + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}`; + + try { + repeatedUser = await User.findOne({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${ + userData.username + } failed to be found at activate-account.` + ); + return next(err); + } + } while (repeatedUser && repeatedUser.username === userData.username); + } + } + + let user; + try { + user = await User.create(userData); + } catch (err) { + console.log( + `User failed to be created at activate-account.\nData: ${JSON.stringify( + userData + )}` + ); + return next(err); + } + + const today = moment.utc(); + expiresAt = today.add(14, 'days').toDate(); + const refreshTokenData = { + expiresAt, + key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, + userId: user.id + }; + + try { + await RefreshToken.create(refreshTokenData); + } catch (err) { + console.log( + `Refresh token failed to be created at activate-account.\nData: ${JSON.stringify( + refreshTokenData + )}` + ); + return next(err); + } + + try { + await activationTicket.remove(); + } catch (err) { + console.log( + `Activation ticket with key ${ + activationTicket.key + } failed to be deleted at activate-account.` + ); + return next(err); + } + + return res.redirect(`${process.env.APP_URL}/sign-in`); +}; diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index bc68c5e..d5477ac 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -1,200 +1,201 @@ -const crypto = require('crypto'); - -const axios = require('axios'); -const jwt = require('jsonwebtoken'); -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -const { validateFacebookSignIn } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateFacebookSignIn(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const code = req.body.code; - - const getTokenUrl = 'https://graph.facebook.com/v2.10/oauth/access_token'; - const getTokenParams = { - code, - client_id: process.env.FACEBOOK_CLIENT_ID, - client_secret: process.env.FACEBOOK_CLIENT_SECRET, - redirect_uri: `${process.env.APP_URL}/auth/facebook` - }; - let getTokenResponse; - try { - getTokenResponse = await axios.get(getTokenUrl, { params: getTokenParams }); - } catch (err) { - return res.status(400).json({ general: 'Invalid code' }); - } - - const facebookToken = getTokenResponse.data.access_token; - - const getProfileUrl = - 'https://graph.facebook.com/v2.10/me?fields=id,email,first_name,last_name,locale'; - const getProfileOptions = { - params: { - access_token: facebookToken - } - }; - let getProfileResponse; - try { - getProfileResponse = await axios.get(getProfileUrl, getProfileOptions); - } catch (err) { - console.log('Profile data failed to be found at facebook-sign-in.'); - return next(err); - } - - const email = getProfileResponse.data.email - ? getProfileResponse.data.email - : ''; - const facebookId = getProfileResponse.data.id; - let user; - try { - user = await User.findOne({ - $or: [{ email }, { facebookId }], - isArchived: false - }); - } catch (err) { - console.log( - `User with facebookId ${facebookId} and email ${email} failed to be found at facebook-sign-in.` - ); - return next(err); - } - - let accessToken; - let refreshToken; - - if (!user) { - console.log(getProfileResponse.data); - const userData = { - email: getProfileResponse.data.email ? getProfileResponse.data.email : '', - facebookId: getProfileResponse.data.id, - firstName: getProfileResponse.data.first_name, - lastName: getProfileResponse.data.last_name - }; - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}`; - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log('Users failed to be found at facebook-sign-in.'); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}`; - - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at facebook-sign-in.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } - - const getPictureUrl = `https://graph.facebook.com/v2.10/${ - userData.facebookId - }/picture`; - const getPictureOptions = { - params: { - access_token: accessToken, - redirect: false, - type: 'large' - } - }; - let getPictureResponse; - try { - getPictureResponse = await axios.get(getPictureUrl, getPictureOptions); - } catch (err) { - console.log('User picture failed to be found at facebook-sign-in.'); - return next(err); - } - - const isSilhouette = getPictureResponse.data.data.is_silhouette; - if (!isSilhouette) { - userData.avatar = getPictureResponse.data.data.url; - } - - try { - user = await User.create(userData); - } catch (err) { - console.log( - `User failed to be created at facebook-sign-in.\nData: ${JSON.stringify( - userData - )}` - ); - return next(err); - } - - const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const refreshTokenData = { - expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id - }; - - try { - refreshToken = await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token failed to be created at facebook-sign-in.\nData: ${JSON.stringify( - refreshTokenData - )}` - ); - return next(err); - } - } else { - const userId = user.id; - const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; - - try { - refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - } catch (err) { - console.log( - `Refresh Token for userId ${userId} failed to be created or updated at facebook-sign-in.` - ); - return next(err); - } - } - - const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600 - }); - refreshToken = refreshToken.key; - - return res.status(200).json({ token, refreshToken }); -}; +const crypto = require('crypto'); + +const axios = require('axios'); +const jwt = require('jsonwebtoken'); +const moment = require('moment'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +const { validateFacebookSignIn } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateFacebookSignIn(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const code = req.body.code; + + const getTokenUrl = 'https://graph.facebook.com/v2.10/oauth/access_token'; + const getTokenParams = { + code, + client_id: process.env.FACEBOOK_CLIENT_ID, + client_secret: process.env.FACEBOOK_CLIENT_SECRET, + redirect_uri: `${process.env.APP_URL}/auth/facebook` + }; + let getTokenResponse; + try { + getTokenResponse = await axios.get(getTokenUrl, { params: getTokenParams }); + } catch (err) { + console.err(err); + return res.status(400).json({ general: 'Invalid code' }); + } + + const facebookToken = getTokenResponse.data.access_token; + + const getProfileUrl = + 'https://graph.facebook.com/v2.10/me?fields=id,email,first_name,last_name,locale'; + const getProfileOptions = { + params: { + access_token: facebookToken + } + }; + let getProfileResponse; + try { + getProfileResponse = await axios.get(getProfileUrl, getProfileOptions); + } catch (err) { + console.log('Profile data failed to be found at facebook-sign-in.'); + return next(err); + } + + const email = getProfileResponse.data.email + ? getProfileResponse.data.email + : ''; + const facebookId = getProfileResponse.data.id; + let user; + try { + user = await User.findOne({ + $or: [{ email }, { facebookId }], + isArchived: false + }); + } catch (err) { + console.log( + `User with facebookId ${facebookId} and email ${email} failed to be found at facebook-sign-in.` + ); + return next(err); + } + + let accessToken; + let refreshToken; + + if (!user) { + console.log(getProfileResponse.data); + const userData = { + email: getProfileResponse.data.email ? getProfileResponse.data.email : '', + facebookId: getProfileResponse.data.id, + firstName: getProfileResponse.data.first_name, + lastName: getProfileResponse.data.last_name + }; + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}`; + + let repeatedUsers; + try { + repeatedUsers = await User.find({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log('Users failed to be found at facebook-sign-in.'); + return next(err); + } + + if (repeatedUsers && repeatedUsers.length > 0) { + let repeatedUser; + do { + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}`; + + try { + repeatedUser = await User.findOne({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${ + userData.username + } failed to be found at facebook-sign-in.` + ); + return next(err); + } + } while (repeatedUser && repeatedUser.username === userData.username); + } + + const getPictureUrl = `https://graph.facebook.com/v2.10/${ + userData.facebookId + }/picture`; + const getPictureOptions = { + params: { + access_token: accessToken, + redirect: false, + type: 'large' + } + }; + let getPictureResponse; + try { + getPictureResponse = await axios.get(getPictureUrl, getPictureOptions); + } catch (err) { + console.log('User picture failed to be found at facebook-sign-in.'); + return next(err); + } + + const isSilhouette = getPictureResponse.data.data.is_silhouette; + if (!isSilhouette) { + userData.avatar = getPictureResponse.data.data.url; + } + + try { + user = await User.create(userData); + } catch (err) { + console.log( + `User failed to be created at facebook-sign-in.\nData: ${JSON.stringify( + userData + )}` + ); + return next(err); + } + + const today = moment.utc(); + const expiresAt = today.add(14, 'days').toDate(); + const refreshTokenData = { + expiresAt, + key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, + userId: user.id + }; + + try { + refreshToken = await RefreshToken.create(refreshTokenData); + } catch (err) { + console.log( + `Refresh token failed to be created at facebook-sign-in.\nData: ${JSON.stringify( + refreshTokenData + )}` + ); + return next(err); + } + } else { + const userId = user.id; + const today = moment.utc(); + const expiresAt = today.add(14, 'days').toDate(); + const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; + + try { + refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + } catch (err) { + console.log( + `Refresh Token for userId ${userId} failed to be created or updated at facebook-sign-in.` + ); + return next(err); + } + } + + const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { + expiresIn: 3600 + }); + refreshToken = refreshToken.key; + + return res.status(200).json({ token, refreshToken }); +}; diff --git a/src/routes/auth/forgotten-password.js b/src/routes/auth/forgotten-password.js index ed3039f..e1e18f7 100644 --- a/src/routes/auth/forgotten-password.js +++ b/src/routes/auth/forgotten-password.js @@ -1,88 +1,88 @@ -const crypto = require('crypto'); - -const moment = require('moment'); - -const { PasswordTicket } = require('../../models/password-ticket'); -const { sendEmail } = require('../../helpers'); -const { User } = require('../../models/user'); - -const { validateForgottenPassword } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateForgottenPassword(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const email = req.body.email; - - let user; - try { - user = await User.findOne({ email, isArchived: false }); - } catch (err) { - console.log( - `User with email ${email} failed to be found at forgotten-password.` - ); - return next(err); - } - - if (!user) { - return res.status(200).json({ general: 'Success' }); - } - - try { - await PasswordTicket.remove({ email }); - } catch (err) { - console.log( - `Password ticket with email ${email} failed to be removed at forgotten-password.` - ); - return next(err); - } - - const today = moment.utc(); - const expiresAt = today.add(1, 'days').toDate(); - const key = `${crypto - .randomBytes(31) - .toString('hex')}${new Date().getTime().toString()}`; - - let passwordTicket; - try { - passwordTicket = await PasswordTicket.create({ email, expiresAt, key }); - } catch (err) { - console.log( - `Password ticket failed to be created at forgotten-password.\nData: ${JSON.stringify( - { email, expiresAt, key } - )}` - ); - return next(err); - } - - const htmlContent = ` -

Hi from AXS Map!

-

To reset your password use the link below:

-
- - ${process.env.APP_URL}/reset-password?key=${passwordTicket.key} - -

-

Stay awesome.

- `; - const receiversEmails = [passwordTicket.email]; - const subject = 'Reset Password'; - const textContent = ` - Hi from AXS Map! - To reset your password use the link below: - ${process.env.APP_URL}/reset-password?key=${passwordTicket.key} - Stay awesome. - `; - - sendEmail({ - receiversEmails, - subject, - htmlContent, - textContent - }); - - return res.status(200).json({ general: 'Success' }); -}; +const crypto = require('crypto'); + +const moment = require('moment'); + +const { PasswordTicket } = require('../../models/password-ticket'); +const { sendEmail } = require('../../helpers'); +const { User } = require('../../models/user'); + +const { validateForgottenPassword } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateForgottenPassword(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const email = req.body.email; + + let user; + try { + user = await User.findOne({ email, isArchived: false }); + } catch (err) { + console.log( + `User with email ${email} failed to be found at forgotten-password.` + ); + return next(err); + } + + if (!user) { + return res.status(200).json({ general: 'Success' }); + } + + try { + await PasswordTicket.remove({ email }); + } catch (err) { + console.log( + `Password ticket with email ${email} failed to be removed at forgotten-password.` + ); + return next(err); + } + + const today = moment.utc(); + const expiresAt = today.add(1, 'days').toDate(); + const key = `${crypto + .randomBytes(31) + .toString('hex')}${new Date().getTime().toString()}`; + + let passwordTicket; + try { + passwordTicket = await PasswordTicket.create({ email, expiresAt, key }); + } catch (err) { + console.log( + `Password ticket failed to be created at forgotten-password.\nData: ${JSON.stringify( + { email, expiresAt, key } + )}` + ); + return next(err); + } + + const htmlContent = ` +

Hi from AXS Map!

+

To reset your password use the link below:

+
+ + ${process.env.APP_URL}/reset-password?key=${passwordTicket.key} + +

+

Stay awesome.

+ `; + const receiversEmails = [passwordTicket.email]; + const subject = 'Reset Password'; + const textContent = ` + Hi from AXS Map! + To reset your password use the link below: + ${process.env.APP_URL}/reset-password?key=${passwordTicket.key} + Stay awesome. + `; + + sendEmail({ + receiversEmails, + subject, + htmlContent, + textContent + }); + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/auth/generate-token.js b/src/routes/auth/generate-token.js index ba1016f..689e2d2 100644 --- a/src/routes/auth/generate-token.js +++ b/src/routes/auth/generate-token.js @@ -1,55 +1,55 @@ -const jwt = require('jsonwebtoken'); -const moment = require('moment'); - -const { RefreshToken } = require('../../models/refresh-token'); - -const { validateGenerateToken } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateGenerateToken(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const key = req.body.key; - - let refreshToken; - try { - refreshToken = await RefreshToken.findOne({ key }); - } catch (err) { - console.log( - `Refresh Token with key ${key} failed to be found at generate-token.` - ); - return next(err); - } - - if (!refreshToken) { - return res.status(404).json({ general: 'Refresh Token not found' }); - } - - const expiresAt = moment(refreshToken.expiresAt).utc(); - const today = moment.utc(); - if (expiresAt.isBefore(today)) { - try { - await refreshToken.remove(); - } catch (err) { - console.log( - `Refresh Token with key ${ - refreshToken.key - } failed to be removed at generate-token.` - ); - return next(err); - } - - return res.status(401).json({ general: 'Refresh Token expired' }); - } - - const token = jwt.sign( - { userId: refreshToken.userId }, - process.env.JWT_SECRET, - { - expiresIn: 3600 - } - ); - return res.status(200).json({ token }); -}; +const jwt = require('jsonwebtoken'); +const moment = require('moment'); + +const { RefreshToken } = require('../../models/refresh-token'); + +const { validateGenerateToken } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateGenerateToken(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const key = req.body.key; + + let refreshToken; + try { + refreshToken = await RefreshToken.findOne({ key }); + } catch (err) { + console.log( + `Refresh Token with key ${key} failed to be found at generate-token.` + ); + return next(err); + } + + if (!refreshToken) { + return res.status(404).json({ general: 'Refresh Token not found' }); + } + + const expiresAt = moment(refreshToken.expiresAt).utc(); + const today = moment.utc(); + if (expiresAt.isBefore(today)) { + try { + await refreshToken.remove(); + } catch (err) { + console.log( + `Refresh Token with key ${ + refreshToken.key + } failed to be removed at generate-token.` + ); + return next(err); + } + + return res.status(401).json({ general: 'Refresh Token expired' }); + } + + const token = jwt.sign( + { userId: refreshToken.userId }, + process.env.JWT_SECRET, + { + expiresIn: 3600 + } + ); + return res.status(200).json({ token }); +}; diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 6031188..14c2a84 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -1,188 +1,189 @@ -const crypto = require('crypto'); -const querystring = require('querystring'); - -const axios = require('axios'); -const GoogleAuth = require('google-auth-library'); -const jwt = require('jsonwebtoken'); -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -const { validateGoogleSignIn } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateGoogleSignIn(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const code = req.body.code; - - const getTokenUrl = 'https://www.googleapis.com/oauth2/v4/token'; - const getTokenParams = { - code, - client_id: process.env.GOOGLE_CLIENT_ID, - client_secret: process.env.GOOGLE_CLIENT_SECRET, - redirect_uri: `${process.env.APP_URL}/auth/google`, - grant_type: 'authorization_code' - }; - let getTokenResponse; - try { - getTokenResponse = await axios.post( - getTokenUrl, - querystring.stringify(getTokenParams) - ); - } catch (err) { - return res.status(400).json({ general: 'Invalid code' }); - } - - const auth = new GoogleAuth(); - const client = new auth.OAuth2(process.env.GOOGLE_CLIENT_ID, '', ''); - const idToken = getTokenResponse.data.id_token; - client.verifyIdToken( - idToken, - process.env.GOOGLE_CLIENT_ID, - async (err, login) => { - if (err) { - return res.status(400).json({ general: 'Invalid token id' }); - } - - const payload = login.getPayload(); - - const email = payload.email; - const googleId = payload.sub; - let user; - try { - user = await User.findOne({ - $or: [{ email }, { googleId }], - isArchived: false - }); - } catch (err) { - console.log( - `User with googleId ${googleId} and email ${email} failed to be found at google-sign-in.` - ); - return next(err); - } - - let refreshToken; - - if (!user) { - const userData = { - email: payload.email, - googleId: payload.sub, - firstName: payload.given_name, - lastName: payload.family_name - }; - - if (payload.locale === 'en') { - userData.language = 'en'; - } else if (payload.locale === 'es') { - userData.language = 'es'; - } - - if (payload.picture) { - userData.avatar = payload.picture; - } - - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}`; - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log('Users failed to be found at google-sign-in.'); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}`; - - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at google-sign-in.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } - - try { - user = await User.create(userData); - } catch (err) { - console.log( - `User failed to be created at google-sign-in.\nData: ${JSON.stringify( - userData - )}` - ); - return next(err); - } - - const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const refreshTokenData = { - expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id - }; - - try { - refreshToken = await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token failed to be created at google-sign-in.\nData: ${JSON.stringify( - refreshTokenData - )}` - ); - return next(err); - } - } else { - const userId = user.id; - const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; - - try { - refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - } catch (err) { - console.log( - `Refresh Token for userId ${userId} failed to be created or updated at google-sign-in.` - ); - return next(err); - } - } - - const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600 - }); - refreshToken = refreshToken.key; - - return res.status(200).json({ token, refreshToken }); - } - ); -}; +const crypto = require('crypto'); +const querystring = require('querystring'); + +const axios = require('axios'); +const GoogleAuth = require('google-auth-library'); +const jwt = require('jsonwebtoken'); +const moment = require('moment'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +const { validateGoogleSignIn } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateGoogleSignIn(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const code = req.body.code; + + const getTokenUrl = 'https://www.googleapis.com/oauth2/v4/token'; + const getTokenParams = { + code, + client_id: process.env.GOOGLE_CLIENT_ID, + client_secret: process.env.GOOGLE_CLIENT_SECRET, + redirect_uri: `${process.env.APP_URL}/auth/google`, + grant_type: 'authorization_code' + }; + let getTokenResponse; + try { + getTokenResponse = await axios.post( + getTokenUrl, + querystring.stringify(getTokenParams) + ); + } catch (err) { + console.error(err); + return res.status(400).json({ general: 'Invalid code' }); + } + + const auth = new GoogleAuth(); + const client = new auth.OAuth2(process.env.GOOGLE_CLIENT_ID, '', ''); + const idToken = getTokenResponse.data.id_token; + client.verifyIdToken( + idToken, + process.env.GOOGLE_CLIENT_ID, + async (err, login) => { + if (err) { + return res.status(400).json({ general: 'Invalid token id' }); + } + + const payload = login.getPayload(); + + const email = payload.email; + const googleId = payload.sub; + let user; + try { + user = await User.findOne({ + $or: [{ email }, { googleId }], + isArchived: false + }); + } catch (err) { + console.log( + `User with googleId ${googleId} and email ${email} failed to be found at google-sign-in.` + ); + return next(err); + } + + let refreshToken; + + if (!user) { + const userData = { + email: payload.email, + googleId: payload.sub, + firstName: payload.given_name, + lastName: payload.family_name + }; + + if (payload.locale === 'en') { + userData.language = 'en'; + } else if (payload.locale === 'es') { + userData.language = 'es'; + } + + if (payload.picture) { + userData.avatar = payload.picture; + } + + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}`; + + let repeatedUsers; + try { + repeatedUsers = await User.find({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log('Users failed to be found at google-sign-in.'); + return next(err); + } + + if (repeatedUsers && repeatedUsers.length > 0) { + let repeatedUser; + do { + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}`; + + try { + repeatedUser = await User.findOne({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${ + userData.username + } failed to be found at google-sign-in.` + ); + return next(err); + } + } while (repeatedUser && repeatedUser.username === userData.username); + } + + try { + user = await User.create(userData); + } catch (err) { + console.log( + `User failed to be created at google-sign-in.\nData: ${JSON.stringify( + userData + )}` + ); + return next(err); + } + + const today = moment.utc(); + const expiresAt = today.add(14, 'days').toDate(); + const refreshTokenData = { + expiresAt, + key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, + userId: user.id + }; + + try { + refreshToken = await RefreshToken.create(refreshTokenData); + } catch (err) { + console.log( + `Refresh token failed to be created at google-sign-in.\nData: ${JSON.stringify( + refreshTokenData + )}` + ); + return next(err); + } + } else { + const userId = user.id; + const today = moment.utc(); + const expiresAt = today.add(14, 'days').toDate(); + const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; + + try { + refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + } catch (err) { + console.log( + `Refresh Token for userId ${userId} failed to be created or updated at google-sign-in.` + ); + return next(err); + } + } + + const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { + expiresIn: 3600 + }); + refreshToken = refreshToken.key; + + return res.status(200).json({ token, refreshToken }); + } + ); +}; diff --git a/src/routes/auth/index.js b/src/routes/auth/index.js index d1cb782..431d0c8 100644 --- a/src/routes/auth/index.js +++ b/src/routes/auth/index.js @@ -1,27 +1,27 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const activateAccount = require('./activate-account'); -const facebookSignIn = require('./facebook-sign-in'); -const forgottenPassword = require('./forgotten-password'); -const generateToken = require('./generate-token'); -const googleSignIn = require('./google-sign-in'); -const resetPassword = require('./reset-password'); -const signIn = require('./sign-in'); -const signOut = require('./sign-out'); -const signUp = require('./sign-up'); - -const router = new express.Router(); - -router.get('/activate-account/:key', activateAccount); -router.post('/facebook', facebookSignIn); -router.post('/forgotten-password', forgottenPassword); -router.post('/google', googleSignIn); -router.put('/reset-password', resetPassword); -router.post('/sign-in', signIn); -router.delete('/sign-out', isAuthenticated({ isOptional: false }), signOut); -router.post('/sign-up', signUp); -router.post('/token', generateToken); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const activateAccount = require('./activate-account'); +const facebookSignIn = require('./facebook-sign-in'); +const forgottenPassword = require('./forgotten-password'); +const generateToken = require('./generate-token'); +const googleSignIn = require('./google-sign-in'); +const resetPassword = require('./reset-password'); +const signIn = require('./sign-in'); +const signOut = require('./sign-out'); +const signUp = require('./sign-up'); + +const router = new express.Router(); + +router.get('/activate-account/:key', activateAccount); +router.post('/facebook', facebookSignIn); +router.post('/forgotten-password', forgottenPassword); +router.post('/google', googleSignIn); +router.put('/reset-password', resetPassword); +router.post('/sign-in', signIn); +router.delete('/sign-out', isAuthenticated({ isOptional: false }), signOut); +router.post('/sign-up', signUp); +router.post('/token', generateToken); + +module.exports = router; diff --git a/src/routes/auth/reset-password.js b/src/routes/auth/reset-password.js index 5e69206..51f6a90 100644 --- a/src/routes/auth/reset-password.js +++ b/src/routes/auth/reset-password.js @@ -1,133 +1,133 @@ -const moment = require('moment'); - -const { PasswordTicket } = require('../../models/password-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -const { validateResetPassword } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateResetPassword(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const key = req.body.key; - const password = req.body.password; - - let passwordTicket; - try { - passwordTicket = await PasswordTicket.findOne({ key }); - } catch (err) { - console.log( - `Password ticket with key ${key} failed to be found at reset-password.` - ); - return next(err); - } - - if (!passwordTicket) { - return res.status(404).json({ general: 'Password Ticket not found' }); - } - - const expiresAt = moment(passwordTicket.expiresAt).utc(); - const today = moment.utc(); - if (expiresAt.isBefore(today)) { - try { - await passwordTicket.remove(); - } catch (err) { - console.log( - `Password Ticket with key ${ - passwordTicket.key - } failed to be removed at reset-password.` - ); - return next(err); - } - - return res.status(400).json({ general: 'Password Ticket expired' }); - } - - let user; - try { - user = await User.findOne({ - email: passwordTicket.email, - isArchived: false - }); - } catch (err) { - console.log( - `User with email ${ - passwordTicket.email - } failed to be found at reset-password.` - ); - return next(err); - } - - if (!user) { - try { - await passwordTicket.remove(); - } catch (err) { - console.log( - `Password Ticket with key ${ - passwordTicket.key - } failed to be removed at reset-password.` - ); - return next(err); - } - - return res.status(400).json({ general: 'User not found' }); - } - - const passwordMatches = user.comparePassword(password); - if (passwordMatches) { - return res.status(400).json({ password: 'Is already used' }); - } - - user.password = password; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log( - `User with email ${user.email} failed to be updated at reset-password.` - ); - return next(err); - } - - let refreshToken; - try { - refreshToken = await RefreshToken.findOne({ userId: user.id }); - } catch (err) { - console.log( - `Refresh token with userId ${ - user.id - } failed to be found at reset-password.` - ); - return next(err); - } - - if (refreshToken) { - try { - await refreshToken.remove(); - } catch (err) { - console.log( - `Refresh Token with userId ${ - refreshToken.userId - } failed to be removed at reset-password.` - ); - return next(err); - } - } - - try { - await passwordTicket.remove(); - } catch (err) { - console.log( - `Password Ticket with key ${ - passwordTicket.key - } failed to be removed at reset-password.` - ); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { PasswordTicket } = require('../../models/password-ticket'); +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +const { validateResetPassword } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateResetPassword(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const key = req.body.key; + const password = req.body.password; + + let passwordTicket; + try { + passwordTicket = await PasswordTicket.findOne({ key }); + } catch (err) { + console.log( + `Password ticket with key ${key} failed to be found at reset-password.` + ); + return next(err); + } + + if (!passwordTicket) { + return res.status(404).json({ general: 'Password Ticket not found' }); + } + + const expiresAt = moment(passwordTicket.expiresAt).utc(); + const today = moment.utc(); + if (expiresAt.isBefore(today)) { + try { + await passwordTicket.remove(); + } catch (err) { + console.log( + `Password Ticket with key ${ + passwordTicket.key + } failed to be removed at reset-password.` + ); + return next(err); + } + + return res.status(400).json({ general: 'Password Ticket expired' }); + } + + let user; + try { + user = await User.findOne({ + email: passwordTicket.email, + isArchived: false + }); + } catch (err) { + console.log( + `User with email ${ + passwordTicket.email + } failed to be found at reset-password.` + ); + return next(err); + } + + if (!user) { + try { + await passwordTicket.remove(); + } catch (err) { + console.log( + `Password Ticket with key ${ + passwordTicket.key + } failed to be removed at reset-password.` + ); + return next(err); + } + + return res.status(400).json({ general: 'User not found' }); + } + + const passwordMatches = user.comparePassword(password); + if (passwordMatches) { + return res.status(400).json({ password: 'Is already used' }); + } + + user.password = password; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log( + `User with email ${user.email} failed to be updated at reset-password.` + ); + return next(err); + } + + let refreshToken; + try { + refreshToken = await RefreshToken.findOne({ userId: user.id }); + } catch (err) { + console.log( + `Refresh token with userId ${ + user.id + } failed to be found at reset-password.` + ); + return next(err); + } + + if (refreshToken) { + try { + await refreshToken.remove(); + } catch (err) { + console.log( + `Refresh Token with userId ${ + refreshToken.userId + } failed to be removed at reset-password.` + ); + return next(err); + } + } + + try { + await passwordTicket.remove(); + } catch (err) { + console.log( + `Password Ticket with key ${ + passwordTicket.key + } failed to be removed at reset-password.` + ); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/auth/sign-in.js b/src/routes/auth/sign-in.js index f0ac99d..3582e2f 100644 --- a/src/routes/auth/sign-in.js +++ b/src/routes/auth/sign-in.js @@ -1,69 +1,70 @@ -const crypto = require('crypto'); - -const jwt = require('jsonwebtoken'); -const moment = require('moment'); - -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -const { validateSignIn } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateSignIn(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const email = req.body.email; - const password = req.body.password; - - let user; - try { - user = await User.findOne({ email, isArchived: false }); - } catch (err) { - console.log(`User with email ${email} failed to be found at sign-in.`); - return next(err); - } - - if (!user) { - return res.status(400).json({ general: 'Email or password incorrect' }); - } - - if (user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - if (!user.hashedPassword) { - return res.status(400).json({ general: 'Email or password incorrect' }); - } - - const passwordMatches = user.comparePassword(password); - - if (!passwordMatches) { - return res.status(400).json({ general: 'Email or password incorrect' }); - } - - const userId = user.id; - const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; - - let refreshToken; - try { - refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - } catch (err) { - console.log( - `Refresh Token for userId ${userId} failed to be created or updated at sign-in.` - ); - return next(err); - } - - const token = jwt.sign({ userId }, process.env.JWT_SECRET, { - expiresIn: 36000 - }); - return res.status(200).json({ refreshToken: refreshToken.key, token }); -}; +const crypto = require("crypto"); + +const jwt = require("jsonwebtoken"); +const moment = require("moment"); + +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); + +const { validateSignIn } = require("./validations"); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateSignIn(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const email = req.body.email; + const password = req.body.password; + + let user; + try { + user = await User.findOne({ email, isArchived: false }); + console.log("User", user); + } catch (err) { + console.log(`User with email ${email} failed to be found at sign-in.`); + return next(err); + } + + if (!user) { + return res.status(400).json({ general: "Email or password incorrect" }); + } + + if (user.isBlocked) { + return res.status(423).json({ general: "You are blocked" }); + } + + if (!user.hashedPassword) { + return res.status(400).json({ general: "Email or password incorrect" }); + } + + const passwordMatches = user.comparePassword(password); + + if (!passwordMatches) { + return res.status(400).json({ general: "Email or password incorrect" }); + } + + const userId = user.id; + const today = moment.utc(); + const expiresAt = today.add(14, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; + + let refreshToken; + try { + refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + } catch (err) { + console.log( + `Refresh Token for userId ${userId} failed to be created or updated at sign-in.` + ); + return next(err); + } + + const token = jwt.sign({ userId }, process.env.JWT_SECRET, { + expiresIn: 36000, + }); + return res.status(200).json({ refreshToken: refreshToken.key, token }); +}; diff --git a/src/routes/auth/sign-out.js b/src/routes/auth/sign-out.js index 075ef8d..6810f6b 100644 --- a/src/routes/auth/sign-out.js +++ b/src/routes/auth/sign-out.js @@ -1,34 +1,34 @@ -const { RefreshToken } = require('../../models/refresh-token'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - let refreshToken; - try { - refreshToken = await RefreshToken.findOne({ userId: req.user.id }); - } catch (err) { - console.log( - `Refresh token with userId ${req.user.id} failed to be found at sign-out.` - ); - return next(err); - } - - if (!refreshToken) { - return res.status(204).json({ general: 'Success' }); - } - - try { - await refreshToken.remove(); - } catch (err) { - console.log( - `Refresh token with userId ${ - req.user.id - } failed to be deleted at sign-out.` - ); - return next(err); - } - - return res.status(204).json({ general: 'Success' }); -}; +const { RefreshToken } = require('../../models/refresh-token'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + let refreshToken; + try { + refreshToken = await RefreshToken.findOne({ userId: req.user.id }); + } catch (err) { + console.log( + `Refresh token with userId ${req.user.id} failed to be found at sign-out.` + ); + return next(err); + } + + if (!refreshToken) { + return res.status(204).json({ general: 'Success' }); + } + + try { + await refreshToken.remove(); + } catch (err) { + console.log( + `Refresh token with userId ${ + req.user.id + } failed to be deleted at sign-out.` + ); + return next(err); + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 8819b94..6bdf8a7 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -1,158 +1,158 @@ -const crypto = require('crypto'); - -const moment = require('moment'); -const { pick } = require('lodash'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -const { ActivationTicket } = require('../../models/activation-ticket'); -const { cleanSpaces, sendEmail } = require('../../helpers'); -const { User } = require('../../models/user'); - -const { validateSignUp } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateSignUp(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const data = pick(req.body, [ - 'email', - 'firstName', - 'isSubscribed', - 'lastName', - 'password' - ]); - data.firstName = cleanSpaces(data.firstName); - data.lastName = cleanSpaces(data.lastName); - data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; - - let activationTicket; - try { - activationTicket = await ActivationTicket.findOne({ email: data.email }); - } catch (err) { - console.log( - `Activation ticket with email ${ - data.email - } failed to be found at sign-up.` - ); - return next(err); - } - - if (activationTicket) { - const expiresAt = moment(activationTicket.expiresAt).utc(); - const today = moment.utc(); - if (expiresAt.isBefore(today)) { - try { - await activationTicket.remove(); - } catch (err) { - console.log( - `Activation ticket with email ${ - activationTicket.email - } failed to be removed at sign-up.` - ); - return next(err); - } - } - } - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - $or: [{ email: data.email }, { username: data.username }], - isArchived: false - }); - } catch (err) { - console.log('Users failed to be found at sign-up.'); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - for (const user of repeatedUsers) { - if (user.email === data.email) { - return res.status(400).json({ email: 'Is already taken' }); - } - - let repeatedUser; - do { - data.username = `${slugify(data.firstName)}-${slugify( - data.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}`; - - try { - repeatedUser = await User.findOne({ - username: data.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${data.username} failed to be found at sign-up.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === data.username); - } - } - - const today = moment.utc(); - const expiresAt = today.add(1, 'days').toDate(); - const key = `${crypto - .randomBytes(31) - .toString('hex')}${new Date().getTime().toString()}`; - - const activationTicketData = { - email: data.email, - expiresAt, - key, - userData: { - firstName: data.firstName, - isSubscribed: data.isSubscribed, - lastName: data.lastName, - password: data.password, - username: data.username - } - }; - try { - activationTicket = await ActivationTicket.create(activationTicketData); - } catch (err) { - console.log( - `Activation ticket failed to be created at sign-up.\nData: ${JSON.stringify( - activationTicketData - )}` - ); - return next(err); - } - - const subject = 'Activate Account'; - const htmlContent = ` -

Welcome to AXS Map!

-

To activate your account use the link below:

-
- - ${process.env.API_URL}/auth/activate-account/${activationTicket.key} - -

-

Stay awesome.

- `; - const textContent = ` - Welcome to AXS Map! - To activate your account use the link below: - ${process.env.API_URL}/auth/activate-account/${activationTicket.key} - Stay awesome. - `; - const receiversEmails = [activationTicket.email]; - - sendEmail({ - subject, - htmlContent, - textContent, - receiversEmails - }); - - return res.status(201).json({ general: 'Success' }); -}; +const crypto = require('crypto'); + +const moment = require('moment'); +const { pick } = require('lodash'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +const { ActivationTicket } = require('../../models/activation-ticket'); +const { cleanSpaces, sendEmail } = require('../../helpers'); +const { User } = require('../../models/user'); + +const { validateSignUp } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateSignUp(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const data = pick(req.body, [ + 'email', + 'firstName', + 'isSubscribed', + 'lastName', + 'password' + ]); + data.firstName = cleanSpaces(data.firstName); + data.lastName = cleanSpaces(data.lastName); + data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; + + let activationTicket; + try { + activationTicket = await ActivationTicket.findOne({ email: data.email }); + } catch (err) { + console.log( + `Activation ticket with email ${ + data.email + } failed to be found at sign-up.` + ); + return next(err); + } + + if (activationTicket) { + const expiresAt = moment(activationTicket.expiresAt).utc(); + const today = moment.utc(); + if (expiresAt.isBefore(today)) { + try { + await activationTicket.remove(); + } catch (err) { + console.log( + `Activation ticket with email ${ + activationTicket.email + } failed to be removed at sign-up.` + ); + return next(err); + } + } + } + + let repeatedUsers; + try { + repeatedUsers = await User.find({ + $or: [{ email: data.email }, { username: data.username }], + isArchived: false + }); + } catch (err) { + console.log('Users failed to be found at sign-up.'); + return next(err); + } + + if (repeatedUsers && repeatedUsers.length > 0) { + for (const user of repeatedUsers) { + if (user.email === data.email) { + return res.status(400).json({ email: 'Is already taken' }); + } + + let repeatedUser; + do { + data.username = `${slugify(data.firstName)}-${slugify( + data.lastName + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}`; + + try { + repeatedUser = await User.findOne({ + username: data.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${data.username} failed to be found at sign-up.` + ); + return next(err); + } + } while (repeatedUser && repeatedUser.username === data.username); + } + } + + const today = moment.utc(); + const expiresAt = today.add(1, 'days').toDate(); + const key = `${crypto + .randomBytes(31) + .toString('hex')}${new Date().getTime().toString()}`; + + const activationTicketData = { + email: data.email, + expiresAt, + key, + userData: { + firstName: data.firstName, + isSubscribed: data.isSubscribed, + lastName: data.lastName, + password: data.password, + username: data.username + } + }; + try { + activationTicket = await ActivationTicket.create(activationTicketData); + } catch (err) { + console.log( + `Activation ticket failed to be created at sign-up.\nData: ${JSON.stringify( + activationTicketData + )}` + ); + return next(err); + } + + const subject = 'Activate Account'; + const htmlContent = ` +

Welcome to AXS Map!

+

To activate your account use the link below:

+
+ + ${process.env.API_URL}/auth/activate-account/${activationTicket.key} + +

+

Stay awesome.

+ `; + const textContent = ` + Welcome to AXS Map! + To activate your account use the link below: + ${process.env.API_URL}/auth/activate-account/${activationTicket.key} + Stay awesome. + `; + const receiversEmails = [activationTicket.email]; + + sendEmail({ + subject, + htmlContent, + textContent, + receiversEmails + }); + + return res.status(201).json({ general: 'Success' }); +}; diff --git a/src/routes/auth/validations.js b/src/routes/auth/validations.js index f8bb8f4..7c11055 100644 --- a/src/routes/auth/validations.js +++ b/src/routes/auth/validations.js @@ -1,155 +1,155 @@ -const freemail = require('freemail'); -const { isEmail } = require('validator'); -const { isEmpty } = require('lodash'); - -const { cleanSpaces } = require('../../helpers'); - -module.exports = { - validateFacebookSignIn(data) { - const errors = {}; - - if (!data.code) { - errors.code = 'Is required'; - } else if (typeof data.code !== 'string') { - errors.code = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateForgottenPassword(data) { - const errors = {}; - - if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; - } else if (!isEmail(data.email)) { - errors.email = 'Should be a valid email'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateGenerateToken(data) { - const errors = {}; - - if (!data.key) { - errors.key = 'Is required'; - } else if (typeof data.key !== 'string') { - errors.key = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateGoogleSignIn(data) { - const errors = {}; - - if (!data.code) { - errors.code = 'Is required'; - } else if (typeof data.code !== 'string') { - errors.code = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateResetPassword(data) { - const errors = {}; - - if (!data.key) { - errors.key = 'Is required'; - } else if (typeof data.key !== 'string') { - errors.key = 'Should be a string'; - } - - if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; - } else if (data.password.length < 8) { - errors.password = 'Should have more than 7 characters'; - } else if (data.password.length > 30) { - errors.password = 'Should have less than 31 characters'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateSignIn(data) { - const errors = {}; - - if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; - } - - if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateSignUp(data) { - const errors = {}; - - if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; - } else if (cleanSpaces(data.email).length > 254) { - errors.email = 'Should have less than 255 characters'; - } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { - errors.email = 'Should be a valid email'; - } - - if (!data.firstName) { - errors.firstName = 'Is required'; - } else if (typeof data.firstName !== 'string') { - errors.firstName = 'Should be a string'; - } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName)) { - errors.firstName = 'Should only have letters'; - } else if (cleanSpaces(data.firstName).length > 24) { - errors.firstName = 'Should have less than 25 characters'; - } else { - const firstName = cleanSpaces(data.firstName); - - if (firstName.split(' ').length > 1) { - errors.firstName = 'Should only be one name'; - } - } - - if (typeof data.isSubscribed === 'undefined') { - errors.isSubscribed = 'Is required'; - } else if (typeof data.isSubscribed !== 'boolean') { - errors.isSubscribed = 'Should be a boolean'; - } - - if (!data.lastName) { - errors.lastName = 'Is required'; - } else if (typeof data.lastName !== 'string') { - errors.lastName = 'Should be a string'; - } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { - errors.lastName = 'Should only have letters'; - } else if (cleanSpaces(data.lastName).length > 36) { - errors.lastName = 'Should have less than 37 characters'; - } else { - const lastName = cleanSpaces(data.lastName); - - if (lastName.split(' ').length > 1) { - errors.lastName = 'Should only be one surname'; - } - } - - if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; - } else if (data.password.length < 8) { - errors.password = 'Should have more than 7 characters'; - } else if (data.password.length > 30) { - errors.password = 'Should have less than 31 characters'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const freemail = require('freemail'); +const { isEmail } = require('validator'); +const { isEmpty } = require('lodash'); + +const { cleanSpaces } = require('../../helpers'); + +module.exports = { + validateFacebookSignIn(data) { + const errors = {}; + + if (!data.code) { + errors.code = 'Is required'; + } else if (typeof data.code !== 'string') { + errors.code = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateForgottenPassword(data) { + const errors = {}; + + if (!data.email) { + errors.email = 'Is required'; + } else if (typeof data.email !== 'string') { + errors.email = 'Should be a string'; + } else if (!isEmail(data.email)) { + errors.email = 'Should be a valid email'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateGenerateToken(data) { + const errors = {}; + + if (!data.key) { + errors.key = 'Is required'; + } else if (typeof data.key !== 'string') { + errors.key = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateGoogleSignIn(data) { + const errors = {}; + + if (!data.code) { + errors.code = 'Is required'; + } else if (typeof data.code !== 'string') { + errors.code = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateResetPassword(data) { + const errors = {}; + + if (!data.key) { + errors.key = 'Is required'; + } else if (typeof data.key !== 'string') { + errors.key = 'Should be a string'; + } + + if (!data.password) { + errors.password = 'Is required'; + } else if (typeof data.password !== 'string') { + errors.password = 'Should be a string'; + } else if (data.password.length < 8) { + errors.password = 'Should have more than 7 characters'; + } else if (data.password.length > 30) { + errors.password = 'Should have less than 31 characters'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateSignIn(data) { + const errors = {}; + + if (!data.email) { + errors.email = 'Is required'; + } else if (typeof data.email !== 'string') { + errors.email = 'Should be a string'; + } + + if (!data.password) { + errors.password = 'Is required'; + } else if (typeof data.password !== 'string') { + errors.password = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateSignUp(data) { + const errors = {}; + + if (!data.email) { + errors.email = 'Is required'; + } else if (typeof data.email !== 'string') { + errors.email = 'Should be a string'; + } else if (cleanSpaces(data.email).length > 254) { + errors.email = 'Should have less than 255 characters'; + } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { + errors.email = 'Should be a valid email'; + } + + if (!data.firstName) { + errors.firstName = 'Is required'; + } else if (typeof data.firstName !== 'string') { + errors.firstName = 'Should be a string'; + } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName)) { + errors.firstName = 'Should only have letters'; + } else if (cleanSpaces(data.firstName).length > 24) { + errors.firstName = 'Should have less than 25 characters'; + } else { + const firstName = cleanSpaces(data.firstName); + + if (firstName.split(' ').length > 1) { + errors.firstName = 'Should only be one name'; + } + } + + if (typeof data.isSubscribed === 'undefined') { + errors.isSubscribed = 'Is required'; + } else if (typeof data.isSubscribed !== 'boolean') { + errors.isSubscribed = 'Should be a boolean'; + } + + if (!data.lastName) { + errors.lastName = 'Is required'; + } else if (typeof data.lastName !== 'string') { + errors.lastName = 'Should be a string'; + } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { + errors.lastName = 'Should only have letters'; + } else if (cleanSpaces(data.lastName).length > 36) { + errors.lastName = 'Should have less than 37 characters'; + } else { + const lastName = cleanSpaces(data.lastName); + + if (lastName.split(' ').length > 1) { + errors.lastName = 'Should only be one surname'; + } + } + + if (!data.password) { + errors.password = 'Is required'; + } else if (typeof data.password !== 'string') { + errors.password = 'Should be a string'; + } else if (data.password.length < 8) { + errors.password = 'Should have more than 7 characters'; + } else if (data.password.length > 30) { + errors.password = 'Should have less than 31 characters'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/events/create-event.js b/src/routes/events/create-event.js index 7b35bda..7787d3f 100644 --- a/src/routes/events/create-event.js +++ b/src/routes/events/create-event.js @@ -1,190 +1,184 @@ -const axios = require('axios'); -const FormData = require('form-data'); -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { Team } = require('../../models/team'); - -const { validateCreateEvent } = require('./validations'); - -module.exports = async (req, res, next) => { - const data = { - address: req.body.address, - description: req.body.description, - donationAmounts: req.body.donationAmounts, - donationEnabled: req.body.donationEnabled, - donationGoal: req.body.donationGoal, - endDate: req.body.endDate, - isOpen: req.body.isOpen, - locationCoordinates: req.body.locationCoordinates, - name: req.body.name, - participantsGoal: req.body.participantsGoal, - poster: req.body.poster, - reviewsGoal: req.body.reviewsGoal, - startDate: req.body.startDate, - teamManager: req.body.teamManager - }; - - const { errors, isValid } = validateCreateEvent(data); - if (!isValid) return res.status(400).json(errors); - - data.address = cleanSpaces(data.address); - - data.endDate = moment(data.endDate) - .endOf('day') - .utc() - .toDate(); - - data.location = { - coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]] - }; - delete data.locationCoordinates; - - data.managers = [req.user.id]; - - data.name = cleanSpaces(data.name); - let repeatedEvent; - try { - repeatedEvent = await Event.findOne({ name: data.name, isArchived: false }); - } catch (err) { - console.log(`Event ${data.name} failed to be found at create-event`); - return next(err); - } - - if (repeatedEvent) { - return res.status(400).json({ name: 'Is already taken' }); - } - - if (data.poster) { - let poster; - try { - poster = await Photo.findOne({ url: data.poster }); - } catch (err) { - console.log(`Poster ${data.poster} failed to be found at create-event`); - return next(err); - } - - if (!poster) { - return res.status(404).json({ poster: 'Not found' }); - } - } - - data.startDate = moment(data.startDate) - .startOf('day') - .utc() - .toDate(); - - if (data.teamManager) { - let team; - try { - team = await Team.findOne({ _id: data.teamManager, isArchived: false }); - } catch (err) { - console.log( - `Team ${data.teamManager} failed to be found at create-event` - ); - return next(err); - } - - if (!team) { - return res.status(404).json({ teamManager: 'Not found' }); - } - - const teamManagers = team.managers.map(m => m.toString()); - if (!teamManagers.includes(req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else { - data.teamManager = undefined; - } - - if (data.donationEnabled) { - const campaignData = new FormData(); - campaignData.append('title', data.name); - campaignData.append('goal_in_cents', data.donationGoal * 100); - - let options = { - method: 'POST', - url: `https://${ - process.env.DONATELY_SUBDOMAIN - }.dntly.com/api/v1/admin/campaigns`, - headers: { - 'Content-Type': `multipart/form-data; boundary=${ - campaignData._boundary - }` - }, - auth: { - username: process.env.DONATELY_TOKEN, - password: '' - }, - data: campaignData - }; - - let response; - try { - response = await axios(options); - } catch (err) { - console.log('Donation campaign failed to be created at create-event.'); - return next(err); - } - - data.donationId = response.data.campaign.id; - } - - let event; - try { - event = await Event.create(data); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Event failed to be created at create-event.\nData: ${JSON.stringify( - data - )}` - ); - return next(err); - } - - req.user.events = [...req.user.events, event.id]; - req.user.updatedAt = moment.utc().toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at create-event`); - return next(err); - } - - let eventLocation; - if (event.location.coordinates) { - eventLocation = { - lat: event.location.coordinates[1], - lng: event.location.coordinates[0] - }; - } - const dataResponse = { - id: event.id, - address: event.address, - description: event.description, - endDate: event.description, - isOpen: event.isOpen, - location: eventLocation, - managers: event.managers, - name: event.name, - participantsGoal: event.participantsGoal, - poster: event.poster, - reviewsGoal: event.reviewsGoal, - teamManager: event.teamManager - }; - - return res.status(201).json(dataResponse); -}; +const axios = require('axios'); +const FormData = require('form-data'); +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { cleanSpaces } = require('../../helpers'); +const { Photo } = require('../../models/photo'); +const { Team } = require('../../models/team'); + +const { validateCreateEvent } = require('./validations'); + +module.exports = async (req, res, next) => { + const data = { + address: req.body.address, + description: req.body.description, + donationAmounts: req.body.donationAmounts, + donationEnabled: req.body.donationEnabled, + donationGoal: req.body.donationGoal, + endDate: req.body.endDate, + isOpen: req.body.isOpen, + locationCoordinates: req.body.locationCoordinates, + name: req.body.name, + participantsGoal: req.body.participantsGoal, + poster: req.body.poster, + reviewsGoal: req.body.reviewsGoal, + startDate: req.body.startDate, + teamManager: req.body.teamManager + }; + + const { errors, isValid } = validateCreateEvent(data); + if (!isValid) return res.status(400).json(errors); + + data.address = cleanSpaces(data.address); + + data.endDate = moment(data.endDate).endOf('day').utc().toDate(); + + data.location = { + coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]] + }; + delete data.locationCoordinates; + + data.managers = [req.user.id]; + + data.name = cleanSpaces(data.name); + let repeatedEvent; + try { + repeatedEvent = await Event.findOne({ name: data.name, isArchived: false }); + } catch (err) { + console.log(`Event ${data.name} failed to be found at create-event`); + return next(err); + } + + if (repeatedEvent) { + return res.status(400).json({ name: 'Is already taken' }); + } + + if (data.poster) { + let poster; + try { + poster = await Photo.findOne({ url: data.poster }); + } catch (err) { + console.log(`Poster ${data.poster} failed to be found at create-event`); + return next(err); + } + + if (!poster) { + return res.status(404).json({ poster: 'Not found' }); + } + } + + data.startDate = moment(data.startDate).startOf('day').utc().toDate(); + + if (data.teamManager) { + let team; + try { + team = await Team.findOne({ _id: data.teamManager, isArchived: false }); + } catch (err) { + console.log( + `Team ${data.teamManager} failed to be found at create-event` + ); + return next(err); + } + + if (!team) { + return res.status(404).json({ teamManager: 'Not found' }); + } + + const teamManagers = team.managers.map((m) => m.toString()); + if (!teamManagers.includes(req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else { + data.teamManager = undefined; + } + + if (data.donationEnabled) { + const campaignData = new FormData(); + campaignData.append('title', data.name); + campaignData.append('goal_in_cents', data.donationGoal * 100); + + let options = { + method: 'POST', + url: `https://${ + process.env.DONATELY_SUBDOMAIN + }.dntly.com/api/v1/admin/campaigns`, + headers: { + 'Content-Type': `multipart/form-data; boundary=${ + campaignData._boundary + }` + }, + auth: { + username: process.env.DONATELY_TOKEN, + password: '' + }, + data: campaignData + }; + + let response; + try { + response = await axios(options); + } catch (err) { + console.log('Donation campaign failed to be created at create-event.'); + return next(err); + } + + data.donationId = response.data.campaign.id; + } + + let event; + try { + event = await Event.create(data); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Event failed to be created at create-event.\nData: ${JSON.stringify( + data + )}` + ); + return next(err); + } + + req.user.events = [...req.user.events, event.id]; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at create-event`); + return next(err); + } + + let eventLocation; + if (event.location.coordinates) { + eventLocation = { + lat: event.location.coordinates[1], + lng: event.location.coordinates[0] + }; + } + const dataResponse = { + id: event.id, + address: event.address, + description: event.description, + endDate: event.description, + isOpen: event.isOpen, + location: eventLocation, + managers: event.managers, + name: event.name, + participantsGoal: event.participantsGoal, + poster: event.poster, + reviewsGoal: event.reviewsGoal, + teamManager: event.teamManager + }; + + return res.status(201).json(dataResponse); +}; diff --git a/src/routes/events/delete-event.js b/src/routes/events/delete-event.js index 17842f1..ca305ae 100644 --- a/src/routes/events/delete-event.js +++ b/src/routes/events/delete-event.js @@ -1,130 +1,130 @@ -const aws = require('aws-sdk'); -const { last } = require('lodash'); -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -const s3 = new aws.S3(); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const eventId = req.params.eventId; - - let event; - try { - event = await Event.findOne({ _id: eventId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); - } - console.log(`Event ${eventId} failed to be found at delete-event`); - return next(err); - } - - if (!event) { - return res.status(404).json({ general: 'Event not found' }); - } - - if ( - !event.managers.find(m => m.toString() === req.user.id) && - !req.user.isAdmin - ) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const endDate = moment(event.endDate).utc(); - const today = moment.utc(); - - if (endDate.isBefore(today) && event.reviews > 0) { - return res.status(423).json({ - general: - 'It cannot be removed because it already ended and has one or more reviews' - }); - } - - const participantsPromises = event.participants.map(p => - User.findOne({ _id: p.toString() }) - ); - - let participants; - try { - participants = await Promise.all(participantsPromises); - } catch (err) { - console.log('A participant failed to be found at delete-event'); - return next(err); - } - - for (const participant of participants) { - participant.events = participant.events.filter( - e => e.toString() !== event.id - ); - participant.updatedAt = moment.utc().toDate(); - - try { - await participant.save(); - } catch (err) { - console.log( - `Participant ${participant.id} failed to be updated at delete-event` - ); - return next(err); - } - } - - if (event.photos && event.photos.length > 0) { - for (const photo of event.photos) { - const photoParams = { - Bucket: process.env.AWS_S3_BUCKET, - Key: `events/photos/${last(photo.url.split('/'))}` - }; - - try { - await s3.deleteObject(photoParams).promise(); - } catch (err) { - console.log( - `Photo ${photoParams.Key} failed to be deleted at delete-event` - ); - return next(err); - } - } - } - - if (event.teams && event.teams.length > 0) { - const teamsPromises = event.teams.map(t => - Team.findOne({ _id: t.toString() }) - ); - - let teams; - try { - teams = await Promise.all(teamsPromises); - } catch (err) { - console.log('A team failed to be found at delete-event'); - return next(err); - } - - for (const team of teams) { - team.events = team.events.filter(e => e.toString() !== event.id); - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log(`Team ${team.id} failed to be updated at delete-event`); - return next(err); - } - } - } - - try { - await event.remove(); - } catch (err) { - console.log(`Event ${event.id} failed to be removed at delete-event`); - return next(err); - } - - return res.status(204).json({ general: 'Success' }); -}; +const aws = require('aws-sdk'); +const { last } = require('lodash'); +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +const s3 = new aws.S3(); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const eventId = req.params.eventId; + + let event; + try { + event = await Event.findOne({ _id: eventId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Event not found' }); + } + console.log(`Event ${eventId} failed to be found at delete-event`); + return next(err); + } + + if (!event) { + return res.status(404).json({ general: 'Event not found' }); + } + + if ( + !event.managers.find((m) => m.toString() === req.user.id) && + !req.user.isAdmin + ) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const endDate = moment(event.endDate).utc(); + const today = moment.utc(); + + if (endDate.isBefore(today) && event.reviews > 0) { + return res.status(423).json({ + general: + 'It cannot be removed because it already ended and has one or more reviews' + }); + } + + const participantsPromises = event.participants.map((p) => + User.findOne({ _id: p.toString() }) + ); + + let participants; + try { + participants = await Promise.all(participantsPromises); + } catch (err) { + console.log('A participant failed to be found at delete-event'); + return next(err); + } + + for (const participant of participants) { + participant.events = participant.events.filter( + (e) => e.toString() !== event.id + ); + participant.updatedAt = moment.utc().toDate(); + + try { + await participant.save(); + } catch (err) { + console.log( + `Participant ${participant.id} failed to be updated at delete-event` + ); + return next(err); + } + } + + if (event.photos && event.photos.length > 0) { + for (const photo of event.photos) { + const photoParams = { + Bucket: process.env.AWS_S3_BUCKET, + Key: `events/photos/${last(photo.url.split('/'))}` + }; + + try { + await s3.deleteObject(photoParams).promise(); + } catch (err) { + console.log( + `Photo ${photoParams.Key} failed to be deleted at delete-event` + ); + return next(err); + } + } + } + + if (event.teams && event.teams.length > 0) { + const teamsPromises = event.teams.map((t) => + Team.findOne({ _id: t.toString() }) + ); + + let teams; + try { + teams = await Promise.all(teamsPromises); + } catch (err) { + console.log('A team failed to be found at delete-event'); + return next(err); + } + + for (const team of teams) { + team.events = team.events.filter((e) => e.toString() !== event.id); + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log(`Team ${team.id} failed to be updated at delete-event`); + return next(err); + } + } + } + + try { + await event.remove(); + } catch (err) { + console.log(`Event ${event.id} failed to be removed at delete-event`); + return next(err); + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/events/edit-event.js b/src/routes/events/edit-event.js index 29368ab..96aa7e2 100644 --- a/src/routes/events/edit-event.js +++ b/src/routes/events/edit-event.js @@ -1,387 +1,377 @@ -const { difference, intersection } = require('lodash'); -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -const { validateEditEvent } = require('./validations'); - -module.exports = async (req, res, next) => { - const eventId = req.params.eventId; - - let event; - try { - event = await Event.findOne({ _id: eventId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); - } - - console.log(`Event ${eventId} failed to be found at edit-event`); - return next(err); - } - - if (!event) { - return res.status(404).json({ general: 'Event not found' }); - } - - if (!event.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const data = { - address: req.body.address, - description: req.body.description, - endDate: req.body.endDate, - isOpen: req.body.isOpen, - locationCoordinates: req.body.locationCoordinates, - managers: req.body.managers, - name: req.body.name, - participants: req.body.participants, - participantsGoal: req.body.participantsGoal, - poster: req.body.poster, - reviewsGoal: req.body.reviewsGoal, - startDate: req.body.startDate, - teamManager: req.body.teamManager, - teams: req.body.teams - }; - - const { errors, isValid } = validateEditEvent(data); - if (!isValid) return res.status(400).json(errors); - - event.address = data.address ? cleanSpaces(data.address) : event.address; - event.description = data.description || event.description; - - if (data.endDate) { - const endDate = moment(data.endDate) - .endOf('day') - .utc(); - const startDate = moment(event.startDate) - .startOf('day') - .utc(); - - if (!data.startDate) { - if (endDate.isBefore(startDate)) { - return res.status(400).json({ - endDate: 'Should be equal to or greater than startDate' - }); - } else if (endDate.diff(startDate, 'days') > 365) { - return res.status(400).json({ - endDate: 'Should last less than 365 days from startDate' - }); - } - } - - event.endDate = endDate.toDate(); - } - - event.isOpen = - typeof data.isOpen !== 'undefined' ? data.isOpen : event.isOpen; - - if (data.locationCoordinates && data.locationCoordinates.length > 0) { - event.location = { - coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]], - type: 'Point' - }; - } - - if (data.managers) { - let managersToAdd = []; - let managersToRemove = []; - - data.managers.forEach(m => { - if (m.startsWith('-')) { - managersToRemove = [...managersToRemove, m.substring(1)]; - } else { - managersToAdd = [...managersToAdd, m]; - } - }); - - const eventManagers = event.managers.map(m => m.toString()); - - managersToAdd = [...new Set(difference(managersToAdd, eventManagers))]; - if (managersToAdd.length > 0) { - const eventParticipants = event.participants.map(p => p.toString()); - const notParticipant = managersToAdd.find( - m => !eventParticipants.includes(m) - ); - - if (notParticipant) { - return res.status(400).json({ - managers: `User ${notParticipant} is not a participant of this event` - }); - } - - event.managers = [...eventManagers, ...managersToAdd]; - event.participants = event.participants.filter( - p => !managersToAdd.includes(p.toString()) - ); - } - - managersToRemove = [ - ...new Set(intersection(managersToRemove, eventManagers)) - ]; - if (managersToRemove.length === event.managers.length) { - return res - .status(400) - .json({ managers: 'Should not remove all managers' }); - } - - event.managers = event.managers.filter( - m => !managersToRemove.includes(m.toString()) - ); - const eventParticipants = event.participants.map(p => p.toString()); - event.participants = [...eventParticipants, ...managersToRemove]; - } - - if (data.name) { - const eventName = cleanSpaces(data.name); - - if (eventName !== event.name) { - let repeatedEvent; - try { - repeatedEvent = await Event.findOne({ - name: eventName, - isArchived: false - }); - } catch (err) { - console.log(`Event ${eventName} failed to be found at edit-event`); - return next(err); - } - - if (repeatedEvent) { - return res.status(400).json({ name: 'Is already taken' }); - } - - event.name = eventName; - } - } - - if (data.participants) { - const eventParticipants = event.participants.map(p => p.toString()); - let participantsToRemove = data.participants.map(p => p.substring(1)); - participantsToRemove = [ - ...new Set(intersection(participantsToRemove, eventParticipants)) - ]; - - const getParticipants = participantsToRemove.map(p => - User.find({ _id: p, isArchived: false }) - ); - let participants; - try { - participants = await Promise.all(getParticipants); - } catch (err) { - console.log('Participants failed to be found at edit-event'); - return next(err); - } - - const updateParticipants = participants.map((p, i) => { - p[i].events = p[i].events.filter(e => e.toString() !== event.id); - return p[i].save(); - }); - - try { - await Promise.all(updateParticipants); - } catch (err) { - console.log('Participants failed to be updated at edit-event'); - return next(err); - } - - event.participants = event.participants.filter( - p => !participantsToRemove.includes(p.toString()) - ); - } - - event.participantsGoal = data.participantsGoal || event.participantsGoal; - - if ( - data.poster && - !data.poster.includes('default') && - data.poster !== event.poster - ) { - let poster; - try { - poster = await Photo.findOne({ url: data.poster }); - } catch (err) { - console.log(`Poster ${data.poster} failed to be found at edit-event`); - return next(err); - } - - if (!poster) { - return res.status(404).json({ poster: 'Not found' }); - } - - event.poster = data.poster; - } else if (data.poster === '') { - event.poster = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/events/posters/default.png`; - } - - event.reviewsGoal = data.reviewsGoal || event.reviewsGoal; - - if (data.startDate) { - const startDate = moment(data.startDate) - .startOf('day') - .utc(); - const endDate = moment(event.endDate) - .endOf('day') - .utc(); - - if (!data.endDate) { - const today = moment() - .startOf('day') - .utc(); - - if (startDate.isBefore(today)) { - return res.status(400).json({ - startDate: 'Should be equal to or greater than the current time' - }); - } else if (startDate.isAfter(endDate)) { - return res.status(400).json({ - startDate: 'Should be equal to or less than endDate' - }); - } else if (endDate.diff(startDate, 'days') > 365) { - return res.status(400).json({ - startDate: 'Should last less than 365 days to endDate' - }); - } - } - - event.startDate = startDate.toDate(); - } - - if (data.teamManager) { - let team; - try { - team = await Team.findOne({ _id: data.teamManager, isArchived: false }); - } catch (err) { - console.log(`Team ${data.teamManager} failed to be found at edit-event`); - return next(err); - } - - if (!team) { - return res.status(404).json({ teamManager: 'Not found' }); - } - - const teamManagers = team.managers.map(m => m.toString()); - if (!teamManagers.includes(req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - event.teamManager = data.teamManager; - - team.events = [...new Set([...team.events, event.id])]; - try { - await team.save(); - } catch (err) { - console.log(`Team ${team.id} failed to be updated at edit-event`); - return next(err); - } - } else if (data.teamManager === '' && event.teamManager) { - let team; - try { - team = await Team.findOne({ _id: event.teamManager, isArchived: false }); - } catch (err) { - console.log(`Team ${event.teamManager} failed to be found at edit-event`); - return next(err); - } - - if (!team) { - return res.status(404).json({ teamManager: 'Not found' }); - } - - const teamManagers = team.managers.map(m => m.toString()); - if (!teamManagers.includes(req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - event.teamManager = null; - - team.events = team.events.filter(e => e.toString() !== event.id); - try { - await team.save(); - } catch (err) { - console.log(`Team ${team.id} failed to be updated at edit-event`); - return next(err); - } - } - - if (data.teams) { - const eventTeams = event.teams.map(t => t.toString()); - let teamsToRemove = data.teams.map(t => t.substring(1)); - teamsToRemove = [...new Set(intersection(teamsToRemove, eventTeams))]; - - const getTeams = teamsToRemove.map(t => - Team.find({ _id: t, isArchived: false }) - ); - let teams; - try { - teams = await Promise.all(getTeams); - } catch (err) { - console.log('Teams failed to be found at edit-event'); - return next(err); - } - - const updateTeams = teams.map((t, i) => { - t[i].events = t[i].events.filter(e => e.toString() !== event.id); - return t[i].save(); - }); - - try { - await Promise.all(updateTeams); - } catch (err) { - console.log('Teams failed to be updated at edit-event'); - return next(err); - } - - event.teams = event.teams.filter( - t => !teamsToRemove.includes(t.toString()) - ); - } - - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log(`Event ${event.id} failed to be updated at edit-event`); - return next(err); - } - - let eventLocation; - if (event.location.coordinates) { - eventLocation = { - lat: event.location.coordinates[1], - lng: event.location.coordinates[0] - }; - } - const dataResponse = { - address: event.address, - description: event.description, - endDate: event.description, - isOpen: event.isOpen, - location: eventLocation, - managers: event.managers, - name: event.name, - participantsGoal: event.participantsGoal, - poster: event.poster, - reviewsGoal: event.reviewsGoal, - teamManager: event.teamManager - }; - - return res.status(200).json(dataResponse); -}; +const { difference, intersection } = require('lodash'); +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { cleanSpaces } = require('../../helpers'); +const { Photo } = require('../../models/photo'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +const { validateEditEvent } = require('./validations'); + +module.exports = async (req, res, next) => { + const eventId = req.params.eventId; + + let event; + try { + event = await Event.findOne({ _id: eventId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Event not found' }); + } + + console.log(`Event ${eventId} failed to be found at edit-event`); + return next(err); + } + + if (!event) { + return res.status(404).json({ general: 'Event not found' }); + } + + if (!event.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const data = { + address: req.body.address, + description: req.body.description, + endDate: req.body.endDate, + isOpen: req.body.isOpen, + locationCoordinates: req.body.locationCoordinates, + managers: req.body.managers, + name: req.body.name, + participants: req.body.participants, + participantsGoal: req.body.participantsGoal, + poster: req.body.poster, + reviewsGoal: req.body.reviewsGoal, + startDate: req.body.startDate, + teamManager: req.body.teamManager, + teams: req.body.teams + }; + + const { errors, isValid } = validateEditEvent(data); + if (!isValid) return res.status(400).json(errors); + + event.address = data.address ? cleanSpaces(data.address) : event.address; + event.description = data.description || event.description; + + if (data.endDate) { + const endDate = moment(data.endDate).endOf('day').utc(); + const startDate = moment(event.startDate).startOf('day').utc(); + + if (!data.startDate) { + if (endDate.isBefore(startDate)) { + return res.status(400).json({ + endDate: 'Should be equal to or greater than startDate' + }); + } else if (endDate.diff(startDate, 'days') > 365) { + return res.status(400).json({ + endDate: 'Should last less than 365 days from startDate' + }); + } + } + + event.endDate = endDate.toDate(); + } + + event.isOpen = + typeof data.isOpen !== 'undefined' ? data.isOpen : event.isOpen; + + if (data.locationCoordinates && data.locationCoordinates.length > 0) { + event.location = { + coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]], + type: 'Point' + }; + } + + if (data.managers) { + let managersToAdd = []; + let managersToRemove = []; + + data.managers.forEach((m) => { + if (m.startsWith('-')) { + managersToRemove = [...managersToRemove, m.substring(1)]; + } else { + managersToAdd = [...managersToAdd, m]; + } + }); + + const eventManagers = event.managers.map((m) => m.toString()); + + managersToAdd = [...new Set(difference(managersToAdd, eventManagers))]; + if (managersToAdd.length > 0) { + const eventParticipants = event.participants.map((p) => p.toString()); + const notParticipant = managersToAdd.find( + (m) => !eventParticipants.includes(m) + ); + + if (notParticipant) { + return res.status(400).json({ + managers: `User ${notParticipant} is not a participant of this event` + }); + } + + event.managers = [...eventManagers, ...managersToAdd]; + event.participants = event.participants.filter( + (p) => !managersToAdd.includes(p.toString()) + ); + } + + managersToRemove = [ + ...new Set(intersection(managersToRemove, eventManagers)) + ]; + if (managersToRemove.length === event.managers.length) { + return res + .status(400) + .json({ managers: 'Should not remove all managers' }); + } + + event.managers = event.managers.filter( + (m) => !managersToRemove.includes(m.toString()) + ); + const eventParticipants = event.participants.map((p) => p.toString()); + event.participants = [...eventParticipants, ...managersToRemove]; + } + + if (data.name) { + const eventName = cleanSpaces(data.name); + + if (eventName !== event.name) { + let repeatedEvent; + try { + repeatedEvent = await Event.findOne({ + name: eventName, + isArchived: false + }); + } catch (err) { + console.log(`Event ${eventName} failed to be found at edit-event`); + return next(err); + } + + if (repeatedEvent) { + return res.status(400).json({ name: 'Is already taken' }); + } + + event.name = eventName; + } + } + + if (data.participants) { + const eventParticipants = event.participants.map((p) => p.toString()); + let participantsToRemove = data.participants.map((p) => p.substring(1)); + participantsToRemove = [ + ...new Set(intersection(participantsToRemove, eventParticipants)) + ]; + + const getParticipants = participantsToRemove.map((p) => + User.find({ _id: p, isArchived: false }) + ); + let participants; + try { + participants = await Promise.all(getParticipants); + } catch (err) { + console.log('Participants failed to be found at edit-event'); + return next(err); + } + + const updateParticipants = participants.map((p, i) => { + p[i].events = p[i].events.filter((e) => e.toString() !== event.id); + return p[i].save(); + }); + + try { + await Promise.all(updateParticipants); + } catch (err) { + console.log('Participants failed to be updated at edit-event'); + return next(err); + } + + event.participants = event.participants.filter( + (p) => !participantsToRemove.includes(p.toString()) + ); + } + + event.participantsGoal = data.participantsGoal || event.participantsGoal; + + if ( + data.poster && + !data.poster.includes('default') && + data.poster !== event.poster + ) { + let poster; + try { + poster = await Photo.findOne({ url: data.poster }); + } catch (err) { + console.log(`Poster ${data.poster} failed to be found at edit-event`); + return next(err); + } + + if (!poster) { + return res.status(404).json({ poster: 'Not found' }); + } + + event.poster = data.poster; + } else if (data.poster === '') { + event.poster = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/events/posters/default.png`; + } + + event.reviewsGoal = data.reviewsGoal || event.reviewsGoal; + + if (data.startDate) { + const startDate = moment(data.startDate).startOf('day').utc(); + const endDate = moment(event.endDate).endOf('day').utc(); + + if (!data.endDate) { + const today = moment().startOf('day').utc(); + + if (startDate.isBefore(today)) { + return res.status(400).json({ + startDate: 'Should be equal to or greater than the current time' + }); + } else if (startDate.isAfter(endDate)) { + return res.status(400).json({ + startDate: 'Should be equal to or less than endDate' + }); + } else if (endDate.diff(startDate, 'days') > 365) { + return res.status(400).json({ + startDate: 'Should last less than 365 days to endDate' + }); + } + } + + event.startDate = startDate.toDate(); + } + + if (data.teamManager) { + let team; + try { + team = await Team.findOne({ _id: data.teamManager, isArchived: false }); + } catch (err) { + console.log(`Team ${data.teamManager} failed to be found at edit-event`); + return next(err); + } + + if (!team) { + return res.status(404).json({ teamManager: 'Not found' }); + } + + const teamManagers = team.managers.map((m) => m.toString()); + if (!teamManagers.includes(req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + event.teamManager = data.teamManager; + + team.events = [...new Set([...team.events, event.id])]; + try { + await team.save(); + } catch (err) { + console.log(`Team ${team.id} failed to be updated at edit-event`); + return next(err); + } + } else if (data.teamManager === '' && event.teamManager) { + let team; + try { + team = await Team.findOne({ _id: event.teamManager, isArchived: false }); + } catch (err) { + console.log(`Team ${event.teamManager} failed to be found at edit-event`); + return next(err); + } + + if (!team) { + return res.status(404).json({ teamManager: 'Not found' }); + } + + const teamManagers = team.managers.map((m) => m.toString()); + if (!teamManagers.includes(req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + event.teamManager = null; + + team.events = team.events.filter((e) => e.toString() !== event.id); + try { + await team.save(); + } catch (err) { + console.log(`Team ${team.id} failed to be updated at edit-event`); + return next(err); + } + } + + if (data.teams) { + const eventTeams = event.teams.map((t) => t.toString()); + let teamsToRemove = data.teams.map((t) => t.substring(1)); + teamsToRemove = [...new Set(intersection(teamsToRemove, eventTeams))]; + + const getTeams = teamsToRemove.map((t) => + Team.find({ _id: t, isArchived: false }) + ); + let teams; + try { + teams = await Promise.all(getTeams); + } catch (err) { + console.log('Teams failed to be found at edit-event'); + return next(err); + } + + const updateTeams = teams.map((t, i) => { + t[i].events = t[i].events.filter((e) => e.toString() !== event.id); + return t[i].save(); + }); + + try { + await Promise.all(updateTeams); + } catch (err) { + console.log('Teams failed to be updated at edit-event'); + return next(err); + } + + event.teams = event.teams.filter( + (t) => !teamsToRemove.includes(t.toString()) + ); + } + + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log(`Event ${event.id} failed to be updated at edit-event`); + return next(err); + } + + let eventLocation; + if (event.location.coordinates) { + eventLocation = { + lat: event.location.coordinates[1], + lng: event.location.coordinates[0] + }; + } + const dataResponse = { + address: event.address, + description: event.description, + endDate: event.description, + isOpen: event.isOpen, + location: eventLocation, + managers: event.managers, + name: event.name, + participantsGoal: event.participantsGoal, + poster: event.poster, + reviewsGoal: event.reviewsGoal, + teamManager: event.teamManager + }; + + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/events/get-event.js b/src/routes/events/get-event.js index eb8bd3a..c07a89d 100644 --- a/src/routes/events/get-event.js +++ b/src/routes/events/get-event.js @@ -1,207 +1,207 @@ -const axios = require('axios'); -const mongoose = require('mongoose'); -const { isMongoId } = require('validator'); - -const { Event } = require('../../models/event'); - -module.exports = async (req, res, next) => { - let eventId = req.params.eventId; - if (!isMongoId(eventId)) { - return res.status(400).json({ general: 'Event not found' }); - } - eventId = mongoose.Types.ObjectId(eventId); - - let event; - try { - event = await Event.aggregate([ - { - $match: { _id: eventId } - }, - { - $lookup: { - from: 'users', - let: { managers: '$managers' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$managers'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1 - } - } - ], - as: 'managers' - } - }, - { - $lookup: { - from: 'users', - let: { participants: '$participants' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$participants'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1 - } - } - ], - as: 'participants' - } - }, - { - $lookup: { - from: 'teams', - let: { teams: '$teams' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$teams'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - name: 1 - } - } - ], - as: 'teams' - } - }, - { - $lookup: { - from: 'teams', - let: { teamManager: '$teamManager' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$teamManager'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - name: 1 - } - } - ], - as: 'teamManager' - } - }, - { - $unwind: { - path: '$teamManager', - preserveNullAndEmptyArrays: true - } - }, - { - $lookup: { - from: 'events', - let: { reviewsAmount: '$reviewsAmount' }, - pipeline: [ - { - $match: { - $expr: { - $gt: ['$reviewsAmount', '$$reviewsAmount'] - } - } - }, - { - $count: 'ranking' - } - ], - as: 'ranking' - } - }, - { - $project: { - _id: 0, - id: '$_id', - address: 1, - description: 1, - donationAmounts: 1, - donationId: 1, - endDate: 1, - isOpen: 1, - location: 1, - managers: 1, - name: 1, - participants: 1, - participantsGoal: 1, - poster: 1, - ranking: 1, - reviewsAmount: 1, - reviewsGoal: 1, - startDate: 1, - teamManager: 1, - teams: 1 - } - } - ]); - } catch (err) { - console.log(`Event ${eventId} failed to be found at get-event`); - return next(err); - } - - if (!event) { - return res.status(404).json({ general: 'Event not found' }); - } - - const dataResponse = Object.assign({}, event[0], { - ranking: event[0].ranking.length ? event[0].ranking[0].ranking + 1 : 1 - }); - - if (dataResponse.donationId) { - let options = { - method: 'GET', - url: `https://${ - process.env.DONATELY_SUBDOMAIN - }.dntly.com/api/v1/admin/campaigns/${dataResponse.donationId}`, - auth: { - username: process.env.DONATELY_TOKEN, - password: '' - } - }; - - let response; - try { - response = await axios(options); - } catch (err) { - console.log('Donation campaign failed to be found at get-event.'); - return next(err); - } - - dataResponse.donationAmountRaised = response.data.campaign.amount_raised; - dataResponse.donationDonorsCount = response.data.campaign.donors_count; - dataResponse.donationGoal = response.data.campaign.campaign_goal; - } - - return res.status(200).json(dataResponse); -}; +const axios = require('axios'); +const mongoose = require('mongoose'); +const { isMongoId } = require('validator'); + +const { Event } = require('../../models/event'); + +module.exports = async (req, res, next) => { + let eventId = req.params.eventId; + if (!isMongoId(eventId)) { + return res.status(400).json({ general: 'Event not found' }); + } + eventId = new mongoose.Types.ObjectId(eventId); + + let event; + try { + event = await Event.aggregate([ + { + $match: { _id: eventId } + }, + { + $lookup: { + from: 'users', + let: { managers: '$managers' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$managers'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1 + } + } + ], + as: 'managers' + } + }, + { + $lookup: { + from: 'users', + let: { participants: '$participants' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$participants'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1 + } + } + ], + as: 'participants' + } + }, + { + $lookup: { + from: 'teams', + let: { teams: '$teams' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$teams'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + name: 1 + } + } + ], + as: 'teams' + } + }, + { + $lookup: { + from: 'teams', + let: { teamManager: '$teamManager' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$teamManager'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + name: 1 + } + } + ], + as: 'teamManager' + } + }, + { + $unwind: { + path: '$teamManager', + preserveNullAndEmptyArrays: true + } + }, + { + $lookup: { + from: 'events', + let: { reviewsAmount: '$reviewsAmount' }, + pipeline: [ + { + $match: { + $expr: { + $gt: ['$reviewsAmount', '$$reviewsAmount'] + } + } + }, + { + $count: 'ranking' + } + ], + as: 'ranking' + } + }, + { + $project: { + _id: 0, + id: '$_id', + address: 1, + description: 1, + donationAmounts: 1, + donationId: 1, + endDate: 1, + isOpen: 1, + location: 1, + managers: 1, + name: 1, + participants: 1, + participantsGoal: 1, + poster: 1, + ranking: 1, + reviewsAmount: 1, + reviewsGoal: 1, + startDate: 1, + teamManager: 1, + teams: 1 + } + } + ]); + } catch (err) { + console.log(`Event ${eventId} failed to be found at get-event`); + return next(err); + } + + if (!event) { + return res.status(404).json({ general: 'Event not found' }); + } + + const dataResponse = Object.assign({}, event[0], { + ranking: event[0].ranking.length ? event[0].ranking[0].ranking + 1 : 1 + }); + + if (dataResponse.donationId) { + let options = { + method: 'GET', + url: `https://${ + process.env.DONATELY_SUBDOMAIN + }.dntly.com/api/v1/admin/campaigns/${dataResponse.donationId}`, + auth: { + username: process.env.DONATELY_TOKEN, + password: '' + } + }; + + let response; + try { + response = await axios(options); + } catch (err) { + console.log('Donation campaign failed to be found at get-event.'); + return next(err); + } + + dataResponse.donationAmountRaised = response.data.campaign.amount_raised; + dataResponse.donationDonorsCount = response.data.campaign.donors_count; + dataResponse.donationGoal = response.data.campaign.campaign_goal; + } + + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/events/index.js b/src/routes/events/index.js index fbbe43d..901a189 100644 --- a/src/routes/events/index.js +++ b/src/routes/events/index.js @@ -1,31 +1,31 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const createEvent = require('./create-event'); -const deleteEvent = require('./delete-event'); -const editEvent = require('./edit-event'); -const getEvent = require('./get-event'); -const leaveEvent = require('./leave-event'); -const listEvents = require('./list-events'); -const joinEvent = require('./join-event'); - -const router = new express.Router(); - -router.get('', listEvents); -router.post('', isAuthenticated({ isOptional: false }), createEvent); -router.get('/:eventId', getEvent); -router.put('/:eventId', isAuthenticated({ isOptional: false }), editEvent); -router.delete('/:eventId', isAuthenticated({ isOptional: false }), deleteEvent); -router.post( - '/:eventId/join', - isAuthenticated({ isOptional: false }), - joinEvent -); -router.put( - '/:eventId/leave', - isAuthenticated({ isOptional: false }), - leaveEvent -); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const createEvent = require('./create-event'); +const deleteEvent = require('./delete-event'); +const editEvent = require('./edit-event'); +const getEvent = require('./get-event'); +const leaveEvent = require('./leave-event'); +const listEvents = require('./list-events'); +const joinEvent = require('./join-event'); + +const router = new express.Router(); + +router.get('', listEvents); +router.post('', isAuthenticated({ isOptional: false }), createEvent); +router.get('/:eventId', getEvent); +router.put('/:eventId', isAuthenticated({ isOptional: false }), editEvent); +router.delete('/:eventId', isAuthenticated({ isOptional: false }), deleteEvent); +router.post( + '/:eventId/join', + isAuthenticated({ isOptional: false }), + joinEvent +); +router.put( + '/:eventId/leave', + isAuthenticated({ isOptional: false }), + leaveEvent +); + +module.exports = router; diff --git a/src/routes/events/join-event.js b/src/routes/events/join-event.js index 91b4f1e..f3b6378 100644 --- a/src/routes/events/join-event.js +++ b/src/routes/events/join-event.js @@ -1,134 +1,134 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); - -module.exports = async (req, res, next) => { - const eventId = req.params.eventId; - - let event; - try { - event = await Event.findOne({ _id: eventId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); - } - - console.log(`Event ${eventId} failed to be found at join-event`); - return next(err); - } - - if (!event) { - return res.status(404).json({ general: 'Event not found' }); - } - - const eventParticipants = event.participants.map(p => p.toString()); - if (eventParticipants.includes(req.user.id)) { - return res - .status(400) - .json({ general: 'You already are a participant in this event' }); - } - - const eventManagers = event.managers.map(m => m.toString()); - if (eventManagers.includes(req.user.id)) { - return res - .status(400) - .json({ general: 'You already are a participant in this event' }); - } - - if (event.isOpen) { - req.user.events = [...req.user.events, event.id]; - req.user.updatedAt = moment.utc().toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at join-event`); - return next(err); - } - - event.participants = [...event.participants, req.user.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log(`Event ${event.id} failed to be updated at join-event`); - return next(err); - } - - return res.status(200).json({ general: 'Joined' }); - } else { - let petition; - try { - petition = await Petition.findOne({ - event: event.id, - sender: req.user.id, - type: 'request-user-event' - }); - } catch (err) { - console.log( - `Petition from user ${req.user.id} to event ${ - event.id - } failed to be found at join-event` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'You already have a pending petition with this event' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at join-event` - ); - return next(err); - } - } - - const endDate = moment(event.endDate).utc(); - const today = moment.utc(); - if (endDate.isBefore(today)) { - return res - .status(423) - .json({ general: 'This event has already finished' }); - } - - const petitionData = { - event: event.id, - sender: req.user.id, - type: 'request-user-event' - }; - try { - await Petition.create(petitionData); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Petition failed to be created at join-event.\nData: ${JSON.stringify( - petitionData - )}` - ); - return next(err); - } - - return res.status(200).json({ general: 'Requested' }); - } -}; +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Petition } = require('../../models/petition'); + +module.exports = async (req, res, next) => { + const eventId = req.params.eventId; + + let event; + try { + event = await Event.findOne({ _id: eventId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Event not found' }); + } + + console.log(`Event ${eventId} failed to be found at join-event`); + return next(err); + } + + if (!event) { + return res.status(404).json({ general: 'Event not found' }); + } + + const eventParticipants = event.participants.map((p) => p.toString()); + if (eventParticipants.includes(req.user.id)) { + return res + .status(400) + .json({ general: 'You already are a participant in this event' }); + } + + const eventManagers = event.managers.map((m) => m.toString()); + if (eventManagers.includes(req.user.id)) { + return res + .status(400) + .json({ general: 'You already are a participant in this event' }); + } + + if (event.isOpen) { + req.user.events = [...req.user.events, event.id]; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at join-event`); + return next(err); + } + + event.participants = [...event.participants, req.user.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log(`Event ${event.id} failed to be updated at join-event`); + return next(err); + } + + return res.status(200).json({ general: 'Joined' }); + } else { + let petition; + try { + petition = await Petition.findOne({ + event: event.id, + sender: req.user.id, + type: 'request-user-event' + }); + } catch (err) { + console.log( + `Petition from user ${req.user.id} to event ${ + event.id + } failed to be found at join-event` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'You already have a pending petition with this event' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at join-event` + ); + return next(err); + } + } + + const endDate = moment(event.endDate).utc(); + const today = moment.utc(); + if (endDate.isBefore(today)) { + return res + .status(423) + .json({ general: 'This event has already finished' }); + } + + const petitionData = { + event: event.id, + sender: req.user.id, + type: 'request-user-event' + }; + try { + await Petition.create(petitionData); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Petition failed to be created at join-event.\nData: ${JSON.stringify( + petitionData + )}` + ); + return next(err); + } + + return res.status(200).json({ general: 'Requested' }); + } +}; diff --git a/src/routes/events/leave-event.js b/src/routes/events/leave-event.js index 5b4e0fd..17dc445 100644 --- a/src/routes/events/leave-event.js +++ b/src/routes/events/leave-event.js @@ -1,69 +1,69 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); - -module.exports = async (req, res, next) => { - const eventId = req.params.eventId; - - let event; - try { - event = await Event.findOne({ _id: eventId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); - } - - console.log(`Event ${eventId} failed to be found at leave-event`); - return next(err); - } - - if (!event) { - return res.status(404).json({ general: 'Event not found' }); - } - - const endDate = moment(event.endDate).utc(); - const today = moment.utc(); - - if (endDate.isBefore(today)) { - return res.status(400).json({ - general: 'You cannot leave because it already ended' - }); - } - - if (event.managers.find(m => m.toString() === req.user.id)) { - event.managers = event.managers.filter(m => m.toString() !== req.user.id); - - if (event.managers.length === 0) { - return res.status(400).json({ - general: 'You cannot leave because you are the only manager' - }); - } - } else if (event.participants.find(p => p.toString() === req.user.id)) { - event.participants = event.participants.filter( - p => p.toString() !== req.user.id - ); - } else { - return res.status(400).json({ general: 'You are not a participant' }); - } - - event.updatedAt = today.toDate(); - - try { - await event.save(); - } catch (err) { - console.log(`Event ${event.id} failed to be updated at leave-event`); - return next(err); - } - - req.user.events = req.user.events.filter(e => e.toString() !== event.id); - req.user.updatedAt = today.toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at leave-event`); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Event } = require('../../models/event'); + +module.exports = async (req, res, next) => { + const eventId = req.params.eventId; + + let event; + try { + event = await Event.findOne({ _id: eventId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Event not found' }); + } + + console.log(`Event ${eventId} failed to be found at leave-event`); + return next(err); + } + + if (!event) { + return res.status(404).json({ general: 'Event not found' }); + } + + const endDate = moment(event.endDate).utc(); + const today = moment.utc(); + + if (endDate.isBefore(today)) { + return res.status(400).json({ + general: 'You cannot leave because it already ended' + }); + } + + if (event.managers.find((m) => m.toString() === req.user.id)) { + event.managers = event.managers.filter((m) => m.toString() !== req.user.id); + + if (event.managers.length === 0) { + return res.status(400).json({ + general: 'You cannot leave because you are the only manager' + }); + } + } else if (event.participants.find((p) => p.toString() === req.user.id)) { + event.participants = event.participants.filter( + (p) => p.toString() !== req.user.id + ); + } else { + return res.status(400).json({ general: 'You are not a participant' }); + } + + event.updatedAt = today.toDate(); + + try { + await event.save(); + } catch (err) { + console.log(`Event ${event.id} failed to be updated at leave-event`); + return next(err); + } + + req.user.events = req.user.events.filter((e) => e.toString() !== event.id); + req.user.updatedAt = today.toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at leave-event`); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 9521d85..7f75d82 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -1,95 +1,88 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); - -const { validateListEvents } = require('./validations'); - -module.exports = async (req, res, next) => { - const queryParams = req.query; - - const { errors, isValid } = validateListEvents(queryParams); - if (!isValid) return res.status(400).json(errors); - - const eventsQuery = {}; - - if (queryParams.keywords) { - eventsQuery.$text = { $search: queryParams.keywords }; - } - - eventsQuery.isArchived = false; - - let afterDate; - let beforeDate; - if (queryParams.afterDate && queryParams.beforeDate) { - afterDate = moment(queryParams.afterDate) - .utc() - .toDate(); - beforeDate = moment(queryParams.beforeDate) - .utc() - .toDate(); - - eventsQuery.startDate = { $gte: afterDate, $lte: beforeDate }; - } else if (queryParams.afterDate) { - afterDate = moment(queryParams.afterDate) - .utc() - .toDate(); - eventsQuery.startDate = { $gte: afterDate }; - } else if (queryParams.beforeDate) { - beforeDate = moment(queryParams.beforeDate) - .utc() - .toDate(); - eventsQuery.startDate = { $lte: beforeDate }; - } - - let sortBy = queryParams.sortBy || '-startDate'; - let page = queryParams.page ? queryParams.page - 1 : 0; - const pageLimit = queryParams.pageLimit || 12; - - let events; - let total; - try { - [events, total] = await Promise.all([ - Event.aggregate() - .match(eventsQuery) - .project({ - _id: 0, - id: '$_id', - address: 1, - endDate: 1, - name: 1, - poster: 1, - reviewsAmount: 1, - reviewsGoal: 1, - startDate: 1 - }) - .sort(sortBy) - .skip(page * pageLimit) - .limit(pageLimit), - Event.find(eventsQuery).count() - ]); - } catch (err) { - console.log('Events failed to be found or count at list-events'); - return next(err); - } - - let lastPage = Math.ceil(total / pageLimit); - if (lastPage > 0) { - if (page > lastPage) { - return res - .status(400) - .json({ page: `Should be equal to or less than ${lastPage}` }); - } - } else { - page = null; - lastPage = null; - } - - return res.status(200).json({ - page: page + 1, - lastPage, - pageLimit, - total, - sortBy, - results: events - }); -}; +const moment = require("moment"); + +const { Event } = require("../../models/event"); + +const { validateListEvents } = require("./validations"); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + + const { errors, isValid } = validateListEvents(queryParams); + if (!isValid) return res.status(400).json(errors); + + const eventsQuery = {}; + + if (queryParams.keywords) { + eventsQuery.$text = { $search: queryParams.keywords }; + } + + eventsQuery.isArchived = false; + + let afterDate; + let beforeDate; + if (queryParams.afterDate && queryParams.beforeDate) { + afterDate = moment(queryParams.afterDate).utc().toDate(); + beforeDate = moment(queryParams.beforeDate).utc().toDate(); + + eventsQuery.startDate = { $gte: afterDate, $lte: beforeDate }; + } else if (queryParams.afterDate) { + afterDate = moment(queryParams.afterDate).utc().toDate(); + eventsQuery.startDate = { $gte: afterDate }; + } else if (queryParams.beforeDate) { + beforeDate = moment(queryParams.beforeDate).utc().toDate(); + eventsQuery.startDate = { $lte: beforeDate }; + } + + let sortBy = queryParams.sortBy || "-startDate"; + let page = queryParams.page ? queryParams.page - 1 : 0; + const pageLimit = queryParams.pageLimit || 12; + + let events; + let total; + try { + [events, total] = await Promise.all([ + Event.aggregate() + .match(eventsQuery) + .project({ + _id: 0, + id: "$_id", + address: 1, + endDate: 1, + name: 1, + poster: 1, + reviewsAmount: 1, + reviewsGoal: 1, + startDate: 1, + description: 1, + }) + .sort(sortBy) + .skip(page * pageLimit) + .limit(pageLimit), + Event.countDocuments(eventsQuery), + ]); + } catch (err) { + console.log("Events failed to be found or count at list-events"); + return next(err); + } + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + + return res.status(200).json({ + page: page + 1, + lastPage, + pageLimit, + total, + sortBy, + results: events, + }); +}; diff --git a/src/routes/events/validations.js b/src/routes/events/validations.js index 2b15620..15b98be 100644 --- a/src/routes/events/validations.js +++ b/src/routes/events/validations.js @@ -1,490 +1,466 @@ -const { isEmpty } = require('lodash'); -const { isInt, isMongoId } = require('validator'); -const moment = require('moment'); - -const { isNumber } = require('../../helpers'); - -module.exports = { - validateCreateEvent(data) { - const errors = {}; - - if (typeof data.address === 'undefined' || data.address === '') { - errors.address = 'Is required'; - } else if (typeof data.address !== 'string') { - errors.address = 'Should be a string'; - } - - if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' - ) { - errors.description = 'Should be a string'; - } - - if (data.donationEnabled === true) { - if (typeof data.donationAmounts === 'undefined') { - errors.donationAmounts = 'Is required'; - } - if (typeof data.donationGoal === 'undefined') { - errors.donationGoal = 'Is required'; - } - } - - if (typeof data.donationAmounts !== 'undefined') { - if (!Array.isArray(data.donationAmounts)) { - errors.donationAmounts = 'Should be an array'; - } else { - data.donationAmounts.some(d => { - if (typeof d.value === 'undefined') { - errors.donationAmounts = - 'All elements should have a value property'; - return true; - } else if (typeof d.value !== 'number') { - errors.donationAmounts = 'All value properties should be numbers'; - return true; - } else if (d < 5 || d > 10000) { - errors.donationAmounts = - 'All value properties should be between 5 and 10000'; - return true; - } - }); - } - } - - if ( - typeof data.donationEnabled !== 'undefined' && - typeof data.donationEnabled !== 'boolean' - ) { - errors.donationEnabled = 'Should be a boolean'; - } - - if (typeof data.donationGoal !== 'undefined') { - if (typeof data.donationGoal !== 'number') { - errors.donationGoal = 'Should be a number'; - } else if (!isInt(data.donationGoal.toString())) { - errors.donationGoal = 'Should be a integer'; - } - } - - let endDateIsValid = false; - if (typeof data.endDate === 'undefined' || data.endDate === '') { - errors.endDate = 'Is required'; - } else if (typeof data.endDate !== 'string') { - errors.endDate = 'Should be a string'; - } else if (!moment(data.endDate).isValid()) { - errors.endDate = 'Should have a ISO-8601 format'; - } else { - const endDate = moment(data.endDate) - .endOf('day') - .utc(); - const today = moment() - .startOf('day') - .utc(); - - if (endDate.isBefore(today)) { - errors.endDate = 'Should be greater than or equal to today'; - } else { - endDateIsValid = true; - } - } - - if ( - typeof data.isOpen !== 'undefined' && - typeof data.isOpen !== 'boolean' - ) { - errors.isOpen = 'Should be a boolean'; - } - - if (typeof data.locationCoordinates === 'undefined') { - errors.locationCoordinates = 'Is required'; - } else if (!Array.isArray(data.locationCoordinates)) { - errors.locationCoordinates = 'Should be an array'; - } else if (typeof data.locationCoordinates[0] === 'undefined') { - errors.locationCoordinates = 'Latitude is required'; - } else if (!isNumber(data.locationCoordinates[0])) { - errors.locationCoordinates = 'Latitude should be a number'; - } else if ( - parseFloat(data.locationCoordinates[0]) < -90 || - parseFloat(data.locationCoordinates[0]) > 90 - ) { - errors.locationCoordinates = 'Latitude value is not valid'; - } else if (typeof data.locationCoordinates[1] === 'undefined') { - errors.locationCoordinates = 'Longitude is required'; - } else if (!isNumber(data.locationCoordinates[1])) { - errors.locationCoordinates = 'Longitude should be a number'; - } else if ( - parseFloat(data.locationCoordinates[1]) < -180 || - parseFloat(data.locationCoordinates[1]) > 180 - ) { - errors.locationCoordinates = 'Longitude value is not valid'; - } else if (data.locationCoordinates.length > 2) { - errors.locationCoordinates = 'Should only have latitude and longitude'; - } - - if (typeof data.name === 'undefined' || data.name === '') { - errors.name = 'Is required'; - } else if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } - - if (typeof data.participantsGoal === 'undefined') { - errors.participantsGoal = 'Is required'; - } else if (typeof data.participantsGoal !== 'number') { - errors.participantsGoal = 'Should be a number'; - } else if (!isInt(data.participantsGoal.toString())) { - errors.participantsGoal = 'Should be a integer'; - } - - if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { - errors.poster = 'Should be a string'; - } - - if (typeof data.reviewsGoal === 'undefined') { - errors.reviewsGoal = 'Is required'; - } else if (typeof data.reviewsGoal !== 'number') { - errors.reviewsGoal = 'Should be a number'; - } else if (!isInt(data.reviewsGoal.toString())) { - errors.reviewsGoal = 'Should be a integer'; - } - - let startDateIsValid = false; - if (typeof data.startDate === 'undefined' || data.startDate === '') { - errors.startDate = 'Is required'; - } else if (typeof data.startDate !== 'string') { - errors.startDate = 'Should be a string'; - } else if (!moment(data.startDate).isValid()) { - errors.startDate = 'Should have a ISO-8601 format'; - } else { - const startDate = moment(data.startDate) - .startOf('day') - .utc(); - const today = moment() - .startOf('day') - .utc(); - - if (startDate.isBefore(today)) { - errors.startDate = 'Should be greater than or equal to today'; - } else { - startDateIsValid = true; - } - } - - if ( - typeof data.teamManager !== 'undefined' && - typeof data.teamManager !== 'string' - ) { - errors.teamManager = 'Should be a string'; - } else if (data.teamManager && !isMongoId(data.teamManager)) { - errors.teamManager = 'Should be a valid id'; - } - - if (endDateIsValid && startDateIsValid) { - const endDate = moment(data.endDate) - .endOf('day') - .utc(); - const startDate = moment(data.startDate) - .startOf('day') - .utc(); - - if (startDate.isAfter(endDate)) { - errors.endDate = 'Should be greater than or equal to startDate'; - errors.startDate = 'Should be less than or equal to endDate'; - } else if (endDate.diff(startDate, 'days') > 365) { - errors.endDate = 'Should last less than 365 days'; - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateEditEvent(data) { - const errors = {}; - - if (typeof data.address !== 'undefined') { - if (typeof data.address !== 'string') { - errors.address = 'Should be a string'; - } else if (data.address === '') { - errors.address = 'Is required'; - } - } - - if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' - ) { - errors.description = 'Should be a string'; - } - - let endDateIsValid = false; - if (typeof data.endDate !== 'undefined') { - if (typeof data.endDate !== 'string') { - errors.endDate = 'Should be a string'; - } else if (data.endDate === '') { - errors.endDate = 'Is required'; - } else if (!moment(data.endDate).isValid()) { - errors.endDate = 'Should have a ISO-8601 format'; - } else { - const endDate = moment(data.endDate) - .endOf('day') - .utc(); - const today = moment() - .startOf('day') - .utc(); - - if (endDate.isBefore(today)) { - errors.endDate = 'Should be greater than or equal to today'; - } else { - endDateIsValid = true; - } - } - } - - if ( - typeof data.isOpen !== 'undefined' && - typeof data.isOpen !== 'boolean' - ) { - errors.isOpen = 'Should be a boolean'; - } - - if (typeof data.locationCoordinates !== 'undefined') { - if (!Array.isArray(data.locationCoordinates)) { - errors.locationCoordinates = 'Should be an array'; - } else if (typeof data.locationCoordinates[0] === 'undefined') { - errors.locationCoordinates = 'Latitude is required'; - } else if (!isNumber(data.locationCoordinates[0])) { - errors.locationCoordinates = 'Latitude should be a number'; - } else if ( - parseFloat(data.locationCoordinates[0]) < -90 || - parseFloat(data.locationCoordinates[0]) > 90 - ) { - errors.locationCoordinates = 'Latitude value is not valid'; - } else if (typeof data.locationCoordinates[1] === 'undefined') { - errors.locationCoordinates = 'Longitude is required'; - } else if (!isNumber(data.locationCoordinates[1])) { - errors.locationCoordinates = 'Longitude should be a number'; - } else if ( - parseFloat(data.locationCoordinates[1]) < -180 || - parseFloat(data.locationCoordinates[1]) > 180 - ) { - errors.locationCoordinates = 'Longitude value is not valid'; - } else if (data.locationCoordinates.length > 2) { - errors.locationCoordinates = 'Should only have latitude and longitude'; - } - } - - if (typeof data.managers !== 'undefined') { - if (!Array.isArray(data.managers)) { - errors.managers = 'Should be an array'; - } else { - data.managers.some(m => { - if (typeof m !== 'string') { - errors.managers = 'Should only have string values'; - return true; - } else if (!m) { - errors.managers = 'Should not have empty values'; - return true; - } else { - if (m.startsWith('-')) { - m = m.substring(1); - } - - if (!isMongoId(m)) { - errors.managers = `${m} should be an id`; - return true; - } - } - }); - } - } - - if (typeof data.name !== 'undefined') { - if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } else if (data.name === '') { - errors.name = 'Is required'; - } - } - - if (typeof data.participants !== 'undefined') { - if (!Array.isArray(data.participants)) { - errors.participants = 'Should be an array'; - } else { - data.participants.some(p => { - if (typeof p !== 'string') { - errors.participants = 'Should only have string values'; - return true; - } else if (!p) { - errors.participants = 'Should not have empty values'; - return true; - } else if (!p.startsWith('-')) { - errors.participants = `${p} should start with -`; - return true; - } else if (!isMongoId(p.substring(1))) { - errors.participants = `${p} should be an id`; - return true; - } - }); - } - } - - if (typeof data.participantsGoal !== 'undefined') { - if (data.participantsGoal === null) { - errors.participantsGoal = 'Is required'; - } else if (typeof data.participantsGoal !== 'number') { - errors.participantsGoal = 'Should be a number'; - } else if (!isInt(data.participantsGoal.toString())) { - errors.participantsGoal = 'Should be a integer'; - } - } - - if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { - errors.poster = 'Should be a string'; - } - - if (typeof data.reviewsGoal !== 'undefined') { - if (data.reviewsGoal === null) { - errors.reviewsGoal = 'Is required'; - } else if (typeof data.reviewsGoal !== 'number') { - errors.reviewsGoal = 'Should be a number'; - } else if (!isInt(data.reviewsGoal.toString())) { - errors.reviewsGoal = 'Should be a integer'; - } - } - - let startDateIsValid = false; - if (typeof data.startDate !== 'undefined') { - if (typeof data.startDate !== 'string') { - errors.startDate = 'Should be a string'; - } else if (data.startDate === '') { - errors.startDate = 'Is required'; - } else if (!moment(data.startDate).isValid()) { - errors.startDate = 'Should have a ISO-8601 format'; - } else { - const startDate = moment(data.startDate) - .startOf('day') - .utc(); - const today = moment() - .startOf('day') - .utc(); - - if (startDate.isBefore(today)) { - errors.startDate = 'Should be greater than or equal to today'; - } else { - startDateIsValid = true; - } - } - } - - if ( - typeof data.teamManager !== 'undefined' && - typeof data.teamManager !== 'string' - ) { - errors.teamManager = 'Should be a string'; - } else if (data.teamManager && !isMongoId(data.teamManager)) { - errors.teamManager = 'Should be a valid id'; - } - - if (typeof data.teams !== 'undefined') { - if (!Array.isArray(data.teams)) { - errors.teams = 'Should be an array'; - } else { - data.teams.some(t => { - if (typeof t !== 'string') { - errors.teams = 'Should only have string values'; - return true; - } else if (!t) { - errors.teams = 'Should not have empty values'; - return true; - } else if (!t.startsWith('-')) { - errors.teams = `${t} should start with -`; - return true; - } else if (!isMongoId(t.substring(1))) { - errors.teams = `${t} should be an id`; - return true; - } - }); - } - } - - if (endDateIsValid && startDateIsValid) { - const endDate = moment(data.endDate) - .endOf('day') - .utc(); - const startDate = moment(data.startDate) - .startOf('day') - .utc(); - - if (startDate.isAfter(endDate)) { - errors.endDate = 'Should be greater than or equal to startDate'; - errors.startDate = 'Should be less than or equal to endDate'; - } else if (endDate.diff(startDate, 'days') > 365) { - errors.endDate = 'Should last less than 365 days'; - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateListEvents(queryParams) { - const errors = {}; - - let isAfterDateValid = false; - if ( - queryParams.afterDate && - !moment(queryParams.afterDate, 'YYYY-MM-DD', true).isValid() - ) { - errors.afterDate = 'Should have YYYY-MM-DD format'; - } else { - isAfterDateValid = true; - } - - let isBeforeDateValid = false; - if ( - queryParams.beforeDate && - !moment(queryParams.beforeDate, 'YYYY-MM-DD', true).isValid() - ) { - errors.beforeDate = 'Should have YYYY-MM-DD format'; - } else { - isBeforeDateValid = true; - } - - if (isAfterDateValid && isBeforeDateValid) { - const afterDate = moment(queryParams.afterDate, 'YYYY-MM-DD').utc(); - const beforeDate = moment(queryParams.beforeDate, 'YYYY-MM-DD').utc(); - if (afterDate.isAfter(beforeDate)) { - errors.afterDate = 'Should be less than beforeDate'; - errors.beforeDate = 'Should be greater than afterDate'; - } - } - - const sortOptions = [ - 'name', - '-name', - 'reviewsAmount', - '-reviewsAmount', - 'startDate', - '-startDate' - ]; - if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { - errors.sortBy = 'Should be a valid sort'; - } - - if (queryParams.page) { - if (!isInt(queryParams.page)) { - errors.page = 'Should be a integer'; - } else if (parseInt(queryParams.page, 10) < 1) { - errors.page = 'Should be a positive integer'; - } - } - - if (queryParams.pageLimit) { - if (!isInt(queryParams.pageLimit)) { - errors.pageLimit = 'Should be a integer'; - } else if (parseInt(queryParams.pageLimit, 10) < 1) { - errors.pageLimit = 'Should be a positive integer'; - } else if (parseInt(queryParams.pageLimit, 10) > 12) { - errors.pageLimit = 'Should be less than 13'; - } - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const { isEmpty } = require('lodash'); +const { isInt, isMongoId } = require('validator'); +const moment = require('moment'); + +const { isNumber } = require('../../helpers'); + +module.exports = { + validateCreateEvent(data) { + const errors = {}; + + if (typeof data.address === 'undefined' || data.address === '') { + errors.address = 'Is required'; + } else if (typeof data.address !== 'string') { + errors.address = 'Should be a string'; + } + + if ( + typeof data.description !== 'undefined' && + typeof data.description !== 'string' + ) { + errors.description = 'Should be a string'; + } + + if (data.donationEnabled === true) { + if (typeof data.donationAmounts === 'undefined') { + errors.donationAmounts = 'Is required'; + } + if (typeof data.donationGoal === 'undefined') { + errors.donationGoal = 'Is required'; + } + } + + if (typeof data.donationAmounts !== 'undefined') { + if (!Array.isArray(data.donationAmounts)) { + errors.donationAmounts = 'Should be an array'; + } else { + data.donationAmounts.some((d) => { + if (typeof d.value === 'undefined') { + errors.donationAmounts = + 'All elements should have a value property'; + return true; + } else if (typeof d.value !== 'number') { + errors.donationAmounts = 'All value properties should be numbers'; + return true; + } else if (d < 5 || d > 10000) { + errors.donationAmounts = + 'All value properties should be between 5 and 10000'; + return true; + } + }); + } + } + + if ( + typeof data.donationEnabled !== 'undefined' && + typeof data.donationEnabled !== 'boolean' + ) { + errors.donationEnabled = 'Should be a boolean'; + } + + if (typeof data.donationGoal !== 'undefined') { + if (typeof data.donationGoal !== 'number') { + errors.donationGoal = 'Should be a number'; + } else if (!isInt(data.donationGoal.toString())) { + errors.donationGoal = 'Should be a integer'; + } + } + + let endDateIsValid = false; + if (typeof data.endDate === 'undefined' || data.endDate === '') { + errors.endDate = 'Is required'; + } else if (typeof data.endDate !== 'string') { + errors.endDate = 'Should be a string'; + } else if (!moment(data.endDate).isValid()) { + errors.endDate = 'Should have a ISO-8601 format'; + } else { + const endDate = moment(data.endDate).endOf('day').utc(); + const today = moment().startOf('day').utc(); + + if (endDate.isBefore(today)) { + errors.endDate = 'Should be greater than or equal to today'; + } else { + endDateIsValid = true; + } + } + + if ( + typeof data.isOpen !== 'undefined' && + typeof data.isOpen !== 'boolean' + ) { + errors.isOpen = 'Should be a boolean'; + } + + if (typeof data.locationCoordinates === 'undefined') { + errors.locationCoordinates = 'Is required'; + } else if (!Array.isArray(data.locationCoordinates)) { + errors.locationCoordinates = 'Should be an array'; + } else if (typeof data.locationCoordinates[0] === 'undefined') { + errors.locationCoordinates = 'Latitude is required'; + } else if (!isNumber(data.locationCoordinates[0])) { + errors.locationCoordinates = 'Latitude should be a number'; + } else if ( + parseFloat(data.locationCoordinates[0]) < -90 || + parseFloat(data.locationCoordinates[0]) > 90 + ) { + errors.locationCoordinates = 'Latitude value is not valid'; + } else if (typeof data.locationCoordinates[1] === 'undefined') { + errors.locationCoordinates = 'Longitude is required'; + } else if (!isNumber(data.locationCoordinates[1])) { + errors.locationCoordinates = 'Longitude should be a number'; + } else if ( + parseFloat(data.locationCoordinates[1]) < -180 || + parseFloat(data.locationCoordinates[1]) > 180 + ) { + errors.locationCoordinates = 'Longitude value is not valid'; + } else if (data.locationCoordinates.length > 2) { + errors.locationCoordinates = 'Should only have latitude and longitude'; + } + + if (typeof data.name === 'undefined' || data.name === '') { + errors.name = 'Is required'; + } else if (typeof data.name !== 'string') { + errors.name = 'Should be a string'; + } + + if (typeof data.participantsGoal === 'undefined') { + errors.participantsGoal = 'Is required'; + } else if (typeof data.participantsGoal !== 'number') { + errors.participantsGoal = 'Should be a number'; + } else if (!isInt(data.participantsGoal.toString())) { + errors.participantsGoal = 'Should be a integer'; + } + + if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { + errors.poster = 'Should be a string'; + } + + if (typeof data.reviewsGoal === 'undefined') { + errors.reviewsGoal = 'Is required'; + } else if (typeof data.reviewsGoal !== 'number') { + errors.reviewsGoal = 'Should be a number'; + } else if (!isInt(data.reviewsGoal.toString())) { + errors.reviewsGoal = 'Should be a integer'; + } + + let startDateIsValid = false; + if (typeof data.startDate === 'undefined' || data.startDate === '') { + errors.startDate = 'Is required'; + } else if (typeof data.startDate !== 'string') { + errors.startDate = 'Should be a string'; + } else if (!moment(data.startDate).isValid()) { + errors.startDate = 'Should have a ISO-8601 format'; + } else { + const startDate = moment(data.startDate).startOf('day').utc(); + const today = moment().startOf('day').utc(); + + if (startDate.isBefore(today)) { + errors.startDate = 'Should be greater than or equal to today'; + } else { + startDateIsValid = true; + } + } + + if ( + typeof data.teamManager !== 'undefined' && + typeof data.teamManager !== 'string' + ) { + errors.teamManager = 'Should be a string'; + } else if (data.teamManager && !isMongoId(data.teamManager)) { + errors.teamManager = 'Should be a valid id'; + } + + if (endDateIsValid && startDateIsValid) { + const endDate = moment(data.endDate).endOf('day').utc(); + const startDate = moment(data.startDate).startOf('day').utc(); + + if (startDate.isAfter(endDate)) { + errors.endDate = 'Should be greater than or equal to startDate'; + errors.startDate = 'Should be less than or equal to endDate'; + } else if (endDate.diff(startDate, 'days') > 365) { + errors.endDate = 'Should last less than 365 days'; + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateEditEvent(data) { + const errors = {}; + + if (typeof data.address !== 'undefined') { + if (typeof data.address !== 'string') { + errors.address = 'Should be a string'; + } else if (data.address === '') { + errors.address = 'Is required'; + } + } + + if ( + typeof data.description !== 'undefined' && + typeof data.description !== 'string' + ) { + errors.description = 'Should be a string'; + } + + let endDateIsValid = false; + if (typeof data.endDate !== 'undefined') { + if (typeof data.endDate !== 'string') { + errors.endDate = 'Should be a string'; + } else if (data.endDate === '') { + errors.endDate = 'Is required'; + } else if (!moment(data.endDate).isValid()) { + errors.endDate = 'Should have a ISO-8601 format'; + } else { + const endDate = moment(data.endDate).endOf('day').utc(); + const today = moment().startOf('day').utc(); + + if (endDate.isBefore(today)) { + errors.endDate = 'Should be greater than or equal to today'; + } else { + endDateIsValid = true; + } + } + } + + if ( + typeof data.isOpen !== 'undefined' && + typeof data.isOpen !== 'boolean' + ) { + errors.isOpen = 'Should be a boolean'; + } + + if (typeof data.locationCoordinates !== 'undefined') { + if (!Array.isArray(data.locationCoordinates)) { + errors.locationCoordinates = 'Should be an array'; + } else if (typeof data.locationCoordinates[0] === 'undefined') { + errors.locationCoordinates = 'Latitude is required'; + } else if (!isNumber(data.locationCoordinates[0])) { + errors.locationCoordinates = 'Latitude should be a number'; + } else if ( + parseFloat(data.locationCoordinates[0]) < -90 || + parseFloat(data.locationCoordinates[0]) > 90 + ) { + errors.locationCoordinates = 'Latitude value is not valid'; + } else if (typeof data.locationCoordinates[1] === 'undefined') { + errors.locationCoordinates = 'Longitude is required'; + } else if (!isNumber(data.locationCoordinates[1])) { + errors.locationCoordinates = 'Longitude should be a number'; + } else if ( + parseFloat(data.locationCoordinates[1]) < -180 || + parseFloat(data.locationCoordinates[1]) > 180 + ) { + errors.locationCoordinates = 'Longitude value is not valid'; + } else if (data.locationCoordinates.length > 2) { + errors.locationCoordinates = 'Should only have latitude and longitude'; + } + } + + if (typeof data.managers !== 'undefined') { + if (!Array.isArray(data.managers)) { + errors.managers = 'Should be an array'; + } else { + data.managers.some((m) => { + if (typeof m !== 'string') { + errors.managers = 'Should only have string values'; + return true; + } else if (!m) { + errors.managers = 'Should not have empty values'; + return true; + } else { + if (m.startsWith('-')) { + m = m.substring(1); + } + + if (!isMongoId(m)) { + errors.managers = `${m} should be an id`; + return true; + } + } + }); + } + } + + if (typeof data.name !== 'undefined') { + if (typeof data.name !== 'string') { + errors.name = 'Should be a string'; + } else if (data.name === '') { + errors.name = 'Is required'; + } + } + + if (typeof data.participants !== 'undefined') { + if (!Array.isArray(data.participants)) { + errors.participants = 'Should be an array'; + } else { + data.participants.some((p) => { + if (typeof p !== 'string') { + errors.participants = 'Should only have string values'; + return true; + } else if (!p) { + errors.participants = 'Should not have empty values'; + return true; + } else if (!p.startsWith('-')) { + errors.participants = `${p} should start with -`; + return true; + } else if (!isMongoId(p.substring(1))) { + errors.participants = `${p} should be an id`; + return true; + } + }); + } + } + + if (typeof data.participantsGoal !== 'undefined') { + if (data.participantsGoal === null) { + errors.participantsGoal = 'Is required'; + } else if (typeof data.participantsGoal !== 'number') { + errors.participantsGoal = 'Should be a number'; + } else if (!isInt(data.participantsGoal.toString())) { + errors.participantsGoal = 'Should be a integer'; + } + } + + if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { + errors.poster = 'Should be a string'; + } + + if (typeof data.reviewsGoal !== 'undefined') { + if (data.reviewsGoal === null) { + errors.reviewsGoal = 'Is required'; + } else if (typeof data.reviewsGoal !== 'number') { + errors.reviewsGoal = 'Should be a number'; + } else if (!isInt(data.reviewsGoal.toString())) { + errors.reviewsGoal = 'Should be a integer'; + } + } + + let startDateIsValid = false; + if (typeof data.startDate !== 'undefined') { + if (typeof data.startDate !== 'string') { + errors.startDate = 'Should be a string'; + } else if (data.startDate === '') { + errors.startDate = 'Is required'; + } else if (!moment(data.startDate).isValid()) { + errors.startDate = 'Should have a ISO-8601 format'; + } else { + const startDate = moment(data.startDate).startOf('day').utc(); + const today = moment().startOf('day').utc(); + + if (startDate.isBefore(today)) { + errors.startDate = 'Should be greater than or equal to today'; + } else { + startDateIsValid = true; + } + } + } + + if ( + typeof data.teamManager !== 'undefined' && + typeof data.teamManager !== 'string' + ) { + errors.teamManager = 'Should be a string'; + } else if (data.teamManager && !isMongoId(data.teamManager)) { + errors.teamManager = 'Should be a valid id'; + } + + if (typeof data.teams !== 'undefined') { + if (!Array.isArray(data.teams)) { + errors.teams = 'Should be an array'; + } else { + data.teams.some((t) => { + if (typeof t !== 'string') { + errors.teams = 'Should only have string values'; + return true; + } else if (!t) { + errors.teams = 'Should not have empty values'; + return true; + } else if (!t.startsWith('-')) { + errors.teams = `${t} should start with -`; + return true; + } else if (!isMongoId(t.substring(1))) { + errors.teams = `${t} should be an id`; + return true; + } + }); + } + } + + if (endDateIsValid && startDateIsValid) { + const endDate = moment(data.endDate).endOf('day').utc(); + const startDate = moment(data.startDate).startOf('day').utc(); + + if (startDate.isAfter(endDate)) { + errors.endDate = 'Should be greater than or equal to startDate'; + errors.startDate = 'Should be less than or equal to endDate'; + } else if (endDate.diff(startDate, 'days') > 365) { + errors.endDate = 'Should last less than 365 days'; + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateListEvents(queryParams) { + const errors = {}; + + let isAfterDateValid = false; + if ( + queryParams.afterDate && + !moment(queryParams.afterDate, 'YYYY-MM-DD', true).isValid() + ) { + errors.afterDate = 'Should have YYYY-MM-DD format'; + } else { + isAfterDateValid = true; + } + + let isBeforeDateValid = false; + if ( + queryParams.beforeDate && + !moment(queryParams.beforeDate, 'YYYY-MM-DD', true).isValid() + ) { + errors.beforeDate = 'Should have YYYY-MM-DD format'; + } else { + isBeforeDateValid = true; + } + + if (isAfterDateValid && isBeforeDateValid) { + const afterDate = moment(queryParams.afterDate, 'YYYY-MM-DD').utc(); + const beforeDate = moment(queryParams.beforeDate, 'YYYY-MM-DD').utc(); + if (afterDate.isAfter(beforeDate)) { + errors.afterDate = 'Should be less than beforeDate'; + errors.beforeDate = 'Should be greater than afterDate'; + } + } + + const sortOptions = [ + 'name', + '-name', + 'reviewsAmount', + '-reviewsAmount', + 'startDate', + '-startDate' + ]; + if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { + errors.sortBy = 'Should be a valid sort'; + } + + if (queryParams.page) { + if (!isInt(queryParams.page)) { + errors.page = 'Should be a integer'; + } else if (parseInt(queryParams.page, 10) < 1) { + errors.page = 'Should be a positive integer'; + } + } + + if (queryParams.pageLimit) { + if (!isInt(queryParams.pageLimit)) { + errors.pageLimit = 'Should be a integer'; + } else if (parseInt(queryParams.pageLimit, 10) < 1) { + errors.pageLimit = 'Should be a positive integer'; + } else if (parseInt(queryParams.pageLimit, 10) > 12) { + errors.pageLimit = 'Should be less than 13'; + } + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/index.js b/src/routes/index.js index 702f72e..b7e0aae 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,25 +1,25 @@ -const express = require('express'); - -const auth = require('./auth'); -const events = require('./events'); -const others = require('./others'); -const petitions = require('./petitions'); -const photos = require('./photos'); -const reviews = require('./reviews'); -const teams = require('./teams'); -const users = require('./users'); -const venues = require('./venues'); - -const router = new express.Router(); - -router.use('', others); -router.use('/auth', auth); -router.use('/events', events); -router.use('/petitions', petitions); -router.use('/photos', photos); -router.use('/reviews', reviews); -router.use('/teams', teams); -router.use('/users', users); -router.use('/venues', venues); - -module.exports = router; +const express = require('express'); + +const auth = require('./auth'); +const events = require('./events'); +const others = require('./others'); +const petitions = require('./petitions'); +const photos = require('./photos'); +const reviews = require('./reviews'); +const teams = require('./teams'); +const users = require('./users'); +const venues = require('./venues'); + +const router = new express.Router(); + +router.use('', others); +router.use('/auth', auth); +router.use('/events', events); +router.use('/petitions', petitions); +router.use('/photos', photos); +router.use('/reviews', reviews); +router.use('/teams', teams); +router.use('/users', users); +router.use('/venues', venues); + +module.exports = router; diff --git a/src/routes/others/contact.js b/src/routes/others/contact.js index 73033b7..b0b689e 100644 --- a/src/routes/others/contact.js +++ b/src/routes/others/contact.js @@ -1,37 +1,37 @@ -const { sendEmail } = require('../../helpers'); - -const { validateContact } = require('./validations'); - -module.exports = async (req, res, next) => { - const data = { - email: req.body.email, - message: req.body.message, - name: req.body.name - }; - - const { errors, isValid } = validateContact(data); - if (!isValid) return res.status(400).json(errors); - - const subject = 'Message from Contact Page'; - const htmlContent = ` -

${data.message}

-

-

Name: ${data.name}

-

Email: ${data.email}

- `; - const textContent = ` - ${data.message}\n\n - Name: ${data.name}\n - Email: ${data.email} - `; - const receiversEmails = [process.env.AXSLAB_EMAIL]; - - sendEmail({ - subject, - htmlContent, - textContent, - receiversEmails - }); - - return res.status(200).json({ message: 'Success' }); -}; +const { sendEmail } = require('../../helpers'); + +const { validateContact } = require('./validations'); + +module.exports = async (req, res) => { + const data = { + email: req.body.email, + message: req.body.message, + name: req.body.name + }; + + const { errors, isValid } = validateContact(data); + if (!isValid) return res.status(400).json(errors); + + const subject = 'Message from Contact Page'; + const htmlContent = ` +

${data.message}

+

+

Name: ${data.name}

+

Email: ${data.email}

+ `; + const textContent = ` + ${data.message}\n\n + Name: ${data.name}\n + Email: ${data.email} + `; + const receiversEmails = [process.env.AXSLAB_EMAIL]; + + sendEmail({ + subject, + htmlContent, + textContent, + receiversEmails + }); + + return res.status(200).json({ message: 'Success' }); +}; diff --git a/src/routes/others/index.js b/src/routes/others/index.js index 09034dc..7ad24b6 100644 --- a/src/routes/others/index.js +++ b/src/routes/others/index.js @@ -1,11 +1,11 @@ -const express = require('express'); - -const contact = require('./contact'); -const migrateScores = require('./migrate-scores'); - -const router = new express.Router(); - -router.post('/contact', contact); -router.get('/migrate-scores', migrateScores); - -module.exports = router; +const express = require('express'); + +const contact = require('./contact'); +const migrateScores = require('./migrate-scores'); + +const router = new express.Router(); + +router.post('/contact', contact); +router.get('/migrate-scores', migrateScores); + +module.exports = router; diff --git a/src/routes/others/migrate-scores.js b/src/routes/others/migrate-scores.js index 06820bb..f311206 100644 --- a/src/routes/others/migrate-scores.js +++ b/src/routes/others/migrate-scores.js @@ -2,7 +2,7 @@ const { Venue } = require('../../models/venue'); const { Review } = require('../../models/review'); const { User } = require('../../models/user'); -module.exports = async (req, res, next) => { +module.exports = async (req, res) => { const saveChanges = req.query.save && req.query.save === 'true'; console.log('IN MIGRATE SCORES, SAVING CHANGES: ' + saveChanges); @@ -28,7 +28,7 @@ module.exports = async (req, res, next) => { let venuesProcessed = 0; let pages = 0; while (venuesProcessed < venuesTotalCount) { - timeBlockStart = new Date(); + let timeBlockStart = new Date(); let venueChunk; try { venueChunk = await Venue.find({ @@ -52,8 +52,8 @@ module.exports = async (req, res, next) => { console.log('UNEXPECTED AMOUNT OF VENUES UNCONVERTED FOUND'); } - for (venue of venueChunk) { - for (review of venue.reviews) { + for (const venue of venueChunk) { + for (const review of venue.reviews) { //console.log("reviewID: ", review); let dbReview; @@ -88,6 +88,7 @@ module.exports = async (req, res, next) => { case 4: dbReview.hasWideEntrance = true; venue.hasWideEntrance.yes += 1; + break; case 3: dbReview.hasPortableRamp = true; venue.hasPortableRamp.yes += 1; @@ -111,6 +112,7 @@ module.exports = async (req, res, next) => { venue.hasLoweredSinks.yes += 1; dbReview.hasSupportAroundToilet = true; venue.hasSupportAroundToilet.yes += 1; + break; case 3: dbReview.hasSwingOutDoor = true; venue.hasSwingOutDoor.yes += 1; @@ -201,40 +203,47 @@ module.exports = async (req, res, next) => { } //end venues while-loop try { - reviewsTotalCount = await Review.countDocuments({ + // Count the total number of unconverted reviews + const reviewsTotalCount = await Review.countDocuments({ _isScoreConverted: { $ne: true } }); - } catch (err) { - console.log('Reviews unconverted failed to be counted, error: ', err); - return res.status(404).json(err); - } - console.log('THERE ARE ' + reviewsTotalCount + ' UNCONVERTED REVIEWS'); - - if (reviewsTotalCount > 0) { - let unconvertedReviews; + console.log('THERE ARE ' + reviewsTotalCount + ' UNCONVERTED REVIEWS'); - try { - unconvertedReviews = await Review.find({ - _isScoreConverted: { $ne: true } - }); - } catch (err) { - console.log('Reviews unconverted failed to be found, error: ', err); - return res.status(404).json(err); - } + if (reviewsTotalCount > 0) { + let unconvertedReviews; - for (unconvertedReview of unconvertedReviews) { try { - matchingVenue = await Venue.find({ - reviews: unconvertedReview.id + // Find all unconverted reviews + unconvertedReviews = await Review.find({ + _isScoreConverted: { $ne: true } }); } catch (err) { console.log('Reviews unconverted failed to be found, error: ', err); return res.status(404).json(err); } - console.log('Review ID: ' + unconvertedReview.id); - console.log("Review's venue: " + matchingVenue.id); + for (const unconvertedReview of unconvertedReviews) { + let matchingVenue; + + try { + // Find the venue for each unconverted review + matchingVenue = await Venue.findOne({ + reviews: unconvertedReview.id + }); + } catch (err) { + console.log('Venue search failed, error: ', err); + return res.status(404).json(err); + } + + console.log('Review ID: ' + unconvertedReview.id); + console.log( + "Review's venue: " + (matchingVenue ? matchingVenue.id : 'Not found') + ); + } } + } catch (err) { + console.log('Reviews unconverted count failed, error: ', err); + return res.status(404).json(err); } console.log('FINISHED PROCESSING ALL RECORDS'); diff --git a/src/routes/others/validations.js b/src/routes/others/validations.js index b1a8c92..3663493 100644 --- a/src/routes/others/validations.js +++ b/src/routes/others/validations.js @@ -1,37 +1,37 @@ -const freemail = require('freemail'); -const { isEmail } = require('validator'); -const { isEmpty } = require('lodash'); - -module.exports = { - validateContact(data) { - const errors = {}; - - if (typeof data.email === 'undefined' || data.email === '') { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; - } else if (data.email.length > 254) { - errors.email = 'Should be less than 255 characters'; - } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { - errors.email = 'Should be a valid email'; - } - - if (typeof data.message === 'undefined' || data.message === '') { - errors.message = 'Is required'; - } else if (typeof data.message !== 'string') { - errors.message = 'Should be a string'; - } else if (data.message.length > 300) { - errors.message = 'Should be less than 301 characters'; - } - - if (typeof data.name === 'undefined' || data.name === '') { - errors.name = 'Is required'; - } else if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } else if (data.name.length > 60) { - errors.name = 'Should be less than 61 characters'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const freemail = require('freemail'); +const { isEmail } = require('validator'); +const { isEmpty } = require('lodash'); + +module.exports = { + validateContact(data) { + const errors = {}; + + if (typeof data.email === 'undefined' || data.email === '') { + errors.email = 'Is required'; + } else if (typeof data.email !== 'string') { + errors.email = 'Should be a string'; + } else if (data.email.length > 254) { + errors.email = 'Should be less than 255 characters'; + } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { + errors.email = 'Should be a valid email'; + } + + if (typeof data.message === 'undefined' || data.message === '') { + errors.message = 'Is required'; + } else if (typeof data.message !== 'string') { + errors.message = 'Should be a string'; + } else if (data.message.length > 300) { + errors.message = 'Should be less than 301 characters'; + } + + if (typeof data.name === 'undefined' || data.name === '') { + errors.name = 'Is required'; + } else if (typeof data.name !== 'string') { + errors.name = 'Should be a string'; + } else if (data.name.length > 60) { + errors.name = 'Should be less than 61 characters'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/petitions/create-petition.js b/src/routes/petitions/create-petition.js index 82ba6b7..3e1b5d8 100644 --- a/src/routes/petitions/create-petition.js +++ b/src/routes/petitions/create-petition.js @@ -1,474 +1,474 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -const { validateCreatePetition } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateCreatePetition(req.body); - if (!isValid) return res.status(400).json(errors); - - const data = Object.assign( - {}, - { - event: req.body.event, - message: req.body.message, - team: req.body.team, - type: req.body.type, - user: req.body.user - } - ); - data.sender = req.user.id.toString(); - const today = moment.utc(); - - if (data.type === 'invite-team-event') { - delete data.user; - - let petition; - try { - petition = await Petition.findOne({ - event: data.event, - team: data.team, - type: data.type - }); - } catch (err) { - console.log( - `Petition from event ${data.event} to team ${ - data.team - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'Team already has a pending invitation to event' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - let event; - try { - event = await Event.findOne({ _id: data.event }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at create-petition`); - return next(err); - } - - if (!event) return res.status(404).json({ event: 'Not found' }); - - if (!event.managers.find(m => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (event.teams.find(t => t.toString() === data.team)) { - return res.status(400).json({ - general: 'Team is already participant of event' - }); - } - - const endDate = moment(event.endDate).utc(); - if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); - } - - let team; - try { - team = await Team.findOne({ _id: data.team }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at create-petition`); - return next(err); - } - - if (!team) return res.status(404).json({ general: 'Team not found' }); - } else if (data.type === 'invite-user-event') { - delete data.team; - - let petition; - try { - petition = await Petition.findOne({ - event: data.event, - type: data.type, - user: data.user - }); - } catch (err) { - console.log( - `Petition from event ${data.event} to user ${ - data.user - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'User already has a pending invitation to event' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - if (data.sender === data.user) { - return res.status(400).json({ general: 'User should not be you' }); - } - - let event; - try { - event = await Event.findOne({ _id: data.event }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at create-petition`); - return next(err); - } - - if (!event) return res.status(404).json({ general: 'Event not found' }); - - if (!event.managers.find(m => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (event.participants.find(p => p.toString() === data.user)) { - return res.status(400).json({ - general: 'User is already participant of event' - }); - } - - const endDate = moment(event.endDate).utc(); - if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); - } - - let user; - try { - user = await User.findOne({ _id: data.user }); - } catch (err) { - console.log(`User ${data.user} failed to be found at create-petition`); - return next(err); - } - - if (!user) return res.status(404).json({ general: 'User not found' }); - } else if (data.type === 'invite-user-team') { - delete data.event; - - let petition; - try { - petition = await Petition.findOne({ - team: data.team, - type: data.type, - user: data.user - }); - } catch (err) { - console.log( - `Petition from team ${data.team} to user ${ - data.user - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'User already has a pending invitation to team' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - if (req.sender === data.user) { - return res.status(400).json({ general: 'User should not be you' }); - } - - let team; - try { - team = await Team.findOne({ _id: data.team }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at create-petition`); - return next(err); - } - - if (!team) return res.status(404).json({ general: 'Team not found' }); - - if (!team.managers.find(m => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (team.members.find(m => m.toString() === data.user)) { - return res.status(400).json({ - general: 'User is already member of team' - }); - } - - let user; - try { - user = await User.findOne({ _id: data.user }); - } catch (err) { - console.log(`User ${data.user} failed to be found at create-petition`); - return next(err); - } - - if (!user) return res.status(404).json({ general: 'User not found' }); - } else if (data.type === 'request-team-event') { - delete data.user; - - let petition; - try { - petition = await Petition.findOne({ - event: data.event, - team: data.team, - type: data.type - }); - } catch (err) { - console.log( - `Petition from team ${data.team} to event ${ - data.event - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'Team already has a pending request with event' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - let event; - try { - event = await Event.findOne({ _id: data.event }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at create-petition`); - return next(err); - } - - if (!event) return res.status(404).json({ general: 'Event not found' }); - - if (event.teams.find(t => t.toString() === data.sender)) { - return res.status(400).json({ - general: 'Team is already participant of event ' - }); - } - - const endDate = moment(event.endDate).utc(); - if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); - } - - let team; - try { - team = await Team.findOne({ _id: data.team }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at create-petition`); - return next(err); - } - - if (!team) return res.status(404).json({ general: 'Team not found' }); - - if (!team.managers.find(m => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else if (data.type === 'request-user-event') { - delete data.team; - - let petition; - try { - petition = await Petition.findOne({ - event: data.event, - sender: data.sender, - type: data.type - }); - } catch (err) { - console.log( - `Petition from user ${data.sender} to event ${ - data.event - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'User already have a pending request with event' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - let event; - try { - event = await Event.findOne({ _id: data.event }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at create-petition`); - return next(err); - } - - if (!event) return res.status(404).json({ general: 'Event not found' }); - - if (event.participants.find(p => p.toString() === data.sender)) { - return res.status(400).json({ - general: 'User already is participant of event' - }); - } - - const endDate = moment(event.endDate).utc(); - if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); - } - } else { - // data.type === request-user-team - delete data.event; - - let petition; - try { - petition = await Petition.findOne({ - team: data.team, - sender: data.sender, - type: data.type - }); - } catch (err) { - console.log( - `Petition from user ${data.sender} to team ${ - data.team - } failed to be found at create-petition` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'User already have a pending request with team' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at create-petition` - ); - return next(err); - } - } - - let team; - try { - team = await Team.findOne({ _id: data.team }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at create-petition`); - return next(err); - } - - if (!team) return res.status(404).json({ general: 'Team not found' }); - - if (team.members.find(m => m.toString() === data.sender)) { - return res.status(400).json({ - general: 'User already is member of team' - }); - } - } - - let petition; - try { - petition = await Petition.create(data); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Petition failed to be created at create-petition.\nData: ${JSON.stringify( - data - )}` - ); - return next(err); - } - - const dataResponse = Object.assign( - {}, - { - createdAt: petition.createdAt, - event: petition.event, - message: petition.message, - sender: petition.sender, - state: petition.state, - team: petition.team, - type: petition.type, - user: petition.user - } - ); - return res.status(201).json(dataResponse); -}; +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Petition } = require('../../models/petition'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +const { validateCreatePetition } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateCreatePetition(req.body); + if (!isValid) return res.status(400).json(errors); + + const data = Object.assign( + {}, + { + event: req.body.event, + message: req.body.message, + team: req.body.team, + type: req.body.type, + user: req.body.user + } + ); + data.sender = req.user.id.toString(); + const today = moment.utc(); + + if (data.type === 'invite-team-event') { + delete data.user; + + let petition; + try { + petition = await Petition.findOne({ + event: data.event, + team: data.team, + type: data.type + }); + } catch (err) { + console.log( + `Petition from event ${data.event} to team ${ + data.team + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'Team already has a pending invitation to event' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + let event; + try { + event = await Event.findOne({ _id: data.event }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at create-petition`); + return next(err); + } + + if (!event) return res.status(404).json({ event: 'Not found' }); + + if (!event.managers.find((m) => m.toString() === data.sender)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (event.teams.find((t) => t.toString() === data.team)) { + return res.status(400).json({ + general: 'Team is already participant of event' + }); + } + + const endDate = moment(event.endDate).utc(); + if (endDate.isBefore(today)) { + return res.status(400).json({ general: 'Event has already finished' }); + } + + let team; + try { + team = await Team.findOne({ _id: data.team }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at create-petition`); + return next(err); + } + + if (!team) return res.status(404).json({ general: 'Team not found' }); + } else if (data.type === 'invite-user-event') { + delete data.team; + + let petition; + try { + petition = await Petition.findOne({ + event: data.event, + type: data.type, + user: data.user + }); + } catch (err) { + console.log( + `Petition from event ${data.event} to user ${ + data.user + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'User already has a pending invitation to event' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + if (data.sender === data.user) { + return res.status(400).json({ general: 'User should not be you' }); + } + + let event; + try { + event = await Event.findOne({ _id: data.event }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at create-petition`); + return next(err); + } + + if (!event) return res.status(404).json({ general: 'Event not found' }); + + if (!event.managers.find((m) => m.toString() === data.sender)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (event.participants.find((p) => p.toString() === data.user)) { + return res.status(400).json({ + general: 'User is already participant of event' + }); + } + + const endDate = moment(event.endDate).utc(); + if (endDate.isBefore(today)) { + return res.status(400).json({ general: 'Event has already finished' }); + } + + let user; + try { + user = await User.findOne({ _id: data.user }); + } catch (err) { + console.log(`User ${data.user} failed to be found at create-petition`); + return next(err); + } + + if (!user) return res.status(404).json({ general: 'User not found' }); + } else if (data.type === 'invite-user-team') { + delete data.event; + + let petition; + try { + petition = await Petition.findOne({ + team: data.team, + type: data.type, + user: data.user + }); + } catch (err) { + console.log( + `Petition from team ${data.team} to user ${ + data.user + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'User already has a pending invitation to team' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + if (req.sender === data.user) { + return res.status(400).json({ general: 'User should not be you' }); + } + + let team; + try { + team = await Team.findOne({ _id: data.team }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at create-petition`); + return next(err); + } + + if (!team) return res.status(404).json({ general: 'Team not found' }); + + if (!team.managers.find((m) => m.toString() === data.sender)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (team.members.find((m) => m.toString() === data.user)) { + return res.status(400).json({ + general: 'User is already member of team' + }); + } + + let user; + try { + user = await User.findOne({ _id: data.user }); + } catch (err) { + console.log(`User ${data.user} failed to be found at create-petition`); + return next(err); + } + + if (!user) return res.status(404).json({ general: 'User not found' }); + } else if (data.type === 'request-team-event') { + delete data.user; + + let petition; + try { + petition = await Petition.findOne({ + event: data.event, + team: data.team, + type: data.type + }); + } catch (err) { + console.log( + `Petition from team ${data.team} to event ${ + data.event + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'Team already has a pending request with event' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + let event; + try { + event = await Event.findOne({ _id: data.event }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at create-petition`); + return next(err); + } + + if (!event) return res.status(404).json({ general: 'Event not found' }); + + if (event.teams.find((t) => t.toString() === data.sender)) { + return res.status(400).json({ + general: 'Team is already participant of event ' + }); + } + + const endDate = moment(event.endDate).utc(); + if (endDate.isBefore(today)) { + return res.status(400).json({ general: 'Event has already finished' }); + } + + let team; + try { + team = await Team.findOne({ _id: data.team }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at create-petition`); + return next(err); + } + + if (!team) return res.status(404).json({ general: 'Team not found' }); + + if (!team.managers.find((m) => m.toString() === data.sender)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else if (data.type === 'request-user-event') { + delete data.team; + + let petition; + try { + petition = await Petition.findOne({ + event: data.event, + sender: data.sender, + type: data.type + }); + } catch (err) { + console.log( + `Petition from user ${data.sender} to event ${ + data.event + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'User already have a pending request with event' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + let event; + try { + event = await Event.findOne({ _id: data.event }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at create-petition`); + return next(err); + } + + if (!event) return res.status(404).json({ general: 'Event not found' }); + + if (event.participants.find((p) => p.toString() === data.sender)) { + return res.status(400).json({ + general: 'User already is participant of event' + }); + } + + const endDate = moment(event.endDate).utc(); + if (endDate.isBefore(today)) { + return res.status(400).json({ general: 'Event has already finished' }); + } + } else { + // data.type === request-user-team + delete data.event; + + let petition; + try { + petition = await Petition.findOne({ + team: data.team, + sender: data.sender, + type: data.type + }); + } catch (err) { + console.log( + `Petition from user ${data.sender} to team ${ + data.team + } failed to be found at create-petition` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'User already have a pending request with team' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at create-petition` + ); + return next(err); + } + } + + let team; + try { + team = await Team.findOne({ _id: data.team }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at create-petition`); + return next(err); + } + + if (!team) return res.status(404).json({ general: 'Team not found' }); + + if (team.members.find((m) => m.toString() === data.sender)) { + return res.status(400).json({ + general: 'User already is member of team' + }); + } + } + + let petition; + try { + petition = await Petition.create(data); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Petition failed to be created at create-petition.\nData: ${JSON.stringify( + data + )}` + ); + return next(err); + } + + const dataResponse = Object.assign( + {}, + { + createdAt: petition.createdAt, + event: petition.event, + message: petition.message, + sender: petition.sender, + state: petition.state, + team: petition.team, + type: petition.type, + user: petition.user + } + ); + return res.status(201).json(dataResponse); +}; diff --git a/src/routes/petitions/edit-petition.js b/src/routes/petitions/edit-petition.js index 5537b38..b3adcfa 100644 --- a/src/routes/petitions/edit-petition.js +++ b/src/routes/petitions/edit-petition.js @@ -1,555 +1,557 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -const { validateEditPetition } = require('./validations'); - -module.exports = async (req, res, next) => { - const petitionId = req.params.petitionId; - - let petition; - try { - petition = await Petition.findOne({ _id: petitionId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Petition not found' }); - } - - console.log(`Petition ${petitionId} failed to be found at edit-petition`); - return next(err); - } - - if (!petition) { - return res.status(404).json({ general: 'Petition not found' }); - } - - if (petition.state === 'accepted') { - return res.status(400).json({ general: 'Is already accepted' }); - } - - if (petition.state === 'canceled') { - return res.status(400).json({ general: 'Is already canceled' }); - } - - if (petition.state === 'rejected') { - return res.status(400).json({ general: 'Is already rejected' }); - } - - const { errors, isValid } = validateEditPetition(req.body); - if (!isValid) return res.status(400).json(errors); - - let isSender = false; - - if (petition.sender.toString() === req.user.id) { - isSender = true; - if (req.body.state === 'canceled') { - petition.state = 'canceled'; - } else { - return res.status(400).json({ state: 'Should only be canceled' }); - } - } - - if (petition.type.endsWith('event')) { - let event; - try { - event = await Event.findOne({ _id: petition.event }); - } catch (err) { - console.log( - `Event ${petition.event} failed to be found at edit-petition` - ); - return next(err); - } - - if (!event) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'Event is already removed. Petition was removed' - }); - } - - if (petition.type === 'invite-team-event') { - let team; - try { - team = await Team.findOne({ _id: petition.team }); - } catch (err) { - console.log( - `Team ${petition.team} failed to be found at edit-petition` - ); - return next(err); - } - - if (!team) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'Team is already removed. Petition was removed' - }); - } - - if (event.teams.find(t => t.toString() === team.id)) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: - 'Team is already a participant of event. Petition was removed' - }); - } - - if (isSender) { - if (!event.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else { - if (!team.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - event.teams = [...event.teams, team.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log( - `Event ${event.id} failed to be updated at edit-petition` - ); - return next(err); - } - - team.events = [...team.events, event.id]; - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log( - `Team ${team.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } else if (petition.type === 'invite-user-event') { - if ( - event.participants.find(p => p.toString() === petition.user.toString()) - ) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: - 'User is already a participant of event. Petition was removed' - }); - } - - if (isSender) { - if (!event.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else { - if (petition.user.toString() !== req.user.id) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - event.participants = [...event.participants, req.user.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log( - `Event ${event.id} failed to be updated at edit-petition` - ); - return next(err); - } - - req.user.events = [...req.user.events, event.id]; - req.user.updatedAt = moment.utc().toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log( - `User ${req.user.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } else if (petition.type === 'request-team-event') { - let team; - try { - team = await Team.findOne({ _id: petition.team }); - } catch (err) { - console.log( - `Team ${petition.team} failed to be found at edit-petition` - ); - return next(err); - } - - if (!team) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'Team is already removed. Petition was removed' - }); - } - - if (event.teams.find(t => t.toString() === team.id)) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: - 'Team is already a participant of event. Petition was removed' - }); - } - - if (isSender) { - if (!team.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else { - if (!event.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - event.teams = [...event.teams, team.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log( - `Event ${event.id} failed to be updated at edit-petition` - ); - return next(err); - } - - team.events = [...team.events, event.id]; - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log( - `Team ${team.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } else { - // petition.type === 'request-user-event' - let user; - try { - user = await User.findOne({ _id: petition.sender }); - } catch (err) { - console.log( - `User ${petition.user} failed to be found at edit-petition` - ); - return next(err); - } - - if (!user) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'User is already removed. Petition was removed' - }); - } - - if (event.participants.find(p => p.toString() === user.id)) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: - 'User is already a participant of event. Petition was removed' - }); - } - - if (!isSender) { - if (!event.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - event.participants = [...event.participants, user.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log( - `Event ${event.id} failed to be updated at edit-petition` - ); - return next(err); - } - - user.events = [...user.events, event.id]; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log( - `User ${user.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } - } else { - // petition.type.endsWith('team') - let team; - try { - team = await Team.findOne({ _id: petition.team }); - } catch (err) { - console.log( - `Team ${petition.entityId} failed to be found at edit-petition` - ); - return next(err); - } - - if (!team) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'Team is already removed. Petition was removed' - }); - } - - if (petition.type === 'invite-user-team') { - if (team.members.find(m => m.toString() === petition.user.toString())) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'User is already a member of team. Petition was removed' - }); - } - - if (isSender) { - if (!team.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - } else { - if (petition.user.toString() !== req.user.id) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - team.members = [...team.members, req.user.id]; - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log( - `Team ${team.id} failed to be updated at edit-petition` - ); - return next(err); - } - - req.user.teams = [...req.user.teams, team.id]; - req.user.updatedAt = moment.utc().toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log( - `User ${req.user.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } else { - // petition.type === 'request-user-team' - - let user; - try { - user = await User.findOne({ _id: petition.sender }); - } catch (err) { - console.log( - `User ${petition.senderId} failed to be found at edit-petition` - ); - return next(err); - } - - if (!user) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'User is already removed. Petition was removed' - }); - } - - if (team.members.find(m => m.toString() === user.id)) { - try { - await petition.remove(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be removed at edit-petition` - ); - return next(err); - } - - return res.status(400).json({ - general: 'User is already a member of team. Petition was removed' - }); - } - - if (!isSender) { - if (!team.managers.find(m => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - if (req.body.state === 'accepted') { - team.members = [...team.members, user.id]; - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log( - `Team ${team.id} failed to be updated at edit-petition` - ); - return next(err); - } - - user.teams = [...user.teams, team.id]; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log( - `User ${user.id} failed to be updated at edit-petition` - ); - return next(err); - } - - petition.state = 'accepted'; - } else { - petition.state = 'rejected'; - } - } - } - } - - petition.updatedAt = moment.utc().toDate(); - - try { - await petition.save(); - } catch (err) { - console.log( - `Petition ${petition.id} failed to be updated at edit-petition` - ); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Petition } = require('../../models/petition'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +const { validateEditPetition } = require('./validations'); + +module.exports = async (req, res, next) => { + const petitionId = req.params.petitionId; + + let petition; + try { + petition = await Petition.findOne({ _id: petitionId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Petition not found' }); + } + + console.log(`Petition ${petitionId} failed to be found at edit-petition`); + return next(err); + } + + if (!petition) { + return res.status(404).json({ general: 'Petition not found' }); + } + + if (petition.state === 'accepted') { + return res.status(400).json({ general: 'Is already accepted' }); + } + + if (petition.state === 'canceled') { + return res.status(400).json({ general: 'Is already canceled' }); + } + + if (petition.state === 'rejected') { + return res.status(400).json({ general: 'Is already rejected' }); + } + + const { errors, isValid } = validateEditPetition(req.body); + if (!isValid) return res.status(400).json(errors); + + let isSender = false; + + if (petition.sender.toString() === req.user.id) { + isSender = true; + if (req.body.state === 'canceled') { + petition.state = 'canceled'; + } else { + return res.status(400).json({ state: 'Should only be canceled' }); + } + } + + if (petition.type.endsWith('event')) { + let event; + try { + event = await Event.findOne({ _id: petition.event }); + } catch (err) { + console.log( + `Event ${petition.event} failed to be found at edit-petition` + ); + return next(err); + } + + if (!event) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'Event is already removed. Petition was removed' + }); + } + + if (petition.type === 'invite-team-event') { + let team; + try { + team = await Team.findOne({ _id: petition.team }); + } catch (err) { + console.log( + `Team ${petition.team} failed to be found at edit-petition` + ); + return next(err); + } + + if (!team) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'Team is already removed. Petition was removed' + }); + } + + if (event.teams.find((t) => t.toString() === team.id)) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: + 'Team is already a participant of event. Petition was removed' + }); + } + + if (isSender) { + if (!event.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else { + if (!team.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + event.teams = [...event.teams, team.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log( + `Event ${event.id} failed to be updated at edit-petition` + ); + return next(err); + } + + team.events = [...team.events, event.id]; + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log( + `Team ${team.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } else if (petition.type === 'invite-user-event') { + if ( + event.participants.find( + (p) => p.toString() === petition.user.toString() + ) + ) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: + 'User is already a participant of event. Petition was removed' + }); + } + + if (isSender) { + if (!event.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else { + if (petition.user.toString() !== req.user.id) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + event.participants = [...event.participants, req.user.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log( + `Event ${event.id} failed to be updated at edit-petition` + ); + return next(err); + } + + req.user.events = [...req.user.events, event.id]; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log( + `User ${req.user.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } else if (petition.type === 'request-team-event') { + let team; + try { + team = await Team.findOne({ _id: petition.team }); + } catch (err) { + console.log( + `Team ${petition.team} failed to be found at edit-petition` + ); + return next(err); + } + + if (!team) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'Team is already removed. Petition was removed' + }); + } + + if (event.teams.find((t) => t.toString() === team.id)) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: + 'Team is already a participant of event. Petition was removed' + }); + } + + if (isSender) { + if (!team.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else { + if (!event.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + event.teams = [...event.teams, team.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log( + `Event ${event.id} failed to be updated at edit-petition` + ); + return next(err); + } + + team.events = [...team.events, event.id]; + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log( + `Team ${team.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } else { + // petition.type === 'request-user-event' + let user; + try { + user = await User.findOne({ _id: petition.sender }); + } catch (err) { + console.log( + `User ${petition.user} failed to be found at edit-petition` + ); + return next(err); + } + + if (!user) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'User is already removed. Petition was removed' + }); + } + + if (event.participants.find((p) => p.toString() === user.id)) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: + 'User is already a participant of event. Petition was removed' + }); + } + + if (!isSender) { + if (!event.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + event.participants = [...event.participants, user.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log( + `Event ${event.id} failed to be updated at edit-petition` + ); + return next(err); + } + + user.events = [...user.events, event.id]; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log( + `User ${user.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } + } else { + // petition.type.endsWith('team') + let team; + try { + team = await Team.findOne({ _id: petition.team }); + } catch (err) { + console.log( + `Team ${petition.entityId} failed to be found at edit-petition` + ); + return next(err); + } + + if (!team) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'Team is already removed. Petition was removed' + }); + } + + if (petition.type === 'invite-user-team') { + if (team.members.find((m) => m.toString() === petition.user.toString())) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'User is already a member of team. Petition was removed' + }); + } + + if (isSender) { + if (!team.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + } else { + if (petition.user.toString() !== req.user.id) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + team.members = [...team.members, req.user.id]; + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log( + `Team ${team.id} failed to be updated at edit-petition` + ); + return next(err); + } + + req.user.teams = [...req.user.teams, team.id]; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log( + `User ${req.user.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } else { + // petition.type === 'request-user-team' + + let user; + try { + user = await User.findOne({ _id: petition.sender }); + } catch (err) { + console.log( + `User ${petition.senderId} failed to be found at edit-petition` + ); + return next(err); + } + + if (!user) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'User is already removed. Petition was removed' + }); + } + + if (team.members.find((m) => m.toString() === user.id)) { + try { + await petition.remove(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be removed at edit-petition` + ); + return next(err); + } + + return res.status(400).json({ + general: 'User is already a member of team. Petition was removed' + }); + } + + if (!isSender) { + if (!team.managers.find((m) => m.toString() === req.user.id)) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + if (req.body.state === 'accepted') { + team.members = [...team.members, user.id]; + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log( + `Team ${team.id} failed to be updated at edit-petition` + ); + return next(err); + } + + user.teams = [...user.teams, team.id]; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log( + `User ${user.id} failed to be updated at edit-petition` + ); + return next(err); + } + + petition.state = 'accepted'; + } else { + petition.state = 'rejected'; + } + } + } + } + + petition.updatedAt = moment.utc().toDate(); + + try { + await petition.save(); + } catch (err) { + console.log( + `Petition ${petition.id} failed to be updated at edit-petition` + ); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/petitions/index.js b/src/routes/petitions/index.js index c2de682..fb87cfe 100644 --- a/src/routes/petitions/index.js +++ b/src/routes/petitions/index.js @@ -1,19 +1,19 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const createPetition = require('./create-petition'); -const editPetition = require('./edit-petition'); -const listPetitions = require('./list-petitions'); - -const router = new express.Router(); - -router.get('', isAuthenticated({ isOptional: false }), listPetitions); -router.post('', isAuthenticated({ isOptional: false }), createPetition); -router.put( - '/:petitionId', - isAuthenticated({ isOptional: false }), - editPetition -); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const createPetition = require('./create-petition'); +const editPetition = require('./edit-petition'); +const listPetitions = require('./list-petitions'); + +const router = new express.Router(); + +router.get('', isAuthenticated({ isOptional: false }), listPetitions); +router.post('', isAuthenticated({ isOptional: false }), createPetition); +router.put( + '/:petitionId', + isAuthenticated({ isOptional: false }), + editPetition +); + +module.exports = router; diff --git a/src/routes/petitions/list-petitions.js b/src/routes/petitions/list-petitions.js index 838d0cb..5188a62 100644 --- a/src/routes/petitions/list-petitions.js +++ b/src/routes/petitions/list-petitions.js @@ -1,277 +1,277 @@ -const mongoose = require('mongoose'); - -const { compact } = require('lodash'); -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); -const { Event } = require('../../models/event'); - -module.exports = async (req, res, next) => { - const queryParams = req.query; - const userId = mongoose.Types.ObjectId(req.user.id); - - const petitionsQuery = { - state: { $in: ['accepted', 'pending', 'rejected'] } - }; - - if (queryParams.filter === 'sent') { - petitionsQuery.sender = userId; - } else { - // get the user's events - const getUserEvents = req.user.events.map(e => Event.findOne({ _id: e })); - // get the user's teams - const getUserTeams = req.user.teams.map(t => Team.findOne({ _id: t })); - - let userEvents = []; - let userTeams = []; - try { - userEvents = await Promise.all(getUserEvents); - // remove null values from array - userEvents = compact(userEvents); - userTeams = await Promise.all(getUserTeams); - // remove null values from array - userTeams = compact(userTeams); - } catch (err) { - console.log('Events/Teams failed to be found at list-petitions'); - return next(err); - } - - const managedEvents = []; - userEvents.map(e => { - const eventManagers = e.managers.map(m => m.toString()); - if (eventManagers.includes(req.user.id)) { - managedEvents.push(mongoose.Types.ObjectId(e.id)); - } - }); - - const managedTeams = []; - userTeams.map(t => { - const teamManagers = t.managers.map(m => m.toString()); - if (teamManagers.includes(req.user.id)) { - managedTeams.push(mongoose.Types.ObjectId(t.id)); - } - }); - - petitionsQuery.$or = [ - { - $and: [ - { user: userId }, - { type: { $in: ['invite-user-event', 'invite-user-team'] } } - ] - }, - { - $and: [ - { event: { $in: managedEvents } }, - { type: { $in: ['request-team-event', 'request-user-event'] } } - ] - }, - { - $and: [ - { team: { $in: managedTeams } }, - { type: { $in: ['invite-team-event', 'request-user-team'] } } - ] - } - ]; - } - - const sortBy = '-createdAt'; - - let page = queryParams.page || 1; - const pageLimit = 12; - if (page > 0) { - page -= 1; - } else { - return res - .status(400) - .json({ page: 'Should be equal to or greater than 1' }); - } - - // Fetch data - const aggregateQuery = [ - { - $match: petitionsQuery - }, - { - $sort: { createdAt: -1 } - }, - { - $lookup: { - from: 'events', - let: { event: '$event' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$event'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - name: 1, - poster: 1 - } - } - ], - as: 'event' - } - }, - { - $unwind: { - path: '$event', - preserveNullAndEmptyArrays: true - } - }, - { - $lookup: { - from: 'users', - let: { sender: '$sender' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$sender'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1 - } - } - ], - as: 'sender' - } - }, - { - $unwind: { - path: '$sender', - preserveNullAndEmptyArrays: true - } - }, - { - $lookup: { - from: 'teams', - let: { team: '$team' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$team'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - name: 1 - } - } - ], - as: 'team' - } - }, - { - $unwind: { - path: '$team', - preserveNullAndEmptyArrays: true - } - }, - { - $lookup: { - from: 'users', - let: { user: '$user' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$user'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1 - } - } - ], - as: 'user' - } - }, - { - $unwind: { - path: '$user', - preserveNullAndEmptyArrays: true - } - }, - { - $project: { - _id: 0, - id: '$_id', - createdAt: 1, - event: 1, - message: 1, - sender: 1, - state: 1, - team: 1, - type: 1, - user: 1 - } - } - ]; - - // paginate - aggregateQuery.push( - { - $skip: page * pageLimit - }, - { - $limit: pageLimit - } - ); - - let petitions; - let total; - try { - [petitions, total] = await Promise.all([ - Petition.aggregate(aggregateQuery), - Petition.find(petitionsQuery).count() - ]); - } catch (err) { - console.log('Petitions failed to be found or count at list-petitions'); - return next(err); - } - - let lastPage = Math.ceil(total / pageLimit); - if (lastPage > 0) { - page += 1; - if (page > lastPage) { - return res - .status(400) - .json({ page: `Should be equal to or less than ${lastPage}` }); - } - } else { - page = null; - lastPage = null; - } - - return res.status(200).json({ - page, - lastPage, - pageLimit, - total, - sortBy, - results: petitions - }); -}; +const mongoose = require('mongoose'); + +const { compact } = require('lodash'); +const { Petition } = require('../../models/petition'); +const { Team } = require('../../models/team'); +const { Event } = require('../../models/event'); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + const userId = new mongoose.Types.ObjectId(req.user.id); + + const petitionsQuery = { + state: { $in: ['accepted', 'pending', 'rejected'] } + }; + + if (queryParams.filter === 'sent') { + petitionsQuery.sender = userId; + } else { + // get the user's events + const getUserEvents = req.user.events.map((e) => Event.findOne({ _id: e })); + // get the user's teams + const getUserTeams = req.user.teams.map((t) => Team.findOne({ _id: t })); + + let userEvents = []; + let userTeams = []; + try { + userEvents = await Promise.all(getUserEvents); + // remove null values from array + userEvents = compact(userEvents); + userTeams = await Promise.all(getUserTeams); + // remove null values from array + userTeams = compact(userTeams); + } catch (err) { + console.log('Events/Teams failed to be found at list-petitions'); + return next(err); + } + + const managedEvents = []; + userEvents.map((e) => { + const eventManagers = e.managers.map((m) => m.toString()); + if (eventManagers.includes(req.user.id)) { + managedEvents.push(new mongoose.Types.ObjectId(e.id)); + } + }); + + const managedTeams = []; + userTeams.map((t) => { + const teamManagers = t.managers.map((m) => m.toString()); + if (teamManagers.includes(req.user.id)) { + managedTeams.push(new mongoose.Types.ObjectId(t.id)); + } + }); + + petitionsQuery.$or = [ + { + $and: [ + { user: userId }, + { type: { $in: ['invite-user-event', 'invite-user-team'] } } + ] + }, + { + $and: [ + { event: { $in: managedEvents } }, + { type: { $in: ['request-team-event', 'request-user-event'] } } + ] + }, + { + $and: [ + { team: { $in: managedTeams } }, + { type: { $in: ['invite-team-event', 'request-user-team'] } } + ] + } + ]; + } + + const sortBy = '-createdAt'; + + let page = queryParams.page || 1; + const pageLimit = 12; + if (page > 0) { + page -= 1; + } else { + return res + .status(400) + .json({ page: 'Should be equal to or greater than 1' }); + } + + // Fetch data + const aggregateQuery = [ + { + $match: petitionsQuery + }, + { + $sort: { createdAt: -1 } + }, + { + $lookup: { + from: 'events', + let: { event: '$event' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$event'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + name: 1, + poster: 1 + } + } + ], + as: 'event' + } + }, + { + $unwind: { + path: '$event', + preserveNullAndEmptyArrays: true + } + }, + { + $lookup: { + from: 'users', + let: { sender: '$sender' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$sender'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1 + } + } + ], + as: 'sender' + } + }, + { + $unwind: { + path: '$sender', + preserveNullAndEmptyArrays: true + } + }, + { + $lookup: { + from: 'teams', + let: { team: '$team' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$team'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + name: 1 + } + } + ], + as: 'team' + } + }, + { + $unwind: { + path: '$team', + preserveNullAndEmptyArrays: true + } + }, + { + $lookup: { + from: 'users', + let: { user: '$user' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$user'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1 + } + } + ], + as: 'user' + } + }, + { + $unwind: { + path: '$user', + preserveNullAndEmptyArrays: true + } + }, + { + $project: { + _id: 0, + id: '$_id', + createdAt: 1, + event: 1, + message: 1, + sender: 1, + state: 1, + team: 1, + type: 1, + user: 1 + } + } + ]; + + // paginate + aggregateQuery.push( + { + $skip: page * pageLimit + }, + { + $limit: pageLimit + } + ); + + let petitions; + let total; + try { + [petitions, total] = await Promise.all([ + Petition.aggregate(aggregateQuery), + Petition.countDocuments(petitionsQuery) + ]); + } catch (err) { + console.log('Petitions failed to be found or count at list-petitions'); + return next(err); + } + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + page += 1; + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + + return res.status(200).json({ + page, + lastPage, + pageLimit, + total, + sortBy, + results: petitions + }); +}; diff --git a/src/routes/petitions/validations.js b/src/routes/petitions/validations.js index fe683d3..03d0f2b 100644 --- a/src/routes/petitions/validations.js +++ b/src/routes/petitions/validations.js @@ -1,79 +1,79 @@ -const { isEmpty } = require('lodash'); -const { isMongoId } = require('validator'); - -const { Petition } = require('../../models/petition'); - -module.exports = { - validateCreatePetition(data) { - const errors = {}; - - if (data.event) { - if (typeof data.event !== 'string') { - errors.event = 'Should be a string'; - } else if (!isMongoId(data.event)) { - errors.event = 'Should be a valid id'; - } - } - - if (data.message && typeof data.message !== 'string') { - errors.message = 'Should be a string'; - } - - if (data.team) { - if (typeof data.team !== 'string') { - errors.team = 'Should be a string'; - } else if (!isMongoId(data.team)) { - errors.team = 'Should be a valid id'; - } - } - - const petitionTypes = Petition.schema.path('type').enumValues; - if (!data.type) { - errors.type = 'Is required'; - } else if (typeof data.type !== 'string') { - errors.type = 'Should be a string'; - } else if (!petitionTypes.includes(data.type)) { - errors.type = 'Should be a valid type'; - } else if ( - data.type === 'invite-team-event' || - data.type === 'request-team-event' - ) { - if (!data.event) errors.event = 'Is required'; - if (!data.team) errors.team = 'Is required'; - } else if (data.type === 'invite-user-event') { - if (!data.event) errors.event = 'Is required'; - if (!data.user) errors.user = 'Is required'; - } else if (data.type === 'request-user-event' && !data.event) { - errors.event = 'Is required'; - } else if (data.type === 'invite-user-team') { - if (!data.team) errors.team = 'Is required'; - if (!data.user) errors.user = 'Is required'; - } else if (data.type === 'request-user-team' && !data.team) { - errors.team = 'Is required'; - } - - if (data.user) { - if (typeof data.user !== 'string') { - errors.user = 'Should be a string'; - } else if (!isMongoId(data.user)) { - errors.user = 'Should be a valid id'; - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateEditPetition(data) { - const errors = {}; - - const petitionStates = Petition.schema.path('state').enumValues; - if (!data.state) { - errors.state = 'Is required'; - } else if (!petitionStates.includes(data.state)) { - errors.state = 'Should be a valid state'; - } else if (data.state === 'pending') { - errors.state = 'Should be a different state'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const { isEmpty } = require('lodash'); +const { isMongoId } = require('validator'); + +const { Petition } = require('../../models/petition'); + +module.exports = { + validateCreatePetition(data) { + const errors = {}; + + if (data.event) { + if (typeof data.event !== 'string') { + errors.event = 'Should be a string'; + } else if (!isMongoId(data.event)) { + errors.event = 'Should be a valid id'; + } + } + + if (data.message && typeof data.message !== 'string') { + errors.message = 'Should be a string'; + } + + if (data.team) { + if (typeof data.team !== 'string') { + errors.team = 'Should be a string'; + } else if (!isMongoId(data.team)) { + errors.team = 'Should be a valid id'; + } + } + + const petitionTypes = Petition.schema.path('type').enumValues; + if (!data.type) { + errors.type = 'Is required'; + } else if (typeof data.type !== 'string') { + errors.type = 'Should be a string'; + } else if (!petitionTypes.includes(data.type)) { + errors.type = 'Should be a valid type'; + } else if ( + data.type === 'invite-team-event' || + data.type === 'request-team-event' + ) { + if (!data.event) errors.event = 'Is required'; + if (!data.team) errors.team = 'Is required'; + } else if (data.type === 'invite-user-event') { + if (!data.event) errors.event = 'Is required'; + if (!data.user) errors.user = 'Is required'; + } else if (data.type === 'request-user-event' && !data.event) { + errors.event = 'Is required'; + } else if (data.type === 'invite-user-team') { + if (!data.team) errors.team = 'Is required'; + if (!data.user) errors.user = 'Is required'; + } else if (data.type === 'request-user-team' && !data.team) { + errors.team = 'Is required'; + } + + if (data.user) { + if (typeof data.user !== 'string') { + errors.user = 'Should be a string'; + } else if (!isMongoId(data.user)) { + errors.user = 'Should be a valid id'; + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateEditPetition(data) { + const errors = {}; + + const petitionStates = Petition.schema.path('state').enumValues; + if (!data.state) { + errors.state = 'Is required'; + } else if (!petitionStates.includes(data.state)) { + errors.state = 'Should be a valid state'; + } else if (data.state === 'pending') { + errors.state = 'Should be a different state'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/photos/create-photo.js b/src/routes/photos/create-photo.js index 43fd66d..8db09f7 100644 --- a/src/routes/photos/create-photo.js +++ b/src/routes/photos/create-photo.js @@ -1,115 +1,115 @@ -const fs = require('fs'); -const util = require('util'); - -const aws = require('aws-sdk'); -const jimp = require('jimp'); -const multer = require('multer'); -const randomstring = require('randomstring'); - -const { Photo } = require('../../models/photo'); - -jimp.prototype.getBufferAsync = util.promisify(jimp.prototype.getBuffer); - -module.exports = async (req, res, next) => { - const uploadPhoto = util.promisify( - multer({ - dest: '/tmp', - limits: { fileSize: 8388608 }, - fileFilter: (req, file, cb) => { - if (/^image\/(jpe?g|png)$/i.test(file.mimetype)) { - cb(null, true); - } else { - cb(new Error('Should have .jpeg or .png extension')); - } - } - }).single('photo') - ); - try { - await uploadPhoto(req, res); - } catch (err) { - return res.status(400).json({ photo: err.message }); - } - - if (!req.file) { - return res.status(400).json({ photo: 'Is required' }); - } - - let photoFile; - try { - photoFile = await jimp.read(req.file.path); - } catch (err) { - console.log('Photo failed to be read at create-photo'); - return next(err); - } - - if (req.body.isWide === 'true') { - photoFile.cover(640, 480).quality(85); - } else { - photoFile.cover(400, 400).quality(85); - } - - let photoBuffer; - try { - photoBuffer = await photoFile.getBufferAsync(photoFile.getMIME()); - } catch (err) { - return next(err); - } - - const photoExtension = photoFile.getExtension(); - const photoFileName = `${Date.now()}${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}.${photoExtension}`; - - const s3 = new aws.S3(); - try { - await s3 - .putObject({ - ACL: 'public-read', - Body: photoBuffer, - Bucket: process.env.AWS_S3_BUCKET, - ContentType: photoFile.getMIME(), - Key: `photos/${photoFileName}` - }) - .promise(); - } catch (err) { - console.log('Photo failed to be uploaded at create-photo'); - return next(err); - } - - fs.unlink(req.file.path); - - const photoData = { - fileName: photoFileName, - url: `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/photos/${photoFileName}`, - user: req.user.id - }; - - let photo; - try { - photo = await Photo.create(photoData); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log('Photo failed to be created at create-photo'); - return next(err); - } - - const dataResponse = { - id: photo.id, - fileName: photo.fileName, - url: photo.url, - user: photo.user - }; - return res.status(201).json(dataResponse); -}; +const fs = require('fs'); + +const aws = require('aws-sdk'); +const jimp = require('jimp'); +const multer = require('multer'); +const randomstring = require('randomstring'); + +const { Photo } = require('../../models/photo'); + +const upload = multer({ + dest: '/tmp', + limits: { fileSize: 8388608 }, + fileFilter: (req, file, cb) => { + if (/^image\/(jpe?g|png)$/i.test(file.mimetype)) { + cb(null, true); + } else { + cb(new Error('Should have .jpeg or .png extension')); + } + } +}).single('photo'); + +module.exports = async (req, res, next) => { + upload(req, res, async (err) => { + if (err) { + return res.status(400).json({ photo: err.message }); + } + + if (!req.file) { + return res.status(400).json({ photo: 'Is required' }); + } + + let photoFile; + try { + photoFile = await jimp.read(req.file.path); + } catch (err) { + console.log('Photo failed to be read at create-photo'); + return next(err); + } + + if (req.body.isWide === 'true') { + photoFile.cover(640, 480).quality(85); + } else { + photoFile.cover(400, 400).quality(85); + } + + let photoBuffer; + try { + photoBuffer = await photoFile.getBufferAsync(photoFile.getMIME()); + } catch (err) { + return next(err); + } + + const photoExtension = photoFile.getExtension(); + const photoFileName = `${Date.now()}${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}.${photoExtension}`; + + const s3 = new aws.S3(); + try { + await s3 + .putObject({ + ACL: 'public-read', + Body: photoBuffer, + Bucket: process.env.AWS_S3_BUCKET, + ContentType: photoFile.getMIME(), + Key: `photos/${photoFileName}` + }) + .promise(); + } catch (err) { + console.log('Photo failed to be uploaded at create-photo'); + return next(err); + } + + fs.unlink(req.file.path, (err) => { + if (err) { + console.log('Failed to delete temporary file', err); + } + }); + + const photoData = { + fileName: photoFileName, + url: `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/photos/${photoFileName}`, + user: req.user.id + }; + + let photo; + try { + photo = await Photo.create(photoData); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log('Photo failed to be created at create-photo'); + return next(err); + } + + const dataResponse = { + id: photo.id, + fileName: photo.fileName, + url: photo.url, + user: photo.user + }; + return res.status(201).json(dataResponse); + }); +}; diff --git a/src/routes/photos/delete-photo.js b/src/routes/photos/delete-photo.js index fa78064..a859696 100644 --- a/src/routes/photos/delete-photo.js +++ b/src/routes/photos/delete-photo.js @@ -1,47 +1,47 @@ -const aws = require('aws-sdk'); - -const { Photo } = require('../../models/photo'); - -module.exports = async (req, res, next) => { - const photoFileName = req.params.photoFileName; - - let photo; - try { - photo = await Photo.findOne({ fileName: photoFileName }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Photo not found' }); - } - - console.log(`Photo ${photoFileName} failed to be found at delete-photo`); - return next(err); - } - - if (photo) { - try { - await photo.remove(); - } catch (err) { - console.log( - `Photo ${photoFileName} failed to be deleted at delete-photo` - ); - return next(err); - } - } - - if (!photoFileName.includes('default')) { - const s3 = new aws.S3(); - try { - await s3 - .deleteObject({ - Bucket: process.env.AWS_S3_BUCKET, - Key: `photos/${photoFileName}` - }) - .promise(); - } catch (err) { - console.log('Photo failed to be deleted at delete-photo'); - return next(err); - } - } - - return res.status(204).json({ general: 'Success' }); -}; +const aws = require('aws-sdk'); + +const { Photo } = require('../../models/photo'); + +module.exports = async (req, res, next) => { + const photoFileName = req.params.photoFileName; + + let photo; + try { + photo = await Photo.findOne({ fileName: photoFileName }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Photo not found' }); + } + + console.log(`Photo ${photoFileName} failed to be found at delete-photo`); + return next(err); + } + + if (photo) { + try { + await photo.remove(); + } catch (err) { + console.log( + `Photo ${photoFileName} failed to be deleted at delete-photo` + ); + return next(err); + } + } + + if (!photoFileName.includes('default')) { + const s3 = new aws.S3(); + try { + await s3 + .deleteObject({ + Bucket: process.env.AWS_S3_BUCKET, + Key: `photos/${photoFileName}` + }) + .promise(); + } catch (err) { + console.log('Photo failed to be deleted at delete-photo'); + return next(err); + } + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/photos/index.js b/src/routes/photos/index.js index bd00f27..c1c7280 100644 --- a/src/routes/photos/index.js +++ b/src/routes/photos/index.js @@ -1,17 +1,17 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const createPhoto = require('./create-photo'); -const deletePhoto = require('./delete-photo'); - -const router = new express.Router(); - -router.post('', isAuthenticated({ isOptional: false }), createPhoto); -router.delete( - '/:photoFileName', - isAuthenticated({ isOptional: false }), - deletePhoto -); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const createPhoto = require('./create-photo'); +const deletePhoto = require('./delete-photo'); + +const router = new express.Router(); + +router.post('', isAuthenticated({ isOptional: false }), createPhoto); +router.delete( + '/:photoFileName', + isAuthenticated({ isOptional: false }), + deletePhoto +); + +module.exports = router; diff --git a/src/routes/reviews/ban-review.js b/src/routes/reviews/ban-review.js index 6e97ee9..227507e 100644 --- a/src/routes/reviews/ban-review.js +++ b/src/routes/reviews/ban-review.js @@ -1,39 +1,39 @@ -const moment = require('moment'); - -const { Review } = require('../../models/review'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const reviewId = req.params.reviewId; - - let review; - try { - review = await Review.findOne({ _id: reviewId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Review not found' }); - } - - console.log(`Review ${reviewId} failed to be found at ban-review`); - return next(err); - } - - if (!review) { - return res.status(404).json({ general: 'Review not found' }); - } - - review.isBanned = true; - review.updatedAt = moment.utc().toDate(); - - try { - await review.save(); - } catch (err) { - console.log(`Review ${review.id} failed to be updated at ban-review`); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Review } = require('../../models/review'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const reviewId = req.params.reviewId; + + let review; + try { + review = await Review.findOne({ _id: reviewId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Review not found' }); + } + + console.log(`Review ${reviewId} failed to be found at ban-review`); + return next(err); + } + + if (!review) { + return res.status(404).json({ general: 'Review not found' }); + } + + review.isBanned = true; + review.updatedAt = moment.utc().toDate(); + + try { + await review.save(); + } catch (err) { + console.log(`Review ${review.id} failed to be updated at ban-review`); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/reviews/create-review.js b/src/routes/reviews/create-review.js index ff61b71..7b78f17 100644 --- a/src/routes/reviews/create-review.js +++ b/src/routes/reviews/create-review.js @@ -1,557 +1,555 @@ -const axios = require('axios'); -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Photo } = require('../../models/photo'); -const { Review } = require('../../models/review'); -const { Team } = require('../../models/team'); -const { Venue } = require('../../models/venue'); - -const { validateCreateEditReview } = require('./validations'); -const venueReviewSummary = require('../../helpers/venue-review-summary.js'); - -module.exports = async (req, res, next) => { - console.log('body: ', req.body); - const { errors, isValid } = validateCreateEditReview(req.body); - if (!isValid) return res.status(400).json(errors); - - const data = { - //new expanded fields - hasPermanentRamp: req.body.hasPermanentRamp, - hasPortableRamp: req.body.hasPortableRamp, - hasWideEntrance: req.body.hasWideEntrance, - hasAccessibleTableHeight: req.body.hasAccessibleTableHeight, - hasAccessibleElevator: req.body.hasAccessibleElevator, - hasInteriorRamp: req.body.hasInteriorRamp, - hasSwingOutDoor: req.body.hasSwingOutDoor, - hasLargeStall: req.body.hasLargeStall, - hasSupportAroundToilet: req.body.hasSupportAroundToilet, - hasLoweredSinks: req.body.hasLoweredSinks, - interiorScore: req.body.interiorScore, - _isScoreConverted: true, - - //original fields - allowsGuideDog: req.body.allowsGuideDog, - //bathroomScore: req.body.bathroomScore, - comments: req.body.comments, - //entryScore: req.body.entryScore, - event: req.body.event, - hasParking: req.body.hasParking, - hasSecondEntry: req.body.hasSecondEntry, - hasWellLit: req.body.hasWellLit, - isQuiet: req.body.isQuiet, - isSpacious: req.body.isSpacious, - steps: req.body.steps, - team: req.body.team, - user: req.user.id - }; - - let event; - if (data.event) { - try { - event = await Event.findOne({ _id: data.event, isArchived: false }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at create-review`); - return next(err); - } - - if (!event) { - return res.status(404).json({ event: 'Event not found' }); - } - - if ( - !event.participants.find(p => p.toString() === data.user) && - !event.managers.find(m => m.toString() === data.user) - ) { - return res - .status(400) - .json({ event: 'You are not a participant of this event' }); - } - - const startDate = moment(event.startDate).utc(); - const endDate = moment(event.endDate).utc(); - const today = moment() - .startOf('day') - .utc(); - if (startDate.isAfter(today)) { - return res.status(400).json({ event: 'Event has not started yet' }); - } else if (endDate.isBefore(today)) { - return res.status(400).json({ event: 'Event has already finished' }); - } - } - - let team; - if (data.team) { - try { - team = await Team.findOne({ _id: data.team, isArchived: false }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at create-review`); - return next(err); - } - - if (!team) { - return res.status(404).json({ team: 'Team not found' }); - } - - if ( - !team.members.find(m => m.toString() === data.user) && - !team.managers.find(m => m.toString() === data.user) - ) { - return res - .status(400) - .json({ team: 'You are not a member of this team' }); - } - } - - const placeId = req.body.place; - let venue; - try { - venue = await Venue.findOne({ placeId }); - } catch (err) { - console.log( - `Venue with placeId ${placeId} failed to be found at create-review` - ); - return next(err); - } - - if (!venue) { - let response; - try { - response = await axios.get( - `https://maps.googleapis.com/maps/api/place/details/json?placeid=${placeId}&key=${ - process.env.PLACES_API_KEY - }` - ); - } catch (err) { - console.log( - `Place ${placeId} failed to be found at create-review, after Google search` - ); - return next(err); - } - - const statusResponse = response.data.status; - if (statusResponse !== 'OK') { - return res.status(404).json({ general: 'Place not found' }); - } - - const placeData = response.data.result; - const venueData = { - address: placeData.formatted_address, - location: { - coordinates: [ - placeData.geometry.location.lng, - placeData.geometry.location.lat - ] - }, - name: placeData.name, - placeId, - types: placeData.types - }; - - try { - venue = await Venue.create(venueData); - } catch (err) { - console.log( - `Venue failed to be created at create-review.\nData: ${JSON.stringify( - venueData - )}` - ); - return next(err); - } - } - data.venue = venue.id; - - let review; - try { - review = await Review.create(data); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Review failed to be created at create-review.\nData: ${JSON.stringify( - data - )}` - ); - return next(err); - } - - // Sample review Obj - /* - _isScoreConverted: false, - isBanned: false, - voters: [], - _id: 5e853db2587b2740c501f12e, - hasAccessibleElevator: true, - hasInteriorRamp: true, - hasSwingOutDoor: false, - hasLargeStall: false, - user: 5e14e8584701fb22ade354e9, - venue: 5e3da8d56d958200424ffdfe, - complaints: [], - createdAt: 2020-04-02T01:19:46.508Z, - updatedAt: 2020-04-02T01:19:46.508Z, - __v: 0 - */ - - //subtracts out the 10 standard fields to determine - var reviewedFieldsCount = Object.keys(review.toObject()).length - 10; - req.user.reviewFieldsAmount = - req.user.reviewFieldsAmount + reviewedFieldsCount; - req.user.reviewsAmount = req.user.reviewsAmount + 1; - req.user.updatedAt = moment.utc().toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log( - `User ${ - req.user.id - } failed to be updated at create-review, after updated review count` - ); - return next(err); - } - - if (event) { - event.reviewsAmount = event.reviewsAmount + 1; - event.updatedAt = moment.utc().toDate(); - try { - await event.save(); - } catch (err) { - console.log( - `Event ${event.id} failed to be updated at create-review, after event` - ); - return next(err); - } - } - - if (req.body.photo) { - let photo; - try { - photo = await Photo.findOne({ url: req.body.photo }); - } catch (err) { - console.log( - `Photo ${req.body.photo} failed to be found at create-review` - ); - return next(err); - } - - if (!photo) { - return res.status(404).json({ photo: 'Not found' }); - } - - venue.photos = [...venue.photos, photo.id]; - - try { - await venue.save(); - } catch (err) { - console.log( - `Venue ${venue.id} failed to be updated at create-review, after photos` - ); - return next(err); - } - } - - if (team) { - team.reviewsAmount = team.reviewsAmount + 1; - team.updatedAt = moment.utc().toDate(); - try { - await team.save(); - } catch (err) { - console.log( - `Team ${team.id} failed to be updated at create-review, after team` - ); - return next(err); - } - } - - // - //new expanded fields - // - if (typeof review.hasPermanentRamp !== 'undefined') { - venue.hasPermanentRamp = { - yes: review.hasPermanentRamp - ? venue.hasPermanentRamp.yes + 1 - : venue.hasPermanentRamp.yes, - no: review.hasPermanentRamp - ? venue.hasPermanentRamp.no - : venue.hasPermanentRamp.no + 1 - }; - } - - if (typeof review.hasPortableRamp !== 'undefined') { - venue.hasPortableRamp = { - yes: review.hasPortableRamp - ? venue.hasPortableRamp.yes + 1 - : venue.hasPortableRamp.yes, - no: review.hasPortableRamp - ? venue.hasPortableRamp.no - : venue.hasPortableRamp.no + 1 - }; - } - - if (typeof review.hasWideEntrance !== 'undefined') { - venue.hasWideEntrance = { - yes: review.hasWideEntrance - ? venue.hasWideEntrance.yes + 1 - : venue.hasWideEntrance.yes, - no: review.hasWideEntrance - ? venue.hasWideEntrance.no - : venue.hasWideEntrance.no + 1 - }; - } - - if (typeof review.hasAccessibleTableHeight !== 'undefined') { - venue.hasAccessibleTableHeight = { - yes: review.hasAccessibleTableHeight - ? venue.hasAccessibleTableHeight.yes + 1 - : venue.hasAccessibleTableHeight.yes, - no: review.hasAccessibleTableHeight - ? venue.hasAccessibleTableHeight.no - : venue.hasAccessibleTableHeight.no + 1 - }; - } - - if (typeof review.hasAccessibleElevator !== 'undefined') { - venue.hasAccessibleElevator = { - yes: review.hasAccessibleElevator - ? venue.hasAccessibleElevator.yes + 1 - : venue.hasAccessibleElevator.yes, - no: review.hasAccessibleElevator - ? venue.hasAccessibleElevator.no - : venue.hasAccessibleElevator.no + 1 - }; - } - - if (typeof review.hasInteriorRamp !== 'undefined') { - venue.hasInteriorRamp = { - yes: review.hasInteriorRamp - ? venue.hasInteriorRamp.yes + 1 - : venue.hasInteriorRamp.yes, - no: review.hasInteriorRamp - ? venue.hasInteriorRamp.no - : venue.hasInteriorRamp.no + 1 - }; - } - - if (typeof review.hasSwingOutDoor !== 'undefined') { - venue.hasSwingOutDoor = { - yes: review.hasSwingOutDoor - ? venue.hasSwingOutDoor.yes + 1 - : venue.hasSwingOutDoor.yes, - no: review.hasSwingOutDoor - ? venue.hasSwingOutDoor.no - : venue.hasSwingOutDoor.no + 1 - }; - } - - if (typeof review.hasLargeStall !== 'undefined') { - venue.hasLargeStall = { - yes: review.hasLargeStall - ? venue.hasLargeStall.yes + 1 - : venue.hasLargeStall.yes, - no: review.hasLargeStall - ? venue.hasLargeStall.no - : venue.hasLargeStall.no + 1 - }; - } - - if (typeof review.hasSupportAroundToilet !== 'undefined') { - venue.hasSupportAroundToilet = { - yes: review.hasSupportAroundToilet - ? venue.hasSupportAroundToilet.yes + 1 - : venue.hasSupportAroundToilet.yes, - no: review.hasSupportAroundToilet - ? venue.hasSupportAroundToilet.no - : venue.hasSupportAroundToilet.no + 1 - }; - } - - if (typeof review.hasLoweredSinks !== 'undefined') { - venue.hasLoweredSinks = { - yes: review.hasLoweredSinks - ? venue.hasLoweredSinks.yes + 1 - : venue.hasLoweredSinks.yes, - no: review.hasLoweredSinks - ? venue.hasLoweredSinks.no - : venue.hasLoweredSinks.no + 1 - }; - } - - // - //original fields - // - if (typeof review.allowsGuideDog !== 'undefined') { - venue.allowsGuideDog = { - yes: review.allowsGuideDog - ? venue.allowsGuideDog.yes + 1 - : venue.allowsGuideDog.yes, - no: review.allowsGuideDog - ? venue.allowsGuideDog.no - : venue.allowsGuideDog.no + 1 - }; - } - - /* - if (typeof review.bathroomScore !== 'undefined') { - if (venue.bathroomReviews > 0) { - venue.bathroomScore = - (venue.bathroomScore * venue.bathroomReviews + review.bathroomScore) / - (venue.bathroomReviews + 1); - venue.bathroomReviews += 1; - } else { - venue.bathroomScore = review.bathroomScore; - venue.bathroomReviews = 1; - } - } - - if (venue.entryReviews > 0) { - venue.entryScore = - (venue.entryScore * venue.entryReviews + review.entryScore) / - (venue.entryReviews + 1); - venue.entryReviews += 1; - } else { - venue.entryScore = review.entryScore; - venue.entryReviews = 1; - } - */ - - if (typeof review.hasParking !== 'undefined') { - venue.hasParking = { - yes: review.hasParking ? venue.hasParking.yes + 1 : venue.hasParking.yes, - no: review.hasParking ? venue.hasParking.no : venue.hasParking.no + 1 - }; - } - - if (typeof review.hasSecondEntry !== 'undefined') { - venue.hasSecondEntry = { - yes: review.hasSecondEntry - ? venue.hasSecondEntry.yes + 1 - : venue.hasSecondEntry.yes, - no: review.hasSecondEntry - ? venue.hasSecondEntry.no - : venue.hasSecondEntry.no + 1 - }; - } - - if (typeof review.hasWellLit !== 'undefined') { - venue.hasWellLit = { - yes: review.hasWellLit ? venue.hasWellLit.yes + 1 : venue.hasWellLit.yes, - no: review.hasWellLit ? venue.hasWellLit.no : venue.hasWellLit.no + 1 - }; - } - - if (typeof review.isQuiet !== 'undefined') { - venue.isQuiet = { - yes: review.isQuiet ? venue.isQuiet.yes + 1 : venue.isQuiet.yes, - no: review.isQuiet ? venue.isQuiet.no : venue.isQuiet.no + 1 - }; - } - - if (typeof review.isSpacious !== 'undefined') { - venue.isSpacious = { - yes: review.isSpacious ? venue.isSpacious.yes + 1 : venue.isSpacious.yes, - no: review.isSpacious ? venue.isSpacious.no : venue.isSpacious.no + 1 - }; - } - - venue.reviews = [...venue.reviews, review.id]; - - if (typeof review.steps !== 'undefined') { - venue.steps = { - zero: review.steps === 0 ? venue.steps.zero + 1 : venue.steps.zero, - one: review.steps === 1 ? venue.steps.one + 1 : venue.steps.one, - two: review.steps === 2 ? venue.steps.two + 1 : venue.steps.two, - moreThanTwo: - review.steps === 3 - ? venue.steps.moreThanTwo + 1 - : venue.steps.moreThanTwo - }; - } - - let scoring; - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); - //console.log('entrance score: ', scoring); - venue.entranceScore = scoring.ratingLevel; - venue.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); - //console.log('interior score: ', scoring); - venue.interiorScore = scoring.ratingLevel; - venue.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); - //console.log('restroom score: ', scoring); - venue.restroomScore = scoring.ratingLevel; - venue.restroomGlyphs = scoring.ratingGlyphs; - - venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - venue.entranceScore, - venue.interiorScore, - venue.restroomScore - ); - - //console.log('venue: ', venue); - - try { - await venue.save(); - } catch (err) { - console.log( - `Venue ${venue.id} failed to be updated at create-review, at final step` - ); - return next(err); - } - - const dataResponse = { - //new expanded fields - hasPermanentRamp: review.hasPermanentRamp, - hasPortableRamp: req.body.hasPortableRamp, - hasWideEntrance: review.hasWideEntrance, - hasAccessibleTableHeight: review.hasAccessibleTableHeight, - hasAccessibleElevator: review.hasAccessibleElevator, - hasInteriorRamp: review.hasInteriorRamp, - hasSwingOutDoor: review.hasSwingOutDoor, - hasLargeStall: review.hasLargeStall, - hasSupportAroundToilet: review.hasSupportAroundToilet, - hasLoweredSinks: review.hasLoweredSinks, - - /* - entranceScore: review.entranceScore, - entranceGlyph: review.entryGlyph, - interiorScore: review.interiorScore, - interiorGlyph: review.interiorGlyph, - restroomScore: review.restroomScore, - restroomGlyph: review.restroomGlyph, - */ - - //original fields - id: review.id, - allowsGuideDog: review.allowsGuideDog, - //bathroomScore: review.bathroomScore, - comments: review.comments, - //entryScore: review.entryScore, - event: review.event, - hasParking: review.hasParking, - hasSecondEntry: review.hasSecondEntry, - hasWellLit: review.hasWellLit, - isQuiet: review.isQuiet, - isSpacious: review.isSpacious, - steps: review.steps, - team: review.team, - user: review.user, - userReviewFieldsAmount: req.user.reviewFieldsAmount, - userReviewsAmount: req.user.reviewsAmount, - venue: review.venue - }; - return res.status(201).json(dataResponse); -}; +const axios = require('axios'); +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Photo } = require('../../models/photo'); +const { Review } = require('../../models/review'); +const { Team } = require('../../models/team'); +const { Venue } = require('../../models/venue'); + +const { validateCreateEditReview } = require('./validations'); +const venueReviewSummary = require('../../helpers/venue-review-summary.js'); + +module.exports = async (req, res, next) => { + console.log('body: ', req.body); + const { errors, isValid } = validateCreateEditReview(req.body); + if (!isValid) return res.status(400).json(errors); + + const data = { + //new expanded fields + hasPermanentRamp: req.body.hasPermanentRamp, + hasPortableRamp: req.body.hasPortableRamp, + hasWideEntrance: req.body.hasWideEntrance, + hasAccessibleTableHeight: req.body.hasAccessibleTableHeight, + hasAccessibleElevator: req.body.hasAccessibleElevator, + hasInteriorRamp: req.body.hasInteriorRamp, + hasSwingOutDoor: req.body.hasSwingOutDoor, + hasLargeStall: req.body.hasLargeStall, + hasSupportAroundToilet: req.body.hasSupportAroundToilet, + hasLoweredSinks: req.body.hasLoweredSinks, + interiorScore: req.body.interiorScore, + _isScoreConverted: true, + + //original fields + allowsGuideDog: req.body.allowsGuideDog, + //bathroomScore: req.body.bathroomScore, + comments: req.body.comments, + //entryScore: req.body.entryScore, + event: req.body.event, + hasParking: req.body.hasParking, + hasSecondEntry: req.body.hasSecondEntry, + hasWellLit: req.body.hasWellLit, + isQuiet: req.body.isQuiet, + isSpacious: req.body.isSpacious, + steps: req.body.steps, + team: req.body.team, + user: req.user.id + }; + + let event; + if (data.event) { + try { + event = await Event.findOne({ _id: data.event, isArchived: false }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at create-review`); + return next(err); + } + + if (!event) { + return res.status(404).json({ event: 'Event not found' }); + } + + if ( + !event.participants.find((p) => p.toString() === data.user) && + !event.managers.find((m) => m.toString() === data.user) + ) { + return res + .status(400) + .json({ event: 'You are not a participant of this event' }); + } + + const startDate = moment(event.startDate).utc(); + const endDate = moment(event.endDate).utc(); + const today = moment().startOf('day').utc(); + if (startDate.isAfter(today)) { + return res.status(400).json({ event: 'Event has not started yet' }); + } else if (endDate.isBefore(today)) { + return res.status(400).json({ event: 'Event has already finished' }); + } + } + + let team; + if (data.team) { + try { + team = await Team.findOne({ _id: data.team, isArchived: false }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at create-review`); + return next(err); + } + + if (!team) { + return res.status(404).json({ team: 'Team not found' }); + } + + if ( + !team.members.find((m) => m.toString() === data.user) && + !team.managers.find((m) => m.toString() === data.user) + ) { + return res + .status(400) + .json({ team: 'You are not a member of this team' }); + } + } + + const placeId = req.body.place; + let venue; + try { + venue = await Venue.findOne({ placeId }); + } catch (err) { + console.log( + `Venue with placeId ${placeId} failed to be found at create-review` + ); + return next(err); + } + + if (!venue) { + let response; + try { + response = await axios.get( + `https://maps.googleapis.com/maps/api/place/details/json?placeid=${placeId}&key=${ + process.env.PLACES_API_KEY + }` + ); + } catch (err) { + console.log( + `Place ${placeId} failed to be found at create-review, after Google search` + ); + return next(err); + } + + const statusResponse = response.data.status; + if (statusResponse !== 'OK') { + return res.status(404).json({ general: 'Place not found' }); + } + + const placeData = response.data.result; + const venueData = { + address: placeData.formatted_address, + location: { + coordinates: [ + placeData.geometry.location.lng, + placeData.geometry.location.lat + ] + }, + name: placeData.name, + placeId, + types: placeData.types + }; + + try { + venue = await Venue.create(venueData); + } catch (err) { + console.log( + `Venue failed to be created at create-review.\nData: ${JSON.stringify( + venueData + )}` + ); + return next(err); + } + } + data.venue = venue.id; + + let review; + try { + review = await Review.create(data); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Review failed to be created at create-review.\nData: ${JSON.stringify( + data + )}` + ); + return next(err); + } + + // Sample review Obj + /* + _isScoreConverted: false, + isBanned: false, + voters: [], + _id: 5e853db2587b2740c501f12e, + hasAccessibleElevator: true, + hasInteriorRamp: true, + hasSwingOutDoor: false, + hasLargeStall: false, + user: 5e14e8584701fb22ade354e9, + venue: 5e3da8d56d958200424ffdfe, + complaints: [], + createdAt: 2020-04-02T01:19:46.508Z, + updatedAt: 2020-04-02T01:19:46.508Z, + __v: 0 + */ + + //subtracts out the 10 standard fields to determine + var reviewedFieldsCount = Object.keys(review.toObject()).length - 10; + req.user.reviewFieldsAmount = + req.user.reviewFieldsAmount + reviewedFieldsCount; + req.user.reviewsAmount = req.user.reviewsAmount + 1; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log( + `User ${ + req.user.id + } failed to be updated at create-review, after updated review count` + ); + return next(err); + } + + if (event) { + event.reviewsAmount = event.reviewsAmount + 1; + event.updatedAt = moment.utc().toDate(); + try { + await event.save(); + } catch (err) { + console.log( + `Event ${event.id} failed to be updated at create-review, after event` + ); + return next(err); + } + } + + if (req.body.photo) { + let photo; + try { + photo = await Photo.findOne({ url: req.body.photo }); + } catch (err) { + console.log( + `Photo ${req.body.photo} failed to be found at create-review` + ); + return next(err); + } + + if (!photo) { + return res.status(404).json({ photo: 'Not found' }); + } + + venue.photos = [...venue.photos, photo.id]; + + try { + await venue.save(); + } catch (err) { + console.log( + `Venue ${venue.id} failed to be updated at create-review, after photos` + ); + return next(err); + } + } + + if (team) { + team.reviewsAmount = team.reviewsAmount + 1; + team.updatedAt = moment.utc().toDate(); + try { + await team.save(); + } catch (err) { + console.log( + `Team ${team.id} failed to be updated at create-review, after team` + ); + return next(err); + } + } + + // + //new expanded fields + // + if (typeof review.hasPermanentRamp !== 'undefined') { + venue.hasPermanentRamp = { + yes: review.hasPermanentRamp + ? venue.hasPermanentRamp.yes + 1 + : venue.hasPermanentRamp.yes, + no: review.hasPermanentRamp + ? venue.hasPermanentRamp.no + : venue.hasPermanentRamp.no + 1 + }; + } + + if (typeof review.hasPortableRamp !== 'undefined') { + venue.hasPortableRamp = { + yes: review.hasPortableRamp + ? venue.hasPortableRamp.yes + 1 + : venue.hasPortableRamp.yes, + no: review.hasPortableRamp + ? venue.hasPortableRamp.no + : venue.hasPortableRamp.no + 1 + }; + } + + if (typeof review.hasWideEntrance !== 'undefined') { + venue.hasWideEntrance = { + yes: review.hasWideEntrance + ? venue.hasWideEntrance.yes + 1 + : venue.hasWideEntrance.yes, + no: review.hasWideEntrance + ? venue.hasWideEntrance.no + : venue.hasWideEntrance.no + 1 + }; + } + + if (typeof review.hasAccessibleTableHeight !== 'undefined') { + venue.hasAccessibleTableHeight = { + yes: review.hasAccessibleTableHeight + ? venue.hasAccessibleTableHeight.yes + 1 + : venue.hasAccessibleTableHeight.yes, + no: review.hasAccessibleTableHeight + ? venue.hasAccessibleTableHeight.no + : venue.hasAccessibleTableHeight.no + 1 + }; + } + + if (typeof review.hasAccessibleElevator !== 'undefined') { + venue.hasAccessibleElevator = { + yes: review.hasAccessibleElevator + ? venue.hasAccessibleElevator.yes + 1 + : venue.hasAccessibleElevator.yes, + no: review.hasAccessibleElevator + ? venue.hasAccessibleElevator.no + : venue.hasAccessibleElevator.no + 1 + }; + } + + if (typeof review.hasInteriorRamp !== 'undefined') { + venue.hasInteriorRamp = { + yes: review.hasInteriorRamp + ? venue.hasInteriorRamp.yes + 1 + : venue.hasInteriorRamp.yes, + no: review.hasInteriorRamp + ? venue.hasInteriorRamp.no + : venue.hasInteriorRamp.no + 1 + }; + } + + if (typeof review.hasSwingOutDoor !== 'undefined') { + venue.hasSwingOutDoor = { + yes: review.hasSwingOutDoor + ? venue.hasSwingOutDoor.yes + 1 + : venue.hasSwingOutDoor.yes, + no: review.hasSwingOutDoor + ? venue.hasSwingOutDoor.no + : venue.hasSwingOutDoor.no + 1 + }; + } + + if (typeof review.hasLargeStall !== 'undefined') { + venue.hasLargeStall = { + yes: review.hasLargeStall + ? venue.hasLargeStall.yes + 1 + : venue.hasLargeStall.yes, + no: review.hasLargeStall + ? venue.hasLargeStall.no + : venue.hasLargeStall.no + 1 + }; + } + + if (typeof review.hasSupportAroundToilet !== 'undefined') { + venue.hasSupportAroundToilet = { + yes: review.hasSupportAroundToilet + ? venue.hasSupportAroundToilet.yes + 1 + : venue.hasSupportAroundToilet.yes, + no: review.hasSupportAroundToilet + ? venue.hasSupportAroundToilet.no + : venue.hasSupportAroundToilet.no + 1 + }; + } + + if (typeof review.hasLoweredSinks !== 'undefined') { + venue.hasLoweredSinks = { + yes: review.hasLoweredSinks + ? venue.hasLoweredSinks.yes + 1 + : venue.hasLoweredSinks.yes, + no: review.hasLoweredSinks + ? venue.hasLoweredSinks.no + : venue.hasLoweredSinks.no + 1 + }; + } + + // + //original fields + // + if (typeof review.allowsGuideDog !== 'undefined') { + venue.allowsGuideDog = { + yes: review.allowsGuideDog + ? venue.allowsGuideDog.yes + 1 + : venue.allowsGuideDog.yes, + no: review.allowsGuideDog + ? venue.allowsGuideDog.no + : venue.allowsGuideDog.no + 1 + }; + } + + /* + if (typeof review.bathroomScore !== 'undefined') { + if (venue.bathroomReviews > 0) { + venue.bathroomScore = + (venue.bathroomScore * venue.bathroomReviews + review.bathroomScore) / + (venue.bathroomReviews + 1); + venue.bathroomReviews += 1; + } else { + venue.bathroomScore = review.bathroomScore; + venue.bathroomReviews = 1; + } + } + + if (venue.entryReviews > 0) { + venue.entryScore = + (venue.entryScore * venue.entryReviews + review.entryScore) / + (venue.entryReviews + 1); + venue.entryReviews += 1; + } else { + venue.entryScore = review.entryScore; + venue.entryReviews = 1; + } + */ + + if (typeof review.hasParking !== 'undefined') { + venue.hasParking = { + yes: review.hasParking ? venue.hasParking.yes + 1 : venue.hasParking.yes, + no: review.hasParking ? venue.hasParking.no : venue.hasParking.no + 1 + }; + } + + if (typeof review.hasSecondEntry !== 'undefined') { + venue.hasSecondEntry = { + yes: review.hasSecondEntry + ? venue.hasSecondEntry.yes + 1 + : venue.hasSecondEntry.yes, + no: review.hasSecondEntry + ? venue.hasSecondEntry.no + : venue.hasSecondEntry.no + 1 + }; + } + + if (typeof review.hasWellLit !== 'undefined') { + venue.hasWellLit = { + yes: review.hasWellLit ? venue.hasWellLit.yes + 1 : venue.hasWellLit.yes, + no: review.hasWellLit ? venue.hasWellLit.no : venue.hasWellLit.no + 1 + }; + } + + if (typeof review.isQuiet !== 'undefined') { + venue.isQuiet = { + yes: review.isQuiet ? venue.isQuiet.yes + 1 : venue.isQuiet.yes, + no: review.isQuiet ? venue.isQuiet.no : venue.isQuiet.no + 1 + }; + } + + if (typeof review.isSpacious !== 'undefined') { + venue.isSpacious = { + yes: review.isSpacious ? venue.isSpacious.yes + 1 : venue.isSpacious.yes, + no: review.isSpacious ? venue.isSpacious.no : venue.isSpacious.no + 1 + }; + } + + venue.reviews = [...venue.reviews, review.id]; + + if (typeof review.steps !== 'undefined') { + venue.steps = { + zero: review.steps === 0 ? venue.steps.zero + 1 : venue.steps.zero, + one: review.steps === 1 ? venue.steps.one + 1 : venue.steps.one, + two: review.steps === 2 ? venue.steps.two + 1 : venue.steps.two, + moreThanTwo: + review.steps === 3 + ? venue.steps.moreThanTwo + 1 + : venue.steps.moreThanTwo + }; + } + + let scoring; + //calculate entranceScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); + //console.log('entrance score: ', scoring); + venue.entranceScore = scoring.ratingLevel; + venue.entranceGlyphs = scoring.ratingGlyphs; + + //calculate interiorScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('interior', venue); + //console.log('interior score: ', scoring); + venue.interiorScore = scoring.ratingLevel; + venue.interiorGlyphs = scoring.ratingGlyphs; + + //calculate restroomScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); + //console.log('restroom score: ', scoring); + venue.restroomScore = scoring.ratingLevel; + venue.restroomGlyphs = scoring.ratingGlyphs; + + venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( + venue.entranceScore, + venue.interiorScore, + venue.restroomScore + ); + + //console.log('venue: ', venue); + + try { + await venue.save(); + } catch (err) { + console.log( + `Venue ${venue.id} failed to be updated at create-review, at final step` + ); + return next(err); + } + + const dataResponse = { + //new expanded fields + hasPermanentRamp: review.hasPermanentRamp, + hasPortableRamp: req.body.hasPortableRamp, + hasWideEntrance: review.hasWideEntrance, + hasAccessibleTableHeight: review.hasAccessibleTableHeight, + hasAccessibleElevator: review.hasAccessibleElevator, + hasInteriorRamp: review.hasInteriorRamp, + hasSwingOutDoor: review.hasSwingOutDoor, + hasLargeStall: review.hasLargeStall, + hasSupportAroundToilet: review.hasSupportAroundToilet, + hasLoweredSinks: review.hasLoweredSinks, + + /* + entranceScore: review.entranceScore, + entranceGlyph: review.entryGlyph, + interiorScore: review.interiorScore, + interiorGlyph: review.interiorGlyph, + restroomScore: review.restroomScore, + restroomGlyph: review.restroomGlyph, + */ + + //original fields + id: review.id, + allowsGuideDog: review.allowsGuideDog, + //bathroomScore: review.bathroomScore, + comments: review.comments, + //entryScore: review.entryScore, + event: review.event, + hasParking: review.hasParking, + hasSecondEntry: review.hasSecondEntry, + hasWellLit: review.hasWellLit, + isQuiet: review.isQuiet, + isSpacious: review.isSpacious, + steps: review.steps, + team: review.team, + user: review.user, + userReviewFieldsAmount: req.user.reviewFieldsAmount, + userReviewsAmount: req.user.reviewsAmount, + venue: review.venue + }; + return res.status(201).json(dataResponse); +}; diff --git a/src/routes/reviews/edit-review.js b/src/routes/reviews/edit-review.js index dd59ebf..251c2d5 100644 --- a/src/routes/reviews/edit-review.js +++ b/src/routes/reviews/edit-review.js @@ -1,217 +1,217 @@ -const moment = require('moment'); -const { pick } = require('lodash'); - -const { Event } = require('../../models/event'); -const { Review } = require('../../models/review'); -const { Team } = require('../../models/team'); -const { Venue } = require('../../models/venue'); - -const { validateCreateEditReview } = require('./validations'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const reviewId = req.params.reviewId; - - let review; - try { - review = await Review.findOne({ _id: reviewId }).select( - '-__v -createdAt -updatedAt' - ); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Review not found' }); - } - - console.log(`Review ${reviewId} failed to be found at edit-review`); - return next(err); - } - - if (!review) { - return res.status(404).json({ general: 'Review not found' }); - } - - if (review.user.toString() !== req.user.id) { - return res - .status(423) - .json({ general: 'You cannot edit someone else review' }); - } - - let venue; - try { - venue = await Venue.findOne({ - _id: review.venue.toString(), - isArchived: false - }); - } catch (err) { - console.log( - `Venue ${review.venue.toString()} failed to be found at edit-review` - ); - return next(err); - } - - if (!venue) { - return res.status(404).json({ general: 'Review venue not found' }); - } - - const data = pick(req.body, [ - //new expanded fields - 'hasPermanentRamp', - 'hasPortableRamp', - 'hasWideEntrance', - 'hasAccessibleTableHeight', - 'hasAccessibleElevator', - 'hasInteriorRamp', - 'hasSwingOutDoor', - 'hasLargeStall', - 'hasSupportAroundToilet', - 'hasLoweredSinks', - - //original fields - //'bathroomScore', - 'comments', - //'entryScore', - 'event', - 'guideDog', - 'parking', - 'quiet', - 'ramp', - 'secondEntry', - 'spacious', - 'steps', - 'team', - 'wellLit' - ]); - const { errors, isValid } = validateCreateEditReview(data); - - if (!isValid) { - return res.status(400).json(errors); - } - - //review.bathroomScore = data.bathroomScore || review.bathroomScore; - review.comments = data.comments || review.comments; - //review.entryScore = data.entryScore || review.entryScore; - - if (data.event) { - let event; - try { - event = await Event.findOne({ _id: data.event }); - } catch (err) { - console.log(`Event ${data.event} failed to be found at edit-review`); - return next(err); - } - - if (!event) { - return res.status(404).json({ event: 'Event not found' }); - } - - if (!event.participants.find(p => p.toString() === req.user.id)) { - return res - .status(400) - .json({ event: 'You are not a participant of this event' }); - } - - const startDate = moment(event.startDate).utc(); - const endDate = moment(event.endDate).utc(); - const today = moment.utc(); - if (startDate.isAfter(today)) { - return res.status(400).json({ event: 'Event has not started yet' }); - } else if (endDate.isBefore(today)) { - return res.status(400).json({ event: 'Event has already finished' }); - } - - review.event = data.event; - } - - review.guideDog = data.guideDog || review.guideDog; - review.parking = data.parking || review.parking; - review.quiet = data.quiet || review.quiet; - review.ramp = data.ramp || review.ramp; - review.secondEntry = data.secondEntry || review.secondEntry; - review.spacious = data.spacious || review.spacious; - - //new expanded fields - review.hasPermanentRamp = data.hasPermanentRamp || review.hasPermanentRamp; - review.hasPortableRamp = data.hasPortableRamp || review.hasPortableRamp; - review.hasWideEntrance = data.hasWideEntrance || review.hasWideEntrance; - review.hasAccessibleTableHeight = - data.hasAccessibleTableHeight || review.hasAccessibleTableHeight; - review.hasAccessibleElevator = - data.hasAccessibleElevator || review.hasAccessibleElevator; - review.hasInteriorRamp = data.hasInteriorRamp || review.hasInteriorRamp; - review.hasSwingOutDoor = data.hasSwingOutDoor || review.hasSwingOutDoor; - review.hasLargeStall = data.hasLargeStall || review.hasLargeStall; - review.hasSupportAroundToilet = - data.hasSupportAroundToilet || review.hasSupportAroundToilet; - review.hasLoweredSinks = data.hasLoweredSinks || review.hasLoweredSinks; - - if (data.steps) { - venue.stepsReviews[review.steps] -= 1; - venue.stepsReviews[data.steps] += 1; - review.steps = data.steps; - } - - if (data.team) { - let team; - try { - team = await Team.findOne({ _id: data.team, isArchived: false }); - } catch (err) { - console.log(`Team ${data.team} failed to be found at edit-review`); - return next(err); - } - - if (!team) { - return res.status(404).json({ team: 'Team not found' }); - } - - if (!team.members.find(m => m.toString() === req.user.id)) { - return res - .status(400) - .json({ team: 'You are not a member of this team' }); - } - - review.team = data.team; - } - - review.wellLit = data.wellLit || review.wellLit; - - review.updatedAt = moment.utc().toDate(); - - try { - await review.save(); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log(`Review ${review.id} failed to be updated at edit-review`); - return next(err); - } - - try { - await venue.save(); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log(`Venue ${venue.id} failed to be updated at edit-review`); - return next(err); - } - - return res.status(200).json(review); -}; +const moment = require('moment'); +const { pick } = require('lodash'); + +const { Event } = require('../../models/event'); +const { Review } = require('../../models/review'); +const { Team } = require('../../models/team'); +const { Venue } = require('../../models/venue'); + +const { validateCreateEditReview } = require('./validations'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const reviewId = req.params.reviewId; + + let review; + try { + review = await Review.findOne({ _id: reviewId }).select( + '-__v -createdAt -updatedAt' + ); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Review not found' }); + } + + console.log(`Review ${reviewId} failed to be found at edit-review`); + return next(err); + } + + if (!review) { + return res.status(404).json({ general: 'Review not found' }); + } + + if (review.user.toString() !== req.user.id) { + return res + .status(423) + .json({ general: 'You cannot edit someone else review' }); + } + + let venue; + try { + venue = await Venue.findOne({ + _id: review.venue.toString(), + isArchived: false + }); + } catch (err) { + console.log( + `Venue ${review.venue.toString()} failed to be found at edit-review` + ); + return next(err); + } + + if (!venue) { + return res.status(404).json({ general: 'Review venue not found' }); + } + + const data = pick(req.body, [ + //new expanded fields + 'hasPermanentRamp', + 'hasPortableRamp', + 'hasWideEntrance', + 'hasAccessibleTableHeight', + 'hasAccessibleElevator', + 'hasInteriorRamp', + 'hasSwingOutDoor', + 'hasLargeStall', + 'hasSupportAroundToilet', + 'hasLoweredSinks', + + //original fields + //'bathroomScore', + 'comments', + //'entryScore', + 'event', + 'guideDog', + 'parking', + 'quiet', + 'ramp', + 'secondEntry', + 'spacious', + 'steps', + 'team', + 'wellLit' + ]); + const { errors, isValid } = validateCreateEditReview(data); + + if (!isValid) { + return res.status(400).json(errors); + } + + //review.bathroomScore = data.bathroomScore || review.bathroomScore; + review.comments = data.comments || review.comments; + //review.entryScore = data.entryScore || review.entryScore; + + if (data.event) { + let event; + try { + event = await Event.findOne({ _id: data.event }); + } catch (err) { + console.log(`Event ${data.event} failed to be found at edit-review`); + return next(err); + } + + if (!event) { + return res.status(404).json({ event: 'Event not found' }); + } + + if (!event.participants.find((p) => p.toString() === req.user.id)) { + return res + .status(400) + .json({ event: 'You are not a participant of this event' }); + } + + const startDate = moment(event.startDate).utc(); + const endDate = moment(event.endDate).utc(); + const today = moment.utc(); + if (startDate.isAfter(today)) { + return res.status(400).json({ event: 'Event has not started yet' }); + } else if (endDate.isBefore(today)) { + return res.status(400).json({ event: 'Event has already finished' }); + } + + review.event = data.event; + } + + review.guideDog = data.guideDog || review.guideDog; + review.parking = data.parking || review.parking; + review.quiet = data.quiet || review.quiet; + review.ramp = data.ramp || review.ramp; + review.secondEntry = data.secondEntry || review.secondEntry; + review.spacious = data.spacious || review.spacious; + + //new expanded fields + review.hasPermanentRamp = data.hasPermanentRamp || review.hasPermanentRamp; + review.hasPortableRamp = data.hasPortableRamp || review.hasPortableRamp; + review.hasWideEntrance = data.hasWideEntrance || review.hasWideEntrance; + review.hasAccessibleTableHeight = + data.hasAccessibleTableHeight || review.hasAccessibleTableHeight; + review.hasAccessibleElevator = + data.hasAccessibleElevator || review.hasAccessibleElevator; + review.hasInteriorRamp = data.hasInteriorRamp || review.hasInteriorRamp; + review.hasSwingOutDoor = data.hasSwingOutDoor || review.hasSwingOutDoor; + review.hasLargeStall = data.hasLargeStall || review.hasLargeStall; + review.hasSupportAroundToilet = + data.hasSupportAroundToilet || review.hasSupportAroundToilet; + review.hasLoweredSinks = data.hasLoweredSinks || review.hasLoweredSinks; + + if (data.steps) { + venue.stepsReviews[review.steps] -= 1; + venue.stepsReviews[data.steps] += 1; + review.steps = data.steps; + } + + if (data.team) { + let team; + try { + team = await Team.findOne({ _id: data.team, isArchived: false }); + } catch (err) { + console.log(`Team ${data.team} failed to be found at edit-review`); + return next(err); + } + + if (!team) { + return res.status(404).json({ team: 'Team not found' }); + } + + if (!team.members.find((m) => m.toString() === req.user.id)) { + return res + .status(400) + .json({ team: 'You are not a member of this team' }); + } + + review.team = data.team; + } + + review.wellLit = data.wellLit || review.wellLit; + + review.updatedAt = moment.utc().toDate(); + + try { + await review.save(); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log(`Review ${review.id} failed to be updated at edit-review`); + return next(err); + } + + try { + await venue.save(); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log(`Venue ${venue.id} failed to be updated at edit-review`); + return next(err); + } + + return res.status(200).json(review); +}; diff --git a/src/routes/reviews/flag-review.js b/src/routes/reviews/flag-review.js index a92319d..9de8ce9 100644 --- a/src/routes/reviews/flag-review.js +++ b/src/routes/reviews/flag-review.js @@ -1,50 +1,50 @@ -const moment = require('moment'); -const { pick } = require('lodash'); - -const { Review } = require('../../models/review'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const reviewId = req.params.reviewId; - - let review; - try { - review = await Review.findOne({ _id: reviewId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Review not found' }); - } - - console.log(`Review ${reviewId} failed to be found at flag-review`); - return next(err); - } - - if (!review) { - return res.status(404).json({ general: 'Review not found' }); - } - - const data = pick(req.body, ['comments', 'type']); - - review.complaints = [ - ...review.complaints, - { - comments: data.comments, - type: data.type, - user: req.user.id - } - ]; - - review.updatedAt = moment.utc().toDate(); - - try { - await review.save(); - } catch (err) { - console.log(`Review ${review.id} failed to be updated at flag-review`); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); +const { pick } = require('lodash'); + +const { Review } = require('../../models/review'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const reviewId = req.params.reviewId; + + let review; + try { + review = await Review.findOne({ _id: reviewId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Review not found' }); + } + + console.log(`Review ${reviewId} failed to be found at flag-review`); + return next(err); + } + + if (!review) { + return res.status(404).json({ general: 'Review not found' }); + } + + const data = pick(req.body, ['comments', 'type']); + + review.complaints = [ + ...review.complaints, + { + comments: data.comments, + type: data.type, + user: req.user.id + } + ]; + + review.updatedAt = moment.utc().toDate(); + + try { + await review.save(); + } catch (err) { + console.log(`Review ${review.id} failed to be updated at flag-review`); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/reviews/index.js b/src/routes/reviews/index.js index 8031f89..df1af41 100644 --- a/src/routes/reviews/index.js +++ b/src/routes/reviews/index.js @@ -1,29 +1,29 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const banReview = require('./ban-review'); -const createReview = require('./create-review'); -const editReview = require('./edit-review'); -const flagReview = require('./flag-review'); -const listReviews = require('./list-reviews'); -const voteReview = require('./vote-review'); - -const router = new express.Router(); - -router.get('', isAuthenticated({ isOptional: false }), listReviews); -router.post('', isAuthenticated({ isOptional: false }), createReview); -router.put('/:reviewId', isAuthenticated({ isOptional: false }), editReview); -router.put( - '/:reviewId/vote', - isAuthenticated({ isOptional: false }), - voteReview -); -router.post( - '/:reviewId/flag', - isAuthenticated({ isOptional: false }), - flagReview -); -router.put('/:reviewId/ban', isAuthenticated({ isOptional: false }), banReview); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const banReview = require('./ban-review'); +const createReview = require('./create-review'); +const editReview = require('./edit-review'); +const flagReview = require('./flag-review'); +const listReviews = require('./list-reviews'); +const voteReview = require('./vote-review'); + +const router = new express.Router(); + +router.get('', isAuthenticated({ isOptional: false }), listReviews); +router.post('', isAuthenticated({ isOptional: false }), createReview); +router.put('/:reviewId', isAuthenticated({ isOptional: false }), editReview); +router.put( + '/:reviewId/vote', + isAuthenticated({ isOptional: false }), + voteReview +); +router.post( + '/:reviewId/flag', + isAuthenticated({ isOptional: false }), + flagReview +); +router.put('/:reviewId/ban', isAuthenticated({ isOptional: false }), banReview); + +module.exports = router; diff --git a/src/routes/reviews/list-reviews.js b/src/routes/reviews/list-reviews.js index 9050b45..280601c 100644 --- a/src/routes/reviews/list-reviews.js +++ b/src/routes/reviews/list-reviews.js @@ -1,184 +1,184 @@ -const { toBoolean, toInt } = require('validator'); - -const { Review } = require('../../models/review'); - -const { validateListReviews } = require('./validations'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const queryParams = req.query; - const { errors, isValid } = validateListReviews(queryParams); - - if (!isValid) { - return res.status(400).json(errors); - } - - const reviewsQuery = {}; - - if (queryParams.restroomScore) { - //const limits = queryParams.bathroomScore.split(','); - reviewsQuery.bathroomScore = { $gte: toInt(queryParams.bathroomScore) }; - } - - if (queryParams.entranceScore) { - //const limits = queryParams.entryScore.split(','); - reviewsQuery.entranceScore = { $gte: toInt(queryParams.entranceScore) }; - } - - if (queryParams.event) { - reviewsQuery.event = queryParams.event; - } - - if (queryParams.guideDog) { - reviewsQuery.guideDog = toBoolean(queryParams.guideDog); - } - - if (queryParams.parking) { - reviewsQuery.parking = toBoolean(queryParams.parking); - } - - if (queryParams.quiet) { - reviewsQuery.quiet = toBoolean(queryParams.quiet); - } - - if (queryParams.ramp) { - reviewsQuery.ramp = toBoolean(queryParams.ramp); - } - - if (queryParams.secondEntry) { - reviewsQuery.secondEntry = toBoolean(queryParams.secondEntry); - } - - if (queryParams.spacious) { - reviewsQuery.spacious = toBoolean(queryParams.spacious); - } - - if (queryParams.steps) { - reviewsQuery.steps = toInt(queryParams.steps); - } - - if (queryParams.team) { - reviewsQuery.team = queryParams.team; - } - - if (queryParams.user) { - reviewsQuery.user = queryParams.user; - } - - if (queryParams.venue) { - reviewsQuery.venue = queryParams.venue; - } - - if (queryParams.wellLit) { - reviewsQuery.wellLit = toBoolean(queryParams.wellLit); - } - - // - // new expanded fields - // - if (queryParams.hasPermanentRamp) { - reviewsQuery.hasPermanentRamp = toBoolean(queryParams.hasPermanentRamp); - } - - if (queryParams.hasPortableRamp) { - reviewsQuery.hasPortableRamp = toBoolean(queryParams.hasPortableRamp); - } - - if (queryParams.hasWideEntrance) { - reviewsQuery.hasWideEntrance = toBoolean(queryParams.hasWideEntrance); - } - - if (queryParams.hasAccessibleTableHeight) { - reviewsQuery.hasAccessibleTableHeight = toBoolean( - queryParams.hasAccessibleTableHeight - ); - } - - if (queryParams.hasAccessibleElevator) { - reviewsQuery.hasAccessibleElevator = toBoolean( - queryParams.hasAccessibleElevator - ); - } - - if (queryParams.hasInteriorRamp) { - reviewsQuery.hasInteriorRamp = toBoolean(queryParams.hasInteriorRamp); - } - - if (queryParams.hasSwingOutDoor) { - reviewsQuery.hasSwingOutDoor = toBoolean(queryParams.hasSwingOutDoor); - } - - if (queryParams.hasLargeStall) { - reviewsQuery.hasLargeStall = toBoolean(queryParams.hasLargeStall); - } - - if (queryParams.hasSupportAroundToilet) { - reviewsQuery.hasSupportAroundToilet = toBoolean( - queryParams.hasSupportAroundToilet - ); - } - - if (queryParams.hasLoweredSinks) { - reviewsQuery.hasLoweredSinks = toBoolean(queryParams.hasLoweredSinks); - } - - if (queryParams.interiorScore) { - reviewsQuery.interiorScore = { $gte: toInt(queryParams.interiorScore) }; - } - - let page = queryParams.page || 1; - const pageLimit = 18; - - if (page > 0) { - page -= 1; - } else { - return res - .status(400) - .json({ page: 'Should be equal to or greater than 1' }); - } - - let reviews; - let total; - try { - [reviews, total] = await Promise.all([ - Review.find(reviewsQuery) - .select('-__v -updatedAt -createdAt') - .sort('createdAt') - .skip(page * pageLimit) - .limit(pageLimit), - Review.find(reviewsQuery).count() - ]); - } catch (err) { - console.log('Reviews failed to be found or count at list-reviews'); - return next(err); - } - - let first = `${process.env.API_URL}/reviews?page=1`; - const lastPage = Math.ceil(total / pageLimit); - let last = `${process.env.API_URL}/reviews?page=${lastPage}`; - - if (lastPage > 0) { - page += 1; - if (page > lastPage) { - return res - .status(400) - .json({ page: `Should be equal to or less than ${lastPage}` }); - } - } else { - first = null; - last = null; - page = null; - } - - return res.status(200).json({ - first, - last, - page, - pageLimit, - results: reviews, - total - }); -}; +const { toBoolean, toInt } = require('validator'); + +const { Review } = require('../../models/review'); + +const { validateListReviews } = require('./validations'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const queryParams = req.query; + const { errors, isValid } = validateListReviews(queryParams); + + if (!isValid) { + return res.status(400).json(errors); + } + + const reviewsQuery = {}; + + if (queryParams.restroomScore) { + //const limits = queryParams.bathroomScore.split(','); + reviewsQuery.bathroomScore = { $gte: toInt(queryParams.bathroomScore) }; + } + + if (queryParams.entranceScore) { + //const limits = queryParams.entryScore.split(','); + reviewsQuery.entranceScore = { $gte: toInt(queryParams.entranceScore) }; + } + + if (queryParams.event) { + reviewsQuery.event = queryParams.event; + } + + if (queryParams.guideDog) { + reviewsQuery.guideDog = toBoolean(queryParams.guideDog); + } + + if (queryParams.parking) { + reviewsQuery.parking = toBoolean(queryParams.parking); + } + + if (queryParams.quiet) { + reviewsQuery.quiet = toBoolean(queryParams.quiet); + } + + if (queryParams.ramp) { + reviewsQuery.ramp = toBoolean(queryParams.ramp); + } + + if (queryParams.secondEntry) { + reviewsQuery.secondEntry = toBoolean(queryParams.secondEntry); + } + + if (queryParams.spacious) { + reviewsQuery.spacious = toBoolean(queryParams.spacious); + } + + if (queryParams.steps) { + reviewsQuery.steps = toInt(queryParams.steps); + } + + if (queryParams.team) { + reviewsQuery.team = queryParams.team; + } + + if (queryParams.user) { + reviewsQuery.user = queryParams.user; + } + + if (queryParams.venue) { + reviewsQuery.venue = queryParams.venue; + } + + if (queryParams.wellLit) { + reviewsQuery.wellLit = toBoolean(queryParams.wellLit); + } + + // + // new expanded fields + // + if (queryParams.hasPermanentRamp) { + reviewsQuery.hasPermanentRamp = toBoolean(queryParams.hasPermanentRamp); + } + + if (queryParams.hasPortableRamp) { + reviewsQuery.hasPortableRamp = toBoolean(queryParams.hasPortableRamp); + } + + if (queryParams.hasWideEntrance) { + reviewsQuery.hasWideEntrance = toBoolean(queryParams.hasWideEntrance); + } + + if (queryParams.hasAccessibleTableHeight) { + reviewsQuery.hasAccessibleTableHeight = toBoolean( + queryParams.hasAccessibleTableHeight + ); + } + + if (queryParams.hasAccessibleElevator) { + reviewsQuery.hasAccessibleElevator = toBoolean( + queryParams.hasAccessibleElevator + ); + } + + if (queryParams.hasInteriorRamp) { + reviewsQuery.hasInteriorRamp = toBoolean(queryParams.hasInteriorRamp); + } + + if (queryParams.hasSwingOutDoor) { + reviewsQuery.hasSwingOutDoor = toBoolean(queryParams.hasSwingOutDoor); + } + + if (queryParams.hasLargeStall) { + reviewsQuery.hasLargeStall = toBoolean(queryParams.hasLargeStall); + } + + if (queryParams.hasSupportAroundToilet) { + reviewsQuery.hasSupportAroundToilet = toBoolean( + queryParams.hasSupportAroundToilet + ); + } + + if (queryParams.hasLoweredSinks) { + reviewsQuery.hasLoweredSinks = toBoolean(queryParams.hasLoweredSinks); + } + + if (queryParams.interiorScore) { + reviewsQuery.interiorScore = { $gte: toInt(queryParams.interiorScore) }; + } + + let page = queryParams.page || 1; + const pageLimit = 18; + + if (page > 0) { + page -= 1; + } else { + return res + .status(400) + .json({ page: 'Should be equal to or greater than 1' }); + } + + let reviews; + let total; + try { + [reviews, total] = await Promise.all([ + Review.find(reviewsQuery) + .select('-__v -updatedAt -createdAt') + .sort('createdAt') + .skip(page * pageLimit) + .limit(pageLimit), + Review.find(reviewsQuery).count() + ]); + } catch (err) { + console.log('Reviews failed to be found or count at list-reviews'); + return next(err); + } + + let first = `${process.env.API_URL}/reviews?page=1`; + const lastPage = Math.ceil(total / pageLimit); + let last = `${process.env.API_URL}/reviews?page=${lastPage}`; + + if (lastPage > 0) { + page += 1; + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + first = null; + last = null; + page = null; + } + + return res.status(200).json({ + first, + last, + page, + pageLimit, + results: reviews, + total + }); +}; diff --git a/src/routes/reviews/validations.js b/src/routes/reviews/validations.js index 70ea8cb..5a811de 100644 --- a/src/routes/reviews/validations.js +++ b/src/routes/reviews/validations.js @@ -1,376 +1,376 @@ -const { isEmpty } = require('lodash'); -const { isInt, isMongoId } = require('validator'); - -module.exports = { - validateCreateEditReview(data) { - const errors = {}; - - // - // new expanded fields - // - if ( - typeof data.hasPermanentRamp !== 'undefined' && - typeof data.hasPermanentRamp !== 'boolean' - ) { - errors.hasPermanentRamp = 'Should be a boolean'; - } - - if ( - typeof data.hasPortableRamp !== 'undefined' && - typeof data.hasPortableRamp !== 'boolean' - ) { - errors.hasPortableRamp = 'Should be a boolean'; - } - - if ( - typeof data.hasWideEntrance !== 'undefined' && - typeof data.hasWideEntrance !== 'boolean' - ) { - errors.hasWideEntrance = 'Should be a boolean'; - } - - if ( - typeof data.hasAccessibleTableHeight !== 'undefined' && - typeof data.hasAccessibleTableHeight !== 'boolean' - ) { - errors.hasAccessibleTableHeight = 'Should be a boolean'; - } - - if ( - typeof data.hasAccessibleElevator !== 'undefined' && - typeof data.hasAccessibleElevator !== 'boolean' - ) { - errors.hasAccessibleElevator = 'Should be a boolean'; - } - - if ( - typeof data.hasInteriorRamp !== 'undefined' && - typeof data.hasInteriorRamp !== 'boolean' - ) { - errors.hasInteriorRamp = 'Should be a boolean'; - } - - if ( - typeof data.hasSwingOutDoor !== 'undefined' && - typeof data.hasSwingOutDoor !== 'boolean' - ) { - errors.hasSwingOutDoor = 'Should be a boolean'; - } - - if ( - typeof data.hasLargeStall !== 'undefined' && - typeof data.hasLargeStall !== 'boolean' - ) { - errors.hasLargeStall = 'Should be a boolean'; - } - - if ( - typeof data.hasSupportAroundToilet !== 'undefined' && - typeof data.hasSupportAroundToilet !== 'boolean' - ) { - errors.hasSupportAroundToilet = 'Should be a boolean'; - } - - if ( - typeof data.hasLoweredSinks !== 'undefined' && - typeof data.hasLoweredSinks !== 'boolean' - ) { - errors.hasLoweredSinks = 'Should be a boolean'; - } - - /* - *interiorScore - if (typeof data.interiorScore !== 'undefined') { - if (typeof data.interiorScore !== 'number') { - errors.interiorScore = 'Should be a number'; - } else if (data.interiorScore < 1 || data.interiorScore > 7) { - //Remove required interiorScore - //errors.interiorScore = 'Should be between 1 and 7'; - } - } - */ - - // - //original fields - // - if ( - typeof data.allowsGuideDog !== 'undefined' && - typeof data.allowsGuideDog !== 'boolean' - ) { - errors.allowsGuideDog = 'Should be a boolean'; - } - - /* - * bathroomScore - if (typeof data.bathroomScore !== 'undefined') { - if (typeof data.bathroomScore !== 'number') { - errors.bathroomScore = 'Should be a number'; - } else if (data.bathroomScore < 1 || data.bathroomScore > 4) { - //Remove required entryScore - //errors.bathroomScore = 'Should be between 1 and 4'; - } - } - */ - - if (data.comments && typeof data.comments !== 'string') { - errors.comments = 'Should be a string'; - } - - /* - * entryScore - if (typeof data.entryScore === 'undefined') { - //Remove required entryScore - //errors.entryScore = 'Is required'; - } else if (typeof data.entryScore !== 'number') { - errors.entryScore = 'Should be a number'; - } else if (data.entryScore < 1 || data.entryScore > 9) { - //Remove required entryScore - //errors.entryScore = 'Should be between 1 and 9'; - } - */ - - if (data.event) { - if (typeof data.event !== 'string') { - errors.event = 'Should be a string'; - } else if (!isMongoId(data.event)) { - errors.event = 'Should be a valid id'; - } - } - - if ( - typeof data.hasParking !== 'undefined' && - typeof data.hasParking !== 'boolean' - ) { - errors.hasParking = 'Should be a boolean'; - } - - if ( - typeof data.hasSecondEntry !== 'undefined' && - typeof data.hasSecondEntry !== 'boolean' - ) { - errors.hasSecondEntry = 'Should be a boolean'; - } - - if ( - typeof data.hasWellLit !== 'undefined' && - typeof data.hasWellLit !== 'boolean' - ) { - errors.hasWellLit = 'Should be a boolean'; - } - - if ( - typeof data.isQuiet !== 'undefined' && - typeof data.isQuiet !== 'boolean' - ) { - errors.isQuiet = 'Should be a boolean'; - } - - if ( - typeof data.isSpacious !== 'undefined' && - typeof data.isSpacious !== 'boolean' - ) { - errors.isSpacious = 'Should be a boolean'; - } - - if (typeof data.photo !== 'undefined' && typeof data.photo !== 'string') { - errors.photo = 'Should be a string'; - } - - if (!data.place) { - errors.place = 'Is required'; - } else if (typeof data.place !== 'string') { - errors.place = 'Should be a string'; - } - - if (typeof data.steps !== 'undefined') { - if (typeof data.steps !== 'number') { - errors.steps = 'Should be a number'; - } else if (data.steps < 0 || data.steps > 3) { - errors.steps = 'Should be between 0 and 3'; - } - } - - if (data.team) { - if (typeof data.team !== 'string') { - errors.team = 'Should be a string'; - } else if (!isMongoId(data.team)) { - errors.team = 'Should be a valid id'; - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateListReviews(queryParams) { - const errors = {}; - - //Remove bathroomScore validation - if (queryParams.bathroomScore) { - /* - const limits = queryParams.bathroomScore.split(','); - - if (limits.length !== 2) { - errors.bathroomScore = 'Should be two integers split by a comma'; - } else if ( - !isInt(limits[0], { min: 1, max: 4 }) || - !isInt(limits[1], { min: 1, max: 4 }) - ) { - errors.bathroomScore = 'Both should be integers between 1 and 4'; - } - */ - } - - //Remove entryScore validation - if (queryParams.entryScore) { - /* - const limits = queryParams.entryScore.split(','); - - if (limits.length !== 2) { - errors.entryScore = 'Should be two integers split by a comma'; - } else if ( - !isInt(limits[0], { min: 1, max: 9 }) || - !isInt(limits[1], { min: 1, max: 9 }) - ) { - errors.entryScore = 'Both should be integers between 1 and 9'; - } - */ - } - - if (queryParams.event && !isMongoId(queryParams.event)) { - errors.event = 'Should be a valid Id'; - } - - if ( - queryParams.guideDog && - !isInt(queryParams.guideDog, { min: 0, max: 1 }) - ) { - errors.guideDog = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.parking && - !isInt(queryParams.parking, { min: 0, max: 1 }) - ) { - errors.parking = 'Should be an integer between 0 and 1'; - } - - if (queryParams.quiet && !isInt(queryParams.quiet, { min: 0, max: 1 })) { - errors.quiet = 'Should be an integer between 0 and 1'; - } - - if (queryParams.ramp && !isInt(queryParams.ramp, { min: 0, max: 1 })) { - errors.ramp = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.secondEntry && - !isInt(queryParams.secondEntry, { min: 0, max: 1 }) - ) { - errors.secondEntry = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.spacious && - !isInt(queryParams.spacious, { min: 0, max: 1 }) - ) { - errors.spacious = 'Should be an integer between 0 and 1'; - } - - if (queryParams.steps && !isInt(queryParams.steps, { min: 0, max: 3 })) { - errors.steps = 'Should be an integer between 0 and 3'; - } - - if (queryParams.team && !isMongoId(queryParams.team)) { - errors.team = 'Should be a valid Id'; - } - - if (queryParams.user && !isMongoId(queryParams.user)) { - errors.user = 'Should be a valid Id'; - } - - if (queryParams.venue && !isMongoId(queryParams.venue)) { - errors.venue = 'Should be a valid Id'; - } - - if ( - queryParams.wellLit && - !isInt(queryParams.wellLit, { min: 0, max: 1 }) - ) { - errors.wellLit = 'Should be an integer between 0 and 1'; - } - - // - // new expanded fields - // - if ( - queryParams.hasPermanentRamp && - !isInt(queryParams.hasPermanentRamp, { min: 0, max: 1 }) - ) { - errors.hasPermanentRamp = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasPortableRamp && - !isInt(queryParams.hasPortableRamp, { min: 0, max: 1 }) - ) { - errors.hasPortableRamp = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasWideEntrance && - !isInt(queryParams.hasWideEntrance, { min: 0, max: 1 }) - ) { - errors.hasWideEntrance = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasAccessibleTableHeight && - !isInt(queryParams.hasAccessibleTableHeight, { min: 0, max: 1 }) - ) { - errors.hasAccessibleTableHeight = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasAccessibleElevator && - !isInt(queryParams.hasAccessibleElevator, { min: 0, max: 1 }) - ) { - errors.hasAccessibleElevator = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasInteriorRamp && - !isInt(queryParams.hasInteriorRamp, { min: 0, max: 1 }) - ) { - errors.hasInteriorRamp = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasSwingOutDoor && - !isInt(queryParams.hasSwingOutDoor, { min: 0, max: 1 }) - ) { - errors.hasSwingOutDoor = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasLargeStall && - !isInt(queryParams.hasLargeStall, { min: 0, max: 1 }) - ) { - errors.hasLargeStall = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasSupportAroundToilet && - !isInt(queryParams.hasSupportAroundToilet, { min: 0, max: 1 }) - ) { - errors.hasSupportAroundToilet = 'Should be an integer between 0 and 1'; - } - - if ( - queryParams.hasLoweredSinks && - !isInt(queryParams.hasLoweredSinks, { min: 0, max: 1 }) - ) { - errors.hasLoweredSinks = 'Should be an integer between 0 and 1'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const { isEmpty } = require('lodash'); +const { isInt, isMongoId } = require('validator'); + +module.exports = { + validateCreateEditReview(data) { + const errors = {}; + + // + // new expanded fields + // + if ( + typeof data.hasPermanentRamp !== 'undefined' && + typeof data.hasPermanentRamp !== 'boolean' + ) { + errors.hasPermanentRamp = 'Should be a boolean'; + } + + if ( + typeof data.hasPortableRamp !== 'undefined' && + typeof data.hasPortableRamp !== 'boolean' + ) { + errors.hasPortableRamp = 'Should be a boolean'; + } + + if ( + typeof data.hasWideEntrance !== 'undefined' && + typeof data.hasWideEntrance !== 'boolean' + ) { + errors.hasWideEntrance = 'Should be a boolean'; + } + + if ( + typeof data.hasAccessibleTableHeight !== 'undefined' && + typeof data.hasAccessibleTableHeight !== 'boolean' + ) { + errors.hasAccessibleTableHeight = 'Should be a boolean'; + } + + if ( + typeof data.hasAccessibleElevator !== 'undefined' && + typeof data.hasAccessibleElevator !== 'boolean' + ) { + errors.hasAccessibleElevator = 'Should be a boolean'; + } + + if ( + typeof data.hasInteriorRamp !== 'undefined' && + typeof data.hasInteriorRamp !== 'boolean' + ) { + errors.hasInteriorRamp = 'Should be a boolean'; + } + + if ( + typeof data.hasSwingOutDoor !== 'undefined' && + typeof data.hasSwingOutDoor !== 'boolean' + ) { + errors.hasSwingOutDoor = 'Should be a boolean'; + } + + if ( + typeof data.hasLargeStall !== 'undefined' && + typeof data.hasLargeStall !== 'boolean' + ) { + errors.hasLargeStall = 'Should be a boolean'; + } + + if ( + typeof data.hasSupportAroundToilet !== 'undefined' && + typeof data.hasSupportAroundToilet !== 'boolean' + ) { + errors.hasSupportAroundToilet = 'Should be a boolean'; + } + + if ( + typeof data.hasLoweredSinks !== 'undefined' && + typeof data.hasLoweredSinks !== 'boolean' + ) { + errors.hasLoweredSinks = 'Should be a boolean'; + } + + /* + *interiorScore + if (typeof data.interiorScore !== 'undefined') { + if (typeof data.interiorScore !== 'number') { + errors.interiorScore = 'Should be a number'; + } else if (data.interiorScore < 1 || data.interiorScore > 7) { + //Remove required interiorScore + //errors.interiorScore = 'Should be between 1 and 7'; + } + } + */ + + // + //original fields + // + if ( + typeof data.allowsGuideDog !== 'undefined' && + typeof data.allowsGuideDog !== 'boolean' + ) { + errors.allowsGuideDog = 'Should be a boolean'; + } + + /* + * bathroomScore + if (typeof data.bathroomScore !== 'undefined') { + if (typeof data.bathroomScore !== 'number') { + errors.bathroomScore = 'Should be a number'; + } else if (data.bathroomScore < 1 || data.bathroomScore > 4) { + //Remove required entryScore + //errors.bathroomScore = 'Should be between 1 and 4'; + } + } + */ + + if (data.comments && typeof data.comments !== 'string') { + errors.comments = 'Should be a string'; + } + + /* + * entryScore + if (typeof data.entryScore === 'undefined') { + //Remove required entryScore + //errors.entryScore = 'Is required'; + } else if (typeof data.entryScore !== 'number') { + errors.entryScore = 'Should be a number'; + } else if (data.entryScore < 1 || data.entryScore > 9) { + //Remove required entryScore + //errors.entryScore = 'Should be between 1 and 9'; + } + */ + + if (data.event) { + if (typeof data.event !== 'string') { + errors.event = 'Should be a string'; + } else if (!isMongoId(data.event)) { + errors.event = 'Should be a valid id'; + } + } + + if ( + typeof data.hasParking !== 'undefined' && + typeof data.hasParking !== 'boolean' + ) { + errors.hasParking = 'Should be a boolean'; + } + + if ( + typeof data.hasSecondEntry !== 'undefined' && + typeof data.hasSecondEntry !== 'boolean' + ) { + errors.hasSecondEntry = 'Should be a boolean'; + } + + if ( + typeof data.hasWellLit !== 'undefined' && + typeof data.hasWellLit !== 'boolean' + ) { + errors.hasWellLit = 'Should be a boolean'; + } + + if ( + typeof data.isQuiet !== 'undefined' && + typeof data.isQuiet !== 'boolean' + ) { + errors.isQuiet = 'Should be a boolean'; + } + + if ( + typeof data.isSpacious !== 'undefined' && + typeof data.isSpacious !== 'boolean' + ) { + errors.isSpacious = 'Should be a boolean'; + } + + if (typeof data.photo !== 'undefined' && typeof data.photo !== 'string') { + errors.photo = 'Should be a string'; + } + + if (!data.place) { + errors.place = 'Is required'; + } else if (typeof data.place !== 'string') { + errors.place = 'Should be a string'; + } + + if (typeof data.steps !== 'undefined') { + if (typeof data.steps !== 'number') { + errors.steps = 'Should be a number'; + } else if (data.steps < 0 || data.steps > 3) { + errors.steps = 'Should be between 0 and 3'; + } + } + + if (data.team) { + if (typeof data.team !== 'string') { + errors.team = 'Should be a string'; + } else if (!isMongoId(data.team)) { + errors.team = 'Should be a valid id'; + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateListReviews(queryParams) { + const errors = {}; + + //Remove bathroomScore validation + if (queryParams.bathroomScore) { + /* + const limits = queryParams.bathroomScore.split(','); + + if (limits.length !== 2) { + errors.bathroomScore = 'Should be two integers split by a comma'; + } else if ( + !isInt(limits[0], { min: 1, max: 4 }) || + !isInt(limits[1], { min: 1, max: 4 }) + ) { + errors.bathroomScore = 'Both should be integers between 1 and 4'; + } + */ + } + + //Remove entryScore validation + if (queryParams.entryScore) { + /* + const limits = queryParams.entryScore.split(','); + + if (limits.length !== 2) { + errors.entryScore = 'Should be two integers split by a comma'; + } else if ( + !isInt(limits[0], { min: 1, max: 9 }) || + !isInt(limits[1], { min: 1, max: 9 }) + ) { + errors.entryScore = 'Both should be integers between 1 and 9'; + } + */ + } + + if (queryParams.event && !isMongoId(queryParams.event)) { + errors.event = 'Should be a valid Id'; + } + + if ( + queryParams.guideDog && + !isInt(queryParams.guideDog, { min: 0, max: 1 }) + ) { + errors.guideDog = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.parking && + !isInt(queryParams.parking, { min: 0, max: 1 }) + ) { + errors.parking = 'Should be an integer between 0 and 1'; + } + + if (queryParams.quiet && !isInt(queryParams.quiet, { min: 0, max: 1 })) { + errors.quiet = 'Should be an integer between 0 and 1'; + } + + if (queryParams.ramp && !isInt(queryParams.ramp, { min: 0, max: 1 })) { + errors.ramp = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.secondEntry && + !isInt(queryParams.secondEntry, { min: 0, max: 1 }) + ) { + errors.secondEntry = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.spacious && + !isInt(queryParams.spacious, { min: 0, max: 1 }) + ) { + errors.spacious = 'Should be an integer between 0 and 1'; + } + + if (queryParams.steps && !isInt(queryParams.steps, { min: 0, max: 3 })) { + errors.steps = 'Should be an integer between 0 and 3'; + } + + if (queryParams.team && !isMongoId(queryParams.team)) { + errors.team = 'Should be a valid Id'; + } + + if (queryParams.user && !isMongoId(queryParams.user)) { + errors.user = 'Should be a valid Id'; + } + + if (queryParams.venue && !isMongoId(queryParams.venue)) { + errors.venue = 'Should be a valid Id'; + } + + if ( + queryParams.wellLit && + !isInt(queryParams.wellLit, { min: 0, max: 1 }) + ) { + errors.wellLit = 'Should be an integer between 0 and 1'; + } + + // + // new expanded fields + // + if ( + queryParams.hasPermanentRamp && + !isInt(queryParams.hasPermanentRamp, { min: 0, max: 1 }) + ) { + errors.hasPermanentRamp = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasPortableRamp && + !isInt(queryParams.hasPortableRamp, { min: 0, max: 1 }) + ) { + errors.hasPortableRamp = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasWideEntrance && + !isInt(queryParams.hasWideEntrance, { min: 0, max: 1 }) + ) { + errors.hasWideEntrance = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasAccessibleTableHeight && + !isInt(queryParams.hasAccessibleTableHeight, { min: 0, max: 1 }) + ) { + errors.hasAccessibleTableHeight = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasAccessibleElevator && + !isInt(queryParams.hasAccessibleElevator, { min: 0, max: 1 }) + ) { + errors.hasAccessibleElevator = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasInteriorRamp && + !isInt(queryParams.hasInteriorRamp, { min: 0, max: 1 }) + ) { + errors.hasInteriorRamp = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasSwingOutDoor && + !isInt(queryParams.hasSwingOutDoor, { min: 0, max: 1 }) + ) { + errors.hasSwingOutDoor = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasLargeStall && + !isInt(queryParams.hasLargeStall, { min: 0, max: 1 }) + ) { + errors.hasLargeStall = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasSupportAroundToilet && + !isInt(queryParams.hasSupportAroundToilet, { min: 0, max: 1 }) + ) { + errors.hasSupportAroundToilet = 'Should be an integer between 0 and 1'; + } + + if ( + queryParams.hasLoweredSinks && + !isInt(queryParams.hasLoweredSinks, { min: 0, max: 1 }) + ) { + errors.hasLoweredSinks = 'Should be an integer between 0 and 1'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/reviews/vote-review.js b/src/routes/reviews/vote-review.js index dbd8b6c..e3e9472 100644 --- a/src/routes/reviews/vote-review.js +++ b/src/routes/reviews/vote-review.js @@ -1,49 +1,49 @@ -const moment = require('moment'); - -const { Review } = require('../../models/review'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const reviewId = req.params.reviewId; - - let review; - try { - review = await Review.findOne({ _id: reviewId }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Review not found' }); - } - - console.log(`Review ${reviewId} failed to be found at vote-review`); - return next(err); - } - - if (!review) { - return res.status(404).json({ general: 'Review not found' }); - } - - let addVote = true; - - if (review.voters.find(v => v.toString() === req.user.id)) { - review.voters = review.voters.filter(v => v.toString() !== req.user.id); - addVote = false; - } else { - review.voters = [...review.voters, req.user.id]; - } - - review.updatedAt = moment.utc().toDate(); - - try { - await review.save(); - } catch (err) { - console.log(`Review ${review.id} failed to be updated at vote-review`); - return next(err); - } - - return res - .status(200) - .json({ general: addVote ? 'One more vote' : 'One less vote' }); -}; +const moment = require('moment'); + +const { Review } = require('../../models/review'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const reviewId = req.params.reviewId; + + let review; + try { + review = await Review.findOne({ _id: reviewId }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Review not found' }); + } + + console.log(`Review ${reviewId} failed to be found at vote-review`); + return next(err); + } + + if (!review) { + return res.status(404).json({ general: 'Review not found' }); + } + + let addVote = true; + + if (review.voters.find((v) => v.toString() === req.user.id)) { + review.voters = review.voters.filter((v) => v.toString() !== req.user.id); + addVote = false; + } else { + review.voters = [...review.voters, req.user.id]; + } + + review.updatedAt = moment.utc().toDate(); + + try { + await review.save(); + } catch (err) { + console.log(`Review ${review.id} failed to be updated at vote-review`); + return next(err); + } + + return res + .status(200) + .json({ general: addVote ? 'One more vote' : 'One less vote' }); +}; diff --git a/src/routes/teams/create-team.js b/src/routes/teams/create-team.js index a40dc19..799bdfe 100644 --- a/src/routes/teams/create-team.js +++ b/src/routes/teams/create-team.js @@ -1,93 +1,93 @@ -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { Team } = require('../../models/team'); - -const { validateCreateTeam } = require('./validations'); - -module.exports = async (req, res, next) => { - const data = { - avatar: req.body.avatar, - description: req.body.description, - name: req.body.name - }; - - const { errors, isValid } = validateCreateTeam(data); - if (!isValid) return res.status(400).json(errors); - - if (data.avatar) { - let avatar; - try { - avatar = await Photo.findOne({ url: data.avatar }); - } catch (err) { - console.log(`Avatar ${data.avatar} failed to be found at create-team`); - return next(err); - } - - if (!avatar) { - return res.status(404).json({ avatar: 'Not found' }); - } - } - - data.managers = [req.user.id]; - - data.name = cleanSpaces(data.name); - - let repeatedTeam; - try { - repeatedTeam = await Team.findOne({ name: data.name, isArchived: false }); - } catch (err) { - console.log(`Team ${data.name} failed to be found at create-team`); - return next(err); - } - - if (repeatedTeam) { - return res.status(400).json({ name: 'Is already taken' }); - } - - let team; - try { - team = await Team.create(data); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Team ${ - data.name - } failed to be created at create-team.\nData: ${JSON.stringify(data)}` - ); - return next(err); - } - - req.user.teams = [...req.user.teams, team.id]; - - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at create-team`); - return next(err); - } - - const dataResponse = { - id: team.id, - avatar: team.avatar, - description: team.description, - managers: [ - { - id: req.user.id, - avatar: req.user.avatar, - name: `${req.user.firstName} ${req.user.lastName}` - } - ], - name: team.name - }; - - return res.status(201).json(dataResponse); -}; +const { cleanSpaces } = require('../../helpers'); +const { Photo } = require('../../models/photo'); +const { Team } = require('../../models/team'); + +const { validateCreateTeam } = require('./validations'); + +module.exports = async (req, res, next) => { + const data = { + avatar: req.body.avatar, + description: req.body.description, + name: req.body.name + }; + + const { errors, isValid } = validateCreateTeam(data); + if (!isValid) return res.status(400).json(errors); + + if (data.avatar) { + let avatar; + try { + avatar = await Photo.findOne({ url: data.avatar }); + } catch (err) { + console.log(`Avatar ${data.avatar} failed to be found at create-team`); + return next(err); + } + + if (!avatar) { + return res.status(404).json({ avatar: 'Not found' }); + } + } + + data.managers = [req.user.id]; + + data.name = cleanSpaces(data.name); + + let repeatedTeam; + try { + repeatedTeam = await Team.findOne({ name: data.name, isArchived: false }); + } catch (err) { + console.log(`Team ${data.name} failed to be found at create-team`); + return next(err); + } + + if (repeatedTeam) { + return res.status(400).json({ name: 'Is already taken' }); + } + + let team; + try { + team = await Team.create(data); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Team ${ + data.name + } failed to be created at create-team.\nData: ${JSON.stringify(data)}` + ); + return next(err); + } + + req.user.teams = [...req.user.teams, team.id]; + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at create-team`); + return next(err); + } + + const dataResponse = { + id: team.id, + avatar: team.avatar, + description: team.description, + managers: [ + { + id: req.user.id, + avatar: req.user.avatar, + name: `${req.user.firstName} ${req.user.lastName}` + } + ], + name: team.name + }; + + return res.status(201).json(dataResponse); +}; diff --git a/src/routes/teams/delete-team.js b/src/routes/teams/delete-team.js index 0bf3431..912b7a1 100644 --- a/src/routes/teams/delete-team.js +++ b/src/routes/teams/delete-team.js @@ -1,115 +1,115 @@ -const moment = require('moment'); - -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const teamId = req.params.teamId; - - let team; - try { - team = await Team.findOne({ _id: teamId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); - } - - console.log(`Team ${teamId} failed to be found at delete-team`); - return next(err); - } - - if (!team) { - return res.status(404).json({ general: 'Team not found' }); - } - - if ( - !team.managers.find(m => m.toString() === req.user.id) && - !req.user.isAdmin - ) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - let archiveTeam = false; - - if (team.events && team.events.length > 0) { - const teamEventsPromises = team.events.map(e => - Event.findOne({ _id: e.toString() }) - ); - - let teamEvents; - try { - teamEvents = await Promise.all(teamEventsPromises); - } catch (err) { - console.log('A team event failed to be found at delete-team'); - return next(err); - } - - for (const event of teamEvents) { - const endDate = moment(event.endDate).utc(); - const endOfToday = moment.utc().endOf('day'); - if (endDate.isBefore(endOfToday)) { - event.teams = event.teams.filter(t => t.toString() !== team.id); - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log(`Event ${event.id} failed to be updated at delete-team`); - return next(err); - } - } else { - archiveTeam = true; - } - } - } - - const teamMembersPromises = team.members.map(m => - User.findOne({ _id: m.toString() }) - ); - - let teamMembers; - try { - teamMembers = await Promise.all(teamMembersPromises); - } catch (err) { - console.log('A team member failed to be found at delete-team'); - return next(err); - } - - for (const member of teamMembers) { - member.teams = member.teams.filter(t => t.toString() !== team.id); - member.updatedAt = moment.utc().toDate(); - - try { - await member.save(); - } catch (err) { - console.log(`Member ${member.id} failed to be updated at delete-team`); - return next(err); - } - } - - if (archiveTeam) { - team.isArchived = true; - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - console.log(`Team ${team.id} failed to be updated at delete-team`); - return next(err); - } - } else { - try { - await team.remove(); - } catch (err) { - console.log(`Team ${team.id} failed to be removed at delete-team`); - return next(err); - } - } - - return res.status(204).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Event } = require('../../models/event'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const teamId = req.params.teamId; + + let team; + try { + team = await Team.findOne({ _id: teamId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Team not found' }); + } + + console.log(`Team ${teamId} failed to be found at delete-team`); + return next(err); + } + + if (!team) { + return res.status(404).json({ general: 'Team not found' }); + } + + if ( + !team.managers.find((m) => m.toString() === req.user.id) && + !req.user.isAdmin + ) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + let archiveTeam = false; + + if (team.events && team.events.length > 0) { + const teamEventsPromises = team.events.map((e) => + Event.findOne({ _id: e.toString() }) + ); + + let teamEvents; + try { + teamEvents = await Promise.all(teamEventsPromises); + } catch (err) { + console.log('A team event failed to be found at delete-team'); + return next(err); + } + + for (const event of teamEvents) { + const endDate = moment(event.endDate).utc(); + const endOfToday = moment.utc().endOf('day'); + if (endDate.isBefore(endOfToday)) { + event.teams = event.teams.filter((t) => t.toString() !== team.id); + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log(`Event ${event.id} failed to be updated at delete-team`); + return next(err); + } + } else { + archiveTeam = true; + } + } + } + + const teamMembersPromises = team.members.map((m) => + User.findOne({ _id: m.toString() }) + ); + + let teamMembers; + try { + teamMembers = await Promise.all(teamMembersPromises); + } catch (err) { + console.log('A team member failed to be found at delete-team'); + return next(err); + } + + for (const member of teamMembers) { + member.teams = member.teams.filter((t) => t.toString() !== team.id); + member.updatedAt = moment.utc().toDate(); + + try { + await member.save(); + } catch (err) { + console.log(`Member ${member.id} failed to be updated at delete-team`); + return next(err); + } + } + + if (archiveTeam) { + team.isArchived = true; + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + console.log(`Team ${team.id} failed to be updated at delete-team`); + return next(err); + } + } else { + try { + await team.remove(); + } catch (err) { + console.log(`Team ${team.id} failed to be removed at delete-team`); + return next(err); + } + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/teams/edit-team.js b/src/routes/teams/edit-team.js index 0afd345..dbbedb4 100644 --- a/src/routes/teams/edit-team.js +++ b/src/routes/teams/edit-team.js @@ -1,205 +1,205 @@ -const { difference, intersection } = require('lodash'); -const moment = require('moment'); - -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); - -const { validateEditTeam } = require('./validations'); - -module.exports = async (req, res, next) => { - const teamId = req.params.teamId; - - let team; - try { - team = await Team.findOne({ _id: teamId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); - } - - console.log(`Team ${teamId} failed to be found at edit-team`); - return next(err); - } - - if (!team) { - return res.status(404).json({ general: 'Team not found' }); - } - - if ( - !team.managers.find(m => m.toString() === req.user.id) && - !req.user.isAdmin - ) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const data = { - avatar: req.body.avatar, - description: req.body.description, - managers: req.body.managers, - members: req.body.members, - name: req.body.name - }; - const { errors, isValid } = validateEditTeam(data); - if (!isValid) return res.status(400).json(errors); - - if ( - data.avatar && - !data.avatar.includes('default') && - data.avatar !== team.avatar - ) { - let avatar; - try { - avatar = await Photo.findOne({ url: data.avatar }); - } catch (err) { - console.log(`Avatar ${data.avatar} failed to be found at edit-team`); - return next(err); - } - - if (!avatar) { - return res.status(404).json({ avatar: 'Not found' }); - } - - team.avatar = data.avatar; - } else if (data.avatar === '') { - team.avatar = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/teams/avatars/default.png`; - } - - team.description = data.description || team.description; - - if (data.managers) { - let managersToAdd = []; - let managersToRemove = []; - - data.managers.forEach(m => { - if (m.startsWith('-')) { - managersToRemove = [...managersToRemove, m.substring(1)]; - } else { - managersToAdd = [...managersToAdd, m]; - } - }); - - const teamManagers = team.managers.map(m => m.toString()); - - managersToAdd = [...new Set(difference(managersToAdd, teamManagers))]; - if (managersToAdd.length > 0) { - const teamMembers = team.members.map(m => m.toString()); - const notMember = managersToAdd.find(m => !teamMembers.includes(m)); - - if (notMember) { - return res - .status(400) - .json({ managers: `User ${notMember} is not a member of this team` }); - } - - team.managers = [...teamManagers, ...managersToAdd]; - team.members = team.members.filter( - m => !managersToAdd.includes(m.toString()) - ); - } - - managersToRemove = [ - ...new Set(intersection(managersToRemove, teamManagers)) - ]; - if (managersToRemove.length === team.managers.length) { - return res - .status(400) - .json({ managers: 'Should not remove all managers' }); - } - - team.managers = team.managers.filter( - m => !managersToRemove.includes(m.toString()) - ); - const teamMembers = team.members.map(m => m.toString()); - team.members = [...teamMembers, ...managersToRemove]; - } - - if (data.members) { - const teamMembers = team.members.map(m => m.toString()); - let membersToRemove = data.members.map(m => m.substring(1)); - membersToRemove = [...new Set(intersection(membersToRemove, teamMembers))]; - - const getMembers = membersToRemove.map(m => - User.find({ _id: m, isArchived: false }) - ); - let members; - try { - members = await Promise.all(getMembers); - } catch (err) { - console.log(`Members failed to be found at edit-team`); - return next(err); - } - - const updateMembers = members.map((m, i) => { - m[i].teams = m[i].teams.filter(t => t.toString() !== team.id); - return m[i].save(); - }); - - try { - await Promise.all(updateMembers); - } catch (err) { - console.log(`Members failed to be updated at edit-team`); - return next(err); - } - - team.members = team.members.filter( - m => !membersToRemove.includes(m.toString()) - ); - } - - if (data.name) { - const teamName = cleanSpaces(data.name); - - if (teamName !== team.name) { - let repeatedTeam; - try { - repeatedTeam = await Team.findOne({ - name: teamName, - isArchived: false - }); - } catch (err) { - console.log(`Team ${teamName} failed to be found at edit-team`); - return next(err); - } - - if (repeatedTeam) { - return res.status(400).json({ name: 'Is already taken' }); - } - - team.name = teamName; - } - } - - team.updatedAt = moment.utc().toDate(); - - try { - await team.save(); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log(`Team ${team.id} failed to be updated at edit-team`); - return next(err); - } - - const dataResponse = { - id: team.id, - avatar: team.avatar, - description: team.description, - managers: team.managers, - members: team.members, - name: team.name - }; - - return res.status(200).json(dataResponse); -}; +const { difference, intersection } = require('lodash'); +const moment = require('moment'); + +const { cleanSpaces } = require('../../helpers'); +const { Photo } = require('../../models/photo'); +const { Team } = require('../../models/team'); +const { User } = require('../../models/user'); + +const { validateEditTeam } = require('./validations'); + +module.exports = async (req, res, next) => { + const teamId = req.params.teamId; + + let team; + try { + team = await Team.findOne({ _id: teamId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Team not found' }); + } + + console.log(`Team ${teamId} failed to be found at edit-team`); + return next(err); + } + + if (!team) { + return res.status(404).json({ general: 'Team not found' }); + } + + if ( + !team.managers.find((m) => m.toString() === req.user.id) && + !req.user.isAdmin + ) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const data = { + avatar: req.body.avatar, + description: req.body.description, + managers: req.body.managers, + members: req.body.members, + name: req.body.name + }; + const { errors, isValid } = validateEditTeam(data); + if (!isValid) return res.status(400).json(errors); + + if ( + data.avatar && + !data.avatar.includes('default') && + data.avatar !== team.avatar + ) { + let avatar; + try { + avatar = await Photo.findOne({ url: data.avatar }); + } catch (err) { + console.log(`Avatar ${data.avatar} failed to be found at edit-team`); + return next(err); + } + + if (!avatar) { + return res.status(404).json({ avatar: 'Not found' }); + } + + team.avatar = data.avatar; + } else if (data.avatar === '') { + team.avatar = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/teams/avatars/default.png`; + } + + team.description = data.description || team.description; + + if (data.managers) { + let managersToAdd = []; + let managersToRemove = []; + + data.managers.forEach((m) => { + if (m.startsWith('-')) { + managersToRemove = [...managersToRemove, m.substring(1)]; + } else { + managersToAdd = [...managersToAdd, m]; + } + }); + + const teamManagers = team.managers.map((m) => m.toString()); + + managersToAdd = [...new Set(difference(managersToAdd, teamManagers))]; + if (managersToAdd.length > 0) { + const teamMembers = team.members.map((m) => m.toString()); + const notMember = managersToAdd.find((m) => !teamMembers.includes(m)); + + if (notMember) { + return res + .status(400) + .json({ managers: `User ${notMember} is not a member of this team` }); + } + + team.managers = [...teamManagers, ...managersToAdd]; + team.members = team.members.filter( + (m) => !managersToAdd.includes(m.toString()) + ); + } + + managersToRemove = [ + ...new Set(intersection(managersToRemove, teamManagers)) + ]; + if (managersToRemove.length === team.managers.length) { + return res + .status(400) + .json({ managers: 'Should not remove all managers' }); + } + + team.managers = team.managers.filter( + (m) => !managersToRemove.includes(m.toString()) + ); + const teamMembers = team.members.map((m) => m.toString()); + team.members = [...teamMembers, ...managersToRemove]; + } + + if (data.members) { + const teamMembers = team.members.map((m) => m.toString()); + let membersToRemove = data.members.map((m) => m.substring(1)); + membersToRemove = [...new Set(intersection(membersToRemove, teamMembers))]; + + const getMembers = membersToRemove.map((m) => + User.find({ _id: m, isArchived: false }) + ); + let members; + try { + members = await Promise.all(getMembers); + } catch (err) { + console.log(`Members failed to be found at edit-team`); + return next(err); + } + + const updateMembers = members.map((m, i) => { + m[i].teams = m[i].teams.filter((t) => t.toString() !== team.id); + return m[i].save(); + }); + + try { + await Promise.all(updateMembers); + } catch (err) { + console.log(`Members failed to be updated at edit-team`); + return next(err); + } + + team.members = team.members.filter( + (m) => !membersToRemove.includes(m.toString()) + ); + } + + if (data.name) { + const teamName = cleanSpaces(data.name); + + if (teamName !== team.name) { + let repeatedTeam; + try { + repeatedTeam = await Team.findOne({ + name: teamName, + isArchived: false + }); + } catch (err) { + console.log(`Team ${teamName} failed to be found at edit-team`); + return next(err); + } + + if (repeatedTeam) { + return res.status(400).json({ name: 'Is already taken' }); + } + + team.name = teamName; + } + } + + team.updatedAt = moment.utc().toDate(); + + try { + await team.save(); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log(`Team ${team.id} failed to be updated at edit-team`); + return next(err); + } + + const dataResponse = { + id: team.id, + avatar: team.avatar, + description: team.description, + managers: team.managers, + members: team.members, + name: team.name + }; + + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/teams/get-team.js b/src/routes/teams/get-team.js index ea86094..9f3f0ca 100644 --- a/src/routes/teams/get-team.js +++ b/src/routes/teams/get-team.js @@ -1,144 +1,144 @@ -const mongoose = require('mongoose'); - -const { Team } = require('../../models/team'); - -module.exports = async (req, res, next) => { - const teamId = req.params.teamId; - - const teamIdObj = mongoose.Types.ObjectId(teamId); - let team; - try { - team = await Team.aggregate([ - { - $match: { _id: teamIdObj } - }, - { - $lookup: { - from: 'users', - let: { members: '$members' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$members'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1, - username: 1 - } - } - ], - as: 'members' - } - }, - { - $lookup: { - from: 'users', - let: { managers: '$managers' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$managers'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1, - username: 1 - } - } - ], - as: 'managers' - } - }, - { - $lookup: { - from: 'events', - let: { events: '$events' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$events'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - endDate: 1, - name: 1, - poster: 1, - startDate: 1 - } - } - ], - as: 'events' - } - }, - { - $lookup: { - from: 'teams', - let: { reviewsAmount: '$reviewsAmount' }, - pipeline: [ - { - $match: { - $expr: { - $gt: ['$reviewsAmount', '$$reviewsAmount'] - } - } - }, - { - $count: 'ranking' - } - ], - as: 'ranking' - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - description: 1, - reviewsAmount: 1, - name: 1, - members: 1, - events: 1, - managers: 1, - ranking: 1 - } - } - ]); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); - } - - console.log(`Team ${teamId} failed to be found at get-team`); - return next(err); - } - - if (!team) { - return res.status(404).json({ general: 'Team not found' }); - } - - const dataResponse = Object.assign({}, team[0], { - ranking: team[0].ranking.length ? team[0].ranking[0].ranking + 1 : 1 - }); - return res.status(200).json(dataResponse); -}; +const mongoose = require('mongoose'); + +const { Team } = require('../../models/team'); + +module.exports = async (req, res, next) => { + const teamId = req.params.teamId; + + const teamIdObj = new mongoose.Types.ObjectId(teamId); + let team; + try { + team = await Team.aggregate([ + { + $match: { _id: teamIdObj } + }, + { + $lookup: { + from: 'users', + let: { members: '$members' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$members'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1, + username: 1 + } + } + ], + as: 'members' + } + }, + { + $lookup: { + from: 'users', + let: { managers: '$managers' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$managers'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1, + username: 1 + } + } + ], + as: 'managers' + } + }, + { + $lookup: { + from: 'events', + let: { events: '$events' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$events'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + endDate: 1, + name: 1, + poster: 1, + startDate: 1 + } + } + ], + as: 'events' + } + }, + { + $lookup: { + from: 'teams', + let: { reviewsAmount: '$reviewsAmount' }, + pipeline: [ + { + $match: { + $expr: { + $gt: ['$reviewsAmount', '$$reviewsAmount'] + } + } + }, + { + $count: 'ranking' + } + ], + as: 'ranking' + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + description: 1, + reviewsAmount: 1, + name: 1, + members: 1, + events: 1, + managers: 1, + ranking: 1 + } + } + ]); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Team not found' }); + } + + console.log(`Team ${teamId} failed to be found at get-team`); + return next(err); + } + + if (!team) { + return res.status(404).json({ general: 'Team not found' }); + } + + const dataResponse = Object.assign({}, team[0], { + ranking: team[0].ranking.length ? team[0].ranking[0].ranking + 1 : 1 + }); + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/teams/index.js b/src/routes/teams/index.js index 8ffc659..83b4f3e 100644 --- a/src/routes/teams/index.js +++ b/src/routes/teams/index.js @@ -1,23 +1,23 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const createTeam = require('./create-team'); -const deleteTeam = require('./delete-team'); -const editTeam = require('./edit-team'); -const getTeam = require('./get-team'); -const joinTeam = require('./join-team'); -const leaveTeam = require('./leave-team'); -const listTeams = require('./list-teams'); - -const router = new express.Router(); - -router.get('', isAuthenticated({ isOptional: true }), listTeams); -router.post('', isAuthenticated({ isOptional: false }), createTeam); -router.get('/:teamId', getTeam); -router.put('/:teamId', isAuthenticated({ isOptional: false }), editTeam); -router.delete('/:teamId', isAuthenticated({ isOptional: false }), deleteTeam); -router.post('/:teamId/join', isAuthenticated({ isOptional: false }), joinTeam); -router.put('/:teamId/leave', isAuthenticated({ isOptional: false }), leaveTeam); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const createTeam = require('./create-team'); +const deleteTeam = require('./delete-team'); +const editTeam = require('./edit-team'); +const getTeam = require('./get-team'); +const joinTeam = require('./join-team'); +const leaveTeam = require('./leave-team'); +const listTeams = require('./list-teams'); + +const router = new express.Router(); + +router.get('', isAuthenticated({ isOptional: true }), listTeams); +router.post('', isAuthenticated({ isOptional: false }), createTeam); +router.get('/:teamId', getTeam); +router.put('/:teamId', isAuthenticated({ isOptional: false }), editTeam); +router.delete('/:teamId', isAuthenticated({ isOptional: false }), deleteTeam); +router.post('/:teamId/join', isAuthenticated({ isOptional: false }), joinTeam); +router.put('/:teamId/leave', isAuthenticated({ isOptional: false }), leaveTeam); + +module.exports = router; diff --git a/src/routes/teams/join-team.js b/src/routes/teams/join-team.js index caf65ea..c2de2e4 100644 --- a/src/routes/teams/join-team.js +++ b/src/routes/teams/join-team.js @@ -1,98 +1,98 @@ -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); - -module.exports = async (req, res, next) => { - const teamId = req.params.teamId; - - let team; - try { - team = await Team.findOne({ _id: teamId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); - } - - console.log(`Team ${teamId} failed to be found at join-team`); - return next(err); - } - - if (!team) { - return res.status(404).json({ general: 'Team not found' }); - } - - const eventMembers = team.members.map(m => m.toString()); - if (eventMembers.includes(req.user.id)) { - return res - .status(400) - .json({ general: 'You already are a member in this team' }); - } - - const eventManagers = team.managers.map(m => m.toString()); - if (eventManagers.includes(req.user.id)) { - return res - .status(400) - .json({ general: 'You already are a member in this team' }); - } - - let petition; - try { - petition = await Petition.findOne({ - team: team.id, - sender: req.user.id, - type: 'request-user-team' - }); - } catch (err) { - console.log( - `Petition from user ${req.user.id} to team ${ - team.id - } failed to be found at join-team` - ); - return next(err); - } - - if (petition && petition.state === 'pending') { - return res.status(400).json({ - general: 'You already have a pending petition with this team' - }); - } - - if ( - petition && - (petition.state === 'rejected' || petition.state === 'canceled') - ) { - try { - await petition.remove(); - } catch (err) { - console.log(`Petition ${petition.id} failed to be removed at join-team`); - return next(err); - } - } - - const petitionData = { - team: team.id, - sender: req.user.id, - type: 'request-user-team' - }; - try { - await Petition.create(petitionData); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `Petition failed to be created at join-team.\nData: ${JSON.stringify( - petitionData - )}` - ); - return next(err); - } - - return res.status(200).json({ general: 'Requested' }); -}; +const { Petition } = require('../../models/petition'); +const { Team } = require('../../models/team'); + +module.exports = async (req, res, next) => { + const teamId = req.params.teamId; + + let team; + try { + team = await Team.findOne({ _id: teamId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Team not found' }); + } + + console.log(`Team ${teamId} failed to be found at join-team`); + return next(err); + } + + if (!team) { + return res.status(404).json({ general: 'Team not found' }); + } + + const eventMembers = team.members.map((m) => m.toString()); + if (eventMembers.includes(req.user.id)) { + return res + .status(400) + .json({ general: 'You already are a member in this team' }); + } + + const eventManagers = team.managers.map((m) => m.toString()); + if (eventManagers.includes(req.user.id)) { + return res + .status(400) + .json({ general: 'You already are a member in this team' }); + } + + let petition; + try { + petition = await Petition.findOne({ + team: team.id, + sender: req.user.id, + type: 'request-user-team' + }); + } catch (err) { + console.log( + `Petition from user ${req.user.id} to team ${ + team.id + } failed to be found at join-team` + ); + return next(err); + } + + if (petition && petition.state === 'pending') { + return res.status(400).json({ + general: 'You already have a pending petition with this team' + }); + } + + if ( + petition && + (petition.state === 'rejected' || petition.state === 'canceled') + ) { + try { + await petition.remove(); + } catch (err) { + console.log(`Petition ${petition.id} failed to be removed at join-team`); + return next(err); + } + } + + const petitionData = { + team: team.id, + sender: req.user.id, + type: 'request-user-team' + }; + try { + await Petition.create(petitionData); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `Petition failed to be created at join-team.\nData: ${JSON.stringify( + petitionData + )}` + ); + return next(err); + } + + return res.status(200).json({ general: 'Requested' }); +}; diff --git a/src/routes/teams/leave-team.js b/src/routes/teams/leave-team.js index 8a9a954..1311c88 100644 --- a/src/routes/teams/leave-team.js +++ b/src/routes/teams/leave-team.js @@ -1,59 +1,59 @@ -const moment = require('moment'); - -const { Team } = require('../../models/team'); - -module.exports = async (req, res, next) => { - const teamId = req.params.teamId; - - let team; - try { - team = await Team.findOne({ _id: teamId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); - } - - console.log(`Team ${teamId} failed to be found at leave-team`); - return next(err); - } - - if (!team) { - return res.status(404).json({ general: 'Team not found' }); - } - - if (team.managers.find(m => m.toString() === req.user.id)) { - team.managers = team.managers.filter(m => m.toString() !== req.user.id); - - if (team.managers.length === 0) { - return res.status(400).json({ - general: 'You cannot leave because you are the only manager' - }); - } - } else if (team.members.find(m => m.toString() === req.user.id)) { - team.members = team.members.filter(m => m.toString() !== req.user.id); - } else { - return res.status(400).json({ general: 'You are not a member' }); - } - - const today = moment.utc(); - team.updatedAt = today.toDate(); - - try { - await team.save(); - } catch (err) { - console.log(`Team ${team.id} failed to be updated at leave-team`); - return next(err); - } - - req.user.teams = req.user.teams.filter(t => t.toString() !== team.id); - req.user.updatedAt = today.toDate(); - - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at leave-team`); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Team } = require('../../models/team'); + +module.exports = async (req, res, next) => { + const teamId = req.params.teamId; + + let team; + try { + team = await Team.findOne({ _id: teamId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Team not found' }); + } + + console.log(`Team ${teamId} failed to be found at leave-team`); + return next(err); + } + + if (!team) { + return res.status(404).json({ general: 'Team not found' }); + } + + if (team.managers.find((m) => m.toString() === req.user.id)) { + team.managers = team.managers.filter((m) => m.toString() !== req.user.id); + + if (team.managers.length === 0) { + return res.status(400).json({ + general: 'You cannot leave because you are the only manager' + }); + } + } else if (team.members.find((m) => m.toString() === req.user.id)) { + team.members = team.members.filter((m) => m.toString() !== req.user.id); + } else { + return res.status(400).json({ general: 'You are not a member' }); + } + + const today = moment.utc(); + team.updatedAt = today.toDate(); + + try { + await team.save(); + } catch (err) { + console.log(`Team ${team.id} failed to be updated at leave-team`); + return next(err); + } + + req.user.teams = req.user.teams.filter((t) => t.toString() !== team.id); + req.user.updatedAt = today.toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at leave-team`); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/teams/list-teams.js b/src/routes/teams/list-teams.js index a667d81..605bcf6 100644 --- a/src/routes/teams/list-teams.js +++ b/src/routes/teams/list-teams.js @@ -1,104 +1,104 @@ -const mongoose = require('mongoose'); -const { toBoolean } = require('validator'); - -const { Team } = require('../../models/team'); - -const { validateListTeams } = require('./validations'); - -module.exports = async (req, res, next) => { - const queryParams = req.query; - - const { errors, isValid } = validateListTeams(queryParams); - if (!isValid) return res.status(400).json(errors); - - const teamsQuery = { isArchived: false }; - - if (queryParams.keywords) { - teamsQuery.$text = { $search: queryParams.keywords }; - } - - if (queryParams.managed) { - if (!req.user) { - return res - .status(400) - .json({ general: 'You cannot use managed filter as anonymous' }); - } - - const managed = toBoolean(queryParams.managed); - if (managed) { - teamsQuery.managers = { $in: [mongoose.Types.ObjectId(req.user.id)] }; - } else { - teamsQuery.managers = { $nin: [mongoose.Types.ObjectId(req.user.id)] }; - } - } - - let sortBy = queryParams.sortBy || '-reviewsAmount'; - let page = queryParams.page ? Number(queryParams.page) - 1 : 0; - const pageLimit = Number(queryParams.pageLimit) || 12; - - let teams; - let total; - try { - [teams, total] = await Promise.all([ - Team.aggregate() - .match(teamsQuery) - .project({ - _id: 0, - id: '$_id', - avatar: 1, - description: 1, - name: 1, - reviewsAmount: 1 - }) - .sort(sortBy) - .skip(page * pageLimit) - .limit(pageLimit), - Team.find(teamsQuery).count() - ]); - } catch (err) { - console.log('Teams failed to be found or count at list-teams'); - return next(err); - } - - const getTeamsRankings = teams.map(t => - Team.find({ reviewsAmount: { $gt: t.reviewsAmount } }).count() - ); - - let teamsRankings; - try { - teamsRankings = await Promise.all(getTeamsRankings); - } catch (err) { - console.log('Teams rankings failed to be count at list-teams'); - return next(err); - } - - teams = teams.map((t, i) => ({ - id: t.id, - avatar: t.avatar, - description: t.description, - name: t.name, - ranking: teamsRankings[i] + 1, - reviewsAmount: t.reviewsAmount - })); - - let lastPage = Math.ceil(total / pageLimit); - if (lastPage > 0) { - if (page > lastPage) { - return res - .status(400) - .json({ page: `Should be equal to or less than ${lastPage}` }); - } - } else { - page = null; - lastPage = null; - } - - return res.status(200).json({ - page: page + 1, - lastPage, - pageLimit, - total, - sortBy, - results: teams - }); -}; +const mongoose = require('mongoose'); +const { toBoolean } = require('validator'); + +const { Team } = require('../../models/team'); + +const { validateListTeams } = require('./validations'); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + + const { errors, isValid } = validateListTeams(queryParams); + if (!isValid) return res.status(400).json(errors); + + const teamsQuery = { isArchived: false }; + + if (queryParams.keywords) { + teamsQuery.$text = { $search: queryParams.keywords }; + } + + if (queryParams.managed) { + if (!req.user) { + return res + .status(400) + .json({ general: 'You cannot use managed filter as anonymous' }); + } + + const managed = toBoolean(queryParams.managed); + if (managed) { + teamsQuery.managers = { $in: [new mongoose.Types.ObjectId(req.user.id)] }; + } else { + teamsQuery.managers = { $nin: [new mongoose.Types.ObjectId(req.user.id)] }; + } + } + + let sortBy = queryParams.sortBy || '-reviewsAmount'; + let page = queryParams.page ? Number(queryParams.page) - 1 : 0; + const pageLimit = Number(queryParams.pageLimit) || 12; + + let teams; + let total; + try { + [teams, total] = await Promise.all([ + Team.aggregate() + .match(teamsQuery) + .project({ + _id: 0, + id: '$_id', + avatar: 1, + description: 1, + name: 1, + reviewsAmount: 1 + }) + .sort(sortBy) + .skip(page * pageLimit) + .limit(pageLimit), + Team.find(teamsQuery).count() + ]); + } catch (err) { + console.log('Teams failed to be found or count at list-teams'); + return next(err); + } + + const getTeamsRankings = teams.map((t) => + Team.find({ reviewsAmount: { $gt: t.reviewsAmount } }).count() + ); + + let teamsRankings; + try { + teamsRankings = await Promise.all(getTeamsRankings); + } catch (err) { + console.log('Teams rankings failed to be count at list-teams'); + return next(err); + } + + teams = teams.map((t, i) => ({ + id: t.id, + avatar: t.avatar, + description: t.description, + name: t.name, + ranking: teamsRankings[i] + 1, + reviewsAmount: t.reviewsAmount + })); + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + + return res.status(200).json({ + page: page + 1, + lastPage, + pageLimit, + total, + sortBy, + results: teams + }); +}; diff --git a/src/routes/teams/validations.js b/src/routes/teams/validations.js index 045359a..ce1f9b2 100644 --- a/src/routes/teams/validations.js +++ b/src/routes/teams/validations.js @@ -1,134 +1,134 @@ -const { isEmpty } = require('lodash'); -const { isInt, isMongoId } = require('validator'); - -module.exports = { - validateCreateTeam(data) { - const errors = {}; - - if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { - errors.avatar = 'Should be a string'; - } - - if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' - ) { - errors.description = 'Should be a string'; - } - - if (typeof data.name === 'undefined' || data.name === '') { - errors.name = 'Is required'; - } else if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateEditTeam(data) { - const errors = {}; - - if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { - errors.avatar = 'Should be a string'; - } - - if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' - ) { - errors.description = 'Should be a string'; - } - - if (typeof data.name !== 'undefined') { - if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } else if (data.name === '') { - errors.name = 'Is required'; - } - } - - if (data.managers) { - if (!Array.isArray(data.managers)) { - errors.managers = 'Should be an array'; - } else { - data.managers.some(m => { - if (typeof m !== 'string') { - errors.managers = 'Should only have string values'; - return true; - } else if (!m) { - errors.managers = 'Should not have empty values'; - return true; - } else { - if (m.startsWith('-')) { - m = m.substring(1); - } - - if (!isMongoId(m)) { - errors.managers = `${m} should be an id`; - return true; - } - } - }); - } - } - - if (data.members) { - if (!Array.isArray(data.members)) { - errors.members = 'Should be an array'; - } else { - data.members.some(m => { - if (typeof m !== 'string') { - errors.members = 'Should only have string values'; - return true; - } else if (!m) { - errors.managers = 'Should not have empty values'; - return true; - } else if (!m.startsWith('-')) { - errors.members = `${m} should start with -`; - return true; - } else if (!isMongoId(m.substring(1))) { - errors.members = `${m} should be an id`; - return true; - } - }); - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateListTeams(queryParams) { - const errors = {}; - - if ( - queryParams.managed && - queryParams.managed !== '0' && - queryParams.managed !== '1' - ) { - errors.managed = 'Should be 0 or 1'; - } - - const sortOptions = ['name', '-name', 'reviewsAmount', '-reviewsAmount']; - if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { - errors.sortBy = 'Should be a valid sort'; - } - - if (queryParams.page) { - if (!isInt(queryParams.page)) { - errors.page = 'Should be a integer'; - } else if (parseInt(queryParams.page, 10) < 1) { - errors.page = 'Should be a positive integer'; - } - } - - if (queryParams.pageLimit) { - if (!isInt(queryParams.pageLimit)) { - errors.pageLimit = 'Should be a integer'; - } else if (parseInt(queryParams.pageLimit, 10) < 1) { - errors.pageLimit = 'Should be a positive integer'; - } else if (parseInt(queryParams.pageLimit, 10) > 12) { - errors.pageLimit = 'Should be less than 13'; - } - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const { isEmpty } = require('lodash'); +const { isInt, isMongoId } = require('validator'); + +module.exports = { + validateCreateTeam(data) { + const errors = {}; + + if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { + errors.avatar = 'Should be a string'; + } + + if ( + typeof data.description !== 'undefined' && + typeof data.description !== 'string' + ) { + errors.description = 'Should be a string'; + } + + if (typeof data.name === 'undefined' || data.name === '') { + errors.name = 'Is required'; + } else if (typeof data.name !== 'string') { + errors.name = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateEditTeam(data) { + const errors = {}; + + if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { + errors.avatar = 'Should be a string'; + } + + if ( + typeof data.description !== 'undefined' && + typeof data.description !== 'string' + ) { + errors.description = 'Should be a string'; + } + + if (typeof data.name !== 'undefined') { + if (typeof data.name !== 'string') { + errors.name = 'Should be a string'; + } else if (data.name === '') { + errors.name = 'Is required'; + } + } + + if (data.managers) { + if (!Array.isArray(data.managers)) { + errors.managers = 'Should be an array'; + } else { + data.managers.some((m) => { + if (typeof m !== 'string') { + errors.managers = 'Should only have string values'; + return true; + } else if (!m) { + errors.managers = 'Should not have empty values'; + return true; + } else { + if (m.startsWith('-')) { + m = m.substring(1); + } + + if (!isMongoId(m)) { + errors.managers = `${m} should be an id`; + return true; + } + } + }); + } + } + + if (data.members) { + if (!Array.isArray(data.members)) { + errors.members = 'Should be an array'; + } else { + data.members.some((m) => { + if (typeof m !== 'string') { + errors.members = 'Should only have string values'; + return true; + } else if (!m) { + errors.managers = 'Should not have empty values'; + return true; + } else if (!m.startsWith('-')) { + errors.members = `${m} should start with -`; + return true; + } else if (!isMongoId(m.substring(1))) { + errors.members = `${m} should be an id`; + return true; + } + }); + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateListTeams(queryParams) { + const errors = {}; + + if ( + queryParams.managed && + queryParams.managed !== '0' && + queryParams.managed !== '1' + ) { + errors.managed = 'Should be 0 or 1'; + } + + const sortOptions = ['name', '-name', 'reviewsAmount', '-reviewsAmount']; + if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { + errors.sortBy = 'Should be a valid sort'; + } + + if (queryParams.page) { + if (!isInt(queryParams.page)) { + errors.page = 'Should be a integer'; + } else if (parseInt(queryParams.page, 10) < 1) { + errors.page = 'Should be a positive integer'; + } + } + + if (queryParams.pageLimit) { + if (!isInt(queryParams.pageLimit)) { + errors.pageLimit = 'Should be a integer'; + } else if (parseInt(queryParams.pageLimit, 10) < 1) { + errors.pageLimit = 'Should be a positive integer'; + } else if (parseInt(queryParams.pageLimit, 10) > 12) { + errors.pageLimit = 'Should be less than 13'; + } + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/users/archive-user.js b/src/routes/users/archive-user.js index 46e3f3c..4d19eba 100644 --- a/src/routes/users/archive-user.js +++ b/src/routes/users/archive-user.js @@ -1,101 +1,101 @@ -const moment = require('moment'); - -const { ActivationTicket } = require('../../models/activation-ticket'); -const { PasswordTicket } = require('../../models/password-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - const userId = req.params.userId; - - let user; - try { - user = await User.findOne({ _id: userId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); - } - - console.log(`User with Id ${userId} failed to be found at archive-user.`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'User not found' }); - } - - if (user.id !== req.user.id && !req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - let activateAccountTicket; - let passwordTicket; - let refreshToken; - try { - [activateAccountTicket, passwordTicket, refreshToken] = await Promise.all([ - ActivationTicket.findOne({ email: user.email }), - PasswordTicket.findOne({ email: user.email }), - RefreshToken.findOne({ userId: user.id }) - ]); - } catch (err) { - console.log( - `Activate account ticket, password ticket or refresh token with email ${ - user.email - } failed to be found at archive-user.` - ); - return next(err); - } - - if (activateAccountTicket) { - try { - await activateAccountTicket.remove(); - } catch (err) { - console.log( - `Activate user ticket with key ${ - activateAccountTicket.key - } failed to be removed at archive-user.` - ); - return next(err); - } - } - - if (passwordTicket) { - try { - await passwordTicket.remove(); - } catch (err) { - console.log( - `Password ticket with key ${ - passwordTicket.key - } failed to be removed at archive-user.` - ); - return next(err); - } - } - - if (refreshToken) { - try { - await refreshToken.remove(); - } catch (err) { - console.log( - `Refresh token with key ${ - refreshToken.key - } failed to be removed at archive-user.` - ); - return next(err); - } - } - - user.isArchived = true; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log( - `User with email ${user.email} failed to be updated at archive-user.` - ); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { ActivationTicket } = require('../../models/activation-ticket'); +const { PasswordTicket } = require('../../models/password-ticket'); +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + const userId = req.params.userId; + + let user; + try { + user = await User.findOne({ _id: userId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'User not found' }); + } + + console.log(`User with Id ${userId} failed to be found at archive-user.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'User not found' }); + } + + if (user.id !== req.user.id && !req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + let activateAccountTicket; + let passwordTicket; + let refreshToken; + try { + [activateAccountTicket, passwordTicket, refreshToken] = await Promise.all([ + ActivationTicket.findOne({ email: user.email }), + PasswordTicket.findOne({ email: user.email }), + RefreshToken.findOne({ userId: user.id }) + ]); + } catch (err) { + console.log( + `Activate account ticket, password ticket or refresh token with email ${ + user.email + } failed to be found at archive-user.` + ); + return next(err); + } + + if (activateAccountTicket) { + try { + await activateAccountTicket.remove(); + } catch (err) { + console.log( + `Activate user ticket with key ${ + activateAccountTicket.key + } failed to be removed at archive-user.` + ); + return next(err); + } + } + + if (passwordTicket) { + try { + await passwordTicket.remove(); + } catch (err) { + console.log( + `Password ticket with key ${ + passwordTicket.key + } failed to be removed at archive-user.` + ); + return next(err); + } + } + + if (refreshToken) { + try { + await refreshToken.remove(); + } catch (err) { + console.log( + `Refresh token with key ${ + refreshToken.key + } failed to be removed at archive-user.` + ); + return next(err); + } + } + + user.isArchived = true; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log( + `User with email ${user.email} failed to be updated at archive-user.` + ); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/users/block-user.js b/src/routes/users/block-user.js index 6e93c8a..44c88ec 100644 --- a/src/routes/users/block-user.js +++ b/src/routes/users/block-user.js @@ -1,39 +1,39 @@ -const moment = require('moment'); - -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const userId = req.params.userId; - - let user; - try { - user = await User.findOne({ _id: userId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); - } - - console.log(`User with Id ${userId} failed to be found at block-user.`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'User not found' }); - } - - user.isBlocked = true; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log(`User with Id ${user.id} failed to be updated at block-user.`); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const userId = req.params.userId; + + let user; + try { + user = await User.findOne({ _id: userId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'User not found' }); + } + + console.log(`User with Id ${userId} failed to be found at block-user.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'User not found' }); + } + + user.isBlocked = true; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log(`User with Id ${user.id} failed to be updated at block-user.`); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/users/change-password.js b/src/routes/users/change-password.js index 13b2391..2c88231 100644 --- a/src/routes/users/change-password.js +++ b/src/routes/users/change-password.js @@ -1,64 +1,64 @@ -const moment = require('moment'); - -const { RefreshToken } = require('../../models/refresh-token'); - -const { validateChangePassword } = require('./validations'); - -module.exports = async (req, res, next) => { - if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); - } - - const { errors, isValid } = validateChangePassword(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const oldPassword = req.body.oldPassword; - const password = req.body.password; - - const passwordMatches = req.user.comparePassword(oldPassword); - - if (!passwordMatches) { - return res.status(400).json({ oldPassword: 'Wrong password' }); - } - - let refreshToken; - try { - refreshToken = await RefreshToken.findOne({ userId: req.user.id }); - } catch (err) { - console.log( - `Refresh Token with userId ${ - req.user.id - } failed to be found at change-password.` - ); - return next(err); - } - - if (refreshToken) { - try { - await refreshToken.remove(); - } catch (err) { - console.log( - `Refresh Token with key ${ - refreshToken.key - } failed to be removed at change-password.` - ); - return next(err); - } - } - - req.user.password = password; - req.user.updatedAt = moment.utc().toDate(); - - try { - req.user.save(); - } catch (err) { - console.log( - `User with Id ${req.user.id} failed to be updated at change-password.` - ); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { RefreshToken } = require('../../models/refresh-token'); + +const { validateChangePassword } = require('./validations'); + +module.exports = async (req, res, next) => { + if (req.user.isBlocked) { + return res.status(423).json({ general: 'You are blocked' }); + } + + const { errors, isValid } = validateChangePassword(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const oldPassword = req.body.oldPassword; + const password = req.body.password; + + const passwordMatches = req.user.comparePassword(oldPassword); + + if (!passwordMatches) { + return res.status(400).json({ oldPassword: 'Wrong password' }); + } + + let refreshToken; + try { + refreshToken = await RefreshToken.findOne({ userId: req.user.id }); + } catch (err) { + console.log( + `Refresh Token with userId ${ + req.user.id + } failed to be found at change-password.` + ); + return next(err); + } + + if (refreshToken) { + try { + await refreshToken.remove(); + } catch (err) { + console.log( + `Refresh Token with key ${ + refreshToken.key + } failed to be removed at change-password.` + ); + return next(err); + } + } + + req.user.password = password; + req.user.updatedAt = moment.utc().toDate(); + + try { + req.user.save(); + } catch (err) { + console.log( + `User with Id ${req.user.id} failed to be updated at change-password.` + ); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/users/create-user.js b/src/routes/users/create-user.js index 937fb97..3fb3d2e 100644 --- a/src/routes/users/create-user.js +++ b/src/routes/users/create-user.js @@ -1,153 +1,150 @@ -const crypto = require('crypto'); - -const moment = require('moment'); -const { pick } = require('lodash'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -const { cleanSpaces } = require('../../helpers'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); - -const { validateCreateUser } = require('./validations'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const { errors, isValid } = validateCreateUser(req.body); - if (!isValid) { - return res.status(400).json(errors); - } - - const userData = pick(req.body, [ - 'description', - 'disabilities', - 'email', - 'firstName', - 'gender', - 'isSubscribed', - 'lastName', - 'password', - 'phone', - 'showDisabilities', - 'showEmail', - 'showPhone', - 'username', - 'zip' - ]); - userData.firstName = cleanSpaces(userData.firstName); - userData.lastName = cleanSpaces(userData.lastName); - - let usernameSent = true; - - if (!userData.username) { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}`; - usernameSent = false; - } - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - $or: [{ email: userData.email }, { username: userData.username }], - isArchived: false - }); - } catch (err) { - console.log('Users failed to be found at create-user.'); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - for (const user of repeatedUsers) { - if (user.email === userData.email) { - return res.status(400).json({ email: 'Is already taken' }); - } else if (usernameSent && user.username === userData.username) { - return res.status(400).json({ username: 'Is already taken' }); - } - - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}`; - - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at create-user.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } - } - - let user; - try { - user = await User.create(userData); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `User with email ${userData.email} failed to be created at create-user.` - ); - return next(err); - } - - const refreshTokenData = { - expiresAt: moment - .utc() - .add(14, 'days') - .toDate(), - key: `${user.id}${crypto.randomBytes(40).toString('hex')}`, - userId: user.id - }; - try { - await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token with userId ${ - refreshTokenData.userId - } failed to be created at create-user.` - ); - return next(err); - } - - const dataResponse = pick(user, [ - '_id', - 'description', - 'disabilities', - 'email', - 'firstName', - 'gender', - 'isSubscribed', - 'lastName', - 'phone', - 'showDisabilities', - 'showEmail', - 'showPhone', - 'username', - 'zip' - ]); - return res.status(201).json(dataResponse); -}; +const crypto = require('crypto'); + +const moment = require('moment'); +const { pick } = require('lodash'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +const { cleanSpaces } = require('../../helpers'); +const { RefreshToken } = require('../../models/refresh-token'); +const { User } = require('../../models/user'); + +const { validateCreateUser } = require('./validations'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const { errors, isValid } = validateCreateUser(req.body); + if (!isValid) { + return res.status(400).json(errors); + } + + const userData = pick(req.body, [ + 'description', + 'disabilities', + 'email', + 'firstName', + 'gender', + 'isSubscribed', + 'lastName', + 'password', + 'phone', + 'showDisabilities', + 'showEmail', + 'showPhone', + 'username', + 'zip' + ]); + userData.firstName = cleanSpaces(userData.firstName); + userData.lastName = cleanSpaces(userData.lastName); + + let usernameSent = true; + + if (!userData.username) { + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}`; + usernameSent = false; + } + + let repeatedUsers; + try { + repeatedUsers = await User.find({ + $or: [{ email: userData.email }, { username: userData.username }], + isArchived: false + }); + } catch (err) { + console.log('Users failed to be found at create-user.'); + return next(err); + } + + if (repeatedUsers && repeatedUsers.length > 0) { + for (const user of repeatedUsers) { + if (user.email === userData.email) { + return res.status(400).json({ email: 'Is already taken' }); + } else if (usernameSent && user.username === userData.username) { + return res.status(400).json({ username: 'Is already taken' }); + } + + let repeatedUser; + do { + userData.username = `${slugify(userData.firstName)}-${slugify( + userData.lastName + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}`; + + try { + repeatedUser = await User.findOne({ + username: userData.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${ + userData.username + } failed to be found at create-user.` + ); + return next(err); + } + } while (repeatedUser && repeatedUser.username === userData.username); + } + } + + let user; + try { + user = await User.create(userData); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `User with email ${userData.email} failed to be created at create-user.` + ); + return next(err); + } + + const refreshTokenData = { + expiresAt: moment.utc().add(14, 'days').toDate(), + key: `${user.id}${crypto.randomBytes(40).toString('hex')}`, + userId: user.id + }; + try { + await RefreshToken.create(refreshTokenData); + } catch (err) { + console.log( + `Refresh token with userId ${ + refreshTokenData.userId + } failed to be created at create-user.` + ); + return next(err); + } + + const dataResponse = pick(user, [ + '_id', + 'description', + 'disabilities', + 'email', + 'firstName', + 'gender', + 'isSubscribed', + 'lastName', + 'phone', + 'showDisabilities', + 'showEmail', + 'showPhone', + 'username', + 'zip' + ]); + return res.status(201).json(dataResponse); +}; diff --git a/src/routes/users/delete-user.js b/src/routes/users/delete-user.js index 39464d2..401e7e4 100644 --- a/src/routes/users/delete-user.js +++ b/src/routes/users/delete-user.js @@ -1,36 +1,36 @@ -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const userId = req.params.userId; - - let user; - try { - user = await User.findOne({ _id: userId, isArchived: true }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Archived user not found' }); - } - - console.log(`User with Id ${userId} failed to be found at delete-user.`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'Archived user not found' }); - } - - try { - await user.remove(); - } catch (err) { - console.log( - `User with email ${user.email} failed to be deleted at delete-user.` - ); - return next(err); - } - - return res.status(204).json({ general: 'Success' }); -}; +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const userId = req.params.userId; + + let user; + try { + user = await User.findOne({ _id: userId, isArchived: true }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Archived user not found' }); + } + + console.log(`User with Id ${userId} failed to be found at delete-user.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'Archived user not found' }); + } + + try { + await user.remove(); + } catch (err) { + console.log( + `User with email ${user.email} failed to be deleted at delete-user.` + ); + return next(err); + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/users/edit-user.js b/src/routes/users/edit-user.js index ae6cb80..f0be2a1 100644 --- a/src/routes/users/edit-user.js +++ b/src/routes/users/edit-user.js @@ -1,160 +1,160 @@ -const moment = require('moment'); - -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { User } = require('../../models/user'); - -const { validateEditUser } = require('./validations'); - -module.exports = async (req, res, next) => { - const userId = req.params.userId; - - let user; - try { - user = await User.findOne({ _id: userId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); - } - - console.log(`User with Id ${userId} failed to be found at edit-user.`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'User not found' }); - } - - if (user.id !== req.user.id && !req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const data = req.body; - - const { errors, isValid } = validateEditUser(data); - if (!isValid) return res.status(400).json(errors); - - if ( - data.avatar && - !data.avatar.includes('default') && - data.avatar !== user.avatar - ) { - let avatar; - try { - avatar = await Photo.findOne({ url: data.avatar }); - } catch (err) { - console.log(`Avatar ${data.avatar} failed to be found at edit-user`); - return next(err); - } - - if (!avatar) { - return res.status(404).json({ avatar: 'Not found' }); - } - - user.avatar = data.avatar; - } else if (data.avatar === '') { - user.avatar = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/users/avatars/default.png`; - } - - user.description = data.description || user.description; - - user.disabilities = data.disabilities || user.disabilities; - - user.firstName = data.firstName - ? cleanSpaces(data.firstName) - : user.firstName; - - user.gender = data.gender || user.gender; - - user.isSubscribed = - typeof data.isSubscribed !== 'undefined' - ? data.isSubscribed - : user.isSubscribed; - - user.language = data.language || user.language; - - user.lastName = data.lastName ? cleanSpaces(data.lastName) : user.lastName; - - user.phone = data.phone || user.phone; - - user.showDisabilities = - typeof data.showDisabilities !== 'undefined' - ? data.showDisabilities - : user.showDisabilities; - - user.showEmail = - typeof data.showEmail !== 'undefined' ? data.showEmail : user.showEmail; - - user.showPhone = - typeof data.showPhone !== 'undefined' ? data.showPhone : user.showPhone; - - if (data.username && data.username !== user.username) { - let repeatedUser; - try { - repeatedUser = await User.findOne({ - username: data.username, - isArchived: false - }); - } catch (err) { - console.log( - `User with username ${data.username} failed to be found at edit-user.` - ); - return next(err); - } - - if (repeatedUser) { - return res.status(400).json({ username: 'Is already taken' }); - } - - user.username = data.username; - } - - user.zip = data.zip ? cleanSpaces(data.zip) : user.zip; - - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - if (typeof err.errors === 'object') { - const validationErrors = {}; - - Object.keys(err.errors).forEach(key => { - validationErrors[key] = err.errors[key].message; - }); - - return res.status(400).json(validationErrors); - } - - console.log( - `User ${ - user.id - } failed to be updated at edit-user.\nData: ${JSON.stringify( - data, - null, - 2 - )}` - ); - return next(err); - } - - const dataResponse = { - id: user.id, - avatar: user.avatar, - description: user.description, - disabilities: user.disabilities, - firstName: user.firstName, - gender: user.gender, - isSubscribed: user.isSubscribed, - lastName: user.lastName, - phone: user.phone, - showDisabilities: user.showDisabilities, - showEmail: user.showEmail, - showPhone: user.showPhone, - username: user.username, - zip: user.zip - }; - return res.status(200).json(dataResponse); -}; +const moment = require('moment'); + +const { cleanSpaces } = require('../../helpers'); +const { Photo } = require('../../models/photo'); +const { User } = require('../../models/user'); + +const { validateEditUser } = require('./validations'); + +module.exports = async (req, res, next) => { + const userId = req.params.userId; + + let user; + try { + user = await User.findOne({ _id: userId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'User not found' }); + } + + console.log(`User with Id ${userId} failed to be found at edit-user.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'User not found' }); + } + + if (user.id !== req.user.id && !req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const data = req.body; + + const { errors, isValid } = validateEditUser(data); + if (!isValid) return res.status(400).json(errors); + + if ( + data.avatar && + !data.avatar.includes('default') && + data.avatar !== user.avatar + ) { + let avatar; + try { + avatar = await Photo.findOne({ url: data.avatar }); + } catch (err) { + console.log(`Avatar ${data.avatar} failed to be found at edit-user`); + return next(err); + } + + if (!avatar) { + return res.status(404).json({ avatar: 'Not found' }); + } + + user.avatar = data.avatar; + } else if (data.avatar === '') { + user.avatar = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/users/avatars/default.png`; + } + + user.description = data.description || user.description; + + user.disabilities = data.disabilities || user.disabilities; + + user.firstName = data.firstName + ? cleanSpaces(data.firstName) + : user.firstName; + + user.gender = data.gender || user.gender; + + user.isSubscribed = + typeof data.isSubscribed !== 'undefined' + ? data.isSubscribed + : user.isSubscribed; + + user.language = data.language || user.language; + + user.lastName = data.lastName ? cleanSpaces(data.lastName) : user.lastName; + + user.phone = data.phone || user.phone; + + user.showDisabilities = + typeof data.showDisabilities !== 'undefined' + ? data.showDisabilities + : user.showDisabilities; + + user.showEmail = + typeof data.showEmail !== 'undefined' ? data.showEmail : user.showEmail; + + user.showPhone = + typeof data.showPhone !== 'undefined' ? data.showPhone : user.showPhone; + + if (data.username && data.username !== user.username) { + let repeatedUser; + try { + repeatedUser = await User.findOne({ + username: data.username, + isArchived: false + }); + } catch (err) { + console.log( + `User with username ${data.username} failed to be found at edit-user.` + ); + return next(err); + } + + if (repeatedUser) { + return res.status(400).json({ username: 'Is already taken' }); + } + + user.username = data.username; + } + + user.zip = data.zip ? cleanSpaces(data.zip) : user.zip; + + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + if (typeof err.errors === 'object') { + const validationErrors = {}; + + Object.keys(err.errors).forEach((key) => { + validationErrors[key] = err.errors[key].message; + }); + + return res.status(400).json(validationErrors); + } + + console.log( + `User ${ + user.id + } failed to be updated at edit-user.\nData: ${JSON.stringify( + data, + null, + 2 + )}` + ); + return next(err); + } + + const dataResponse = { + id: user.id, + avatar: user.avatar, + description: user.description, + disabilities: user.disabilities, + firstName: user.firstName, + gender: user.gender, + isSubscribed: user.isSubscribed, + lastName: user.lastName, + phone: user.phone, + showDisabilities: user.showDisabilities, + showEmail: user.showEmail, + showPhone: user.showPhone, + username: user.username, + zip: user.zip + }; + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/users/get-profile.js b/src/routes/users/get-profile.js index 0d83096..f9685c0 100644 --- a/src/routes/users/get-profile.js +++ b/src/routes/users/get-profile.js @@ -1,93 +1,93 @@ -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); - -module.exports = async (req, res, next) => { - const getUserTeams = req.user.teams.map(t => Team.findOne({ _id: t })); - let userTeams; - try { - userTeams = await Promise.all(getUserTeams); - } catch (err) { - console.log('Teams failed to be found at get-profile'); - return next(err); - } - - const teams = []; - const managedTeams = []; - userTeams.map(t => { - if (t) { - const teamManagers = t.managers.map(m => m.toString()); - if (teamManagers.includes(req.user.id)) { - managedTeams.push({ - id: t.id.toString(), - avatar: t.avatar, - name: t.name - }); - } else { - teams.push({ - id: t.id.toString(), - avatar: t.avatar, - name: t.name - }); - } - } - }); - - const getUserEvents = req.user.events.map(e => Event.findOne({ _id: e })); - let userEvents; - try { - userEvents = await Promise.all(getUserEvents); - } catch (err) { - console.log('Events failed to be found at get-profile'); - return next(err); - } - - const events = []; - const managedEvents = []; - userEvents.map(e => { - if (e) { - const eventManagers = e.managers.map(m => m.toString()); - if (eventManagers.includes(req.user.id)) { - managedEvents.push({ - id: e.id.toString(), - endDate: e.endDate, - name: e.name, - poster: e.poster, - startDate: e.startDate - }); - } else { - events.push({ - id: e.id.toString(), - endDate: e.endDate, - name: e.name, - poster: e.poster, - startDate: e.startDate - }); - } - } - }); - - const userData = { - id: req.user.id, - avatar: req.user.avatar, - description: req.user.description, - disabilities: req.user.disabilities, - email: req.user.email, - events, - firstName: req.user.firstName, - gender: req.user.gender, - isSubscribed: req.user.isSubscribed, - lastName: req.user.lastName, - managedEvents, - managedTeams, - phone: req.user.phone, - reviewFieldsAmount: req.user.reviewFieldsAmount, - reviewsAmount: req.user.reviewsAmount, - showDisabilities: req.user.showDisabilities, - showEmail: req.user.showEmail, - showPhone: req.user.showPhone, - teams, - username: req.user.username, - zip: req.user.zip - }; - return res.status(200).json(userData); -}; +const { Event } = require('../../models/event'); +const { Team } = require('../../models/team'); + +module.exports = async (req, res, next) => { + const getUserTeams = req.user.teams.map((t) => Team.findOne({ _id: t })); + let userTeams; + try { + userTeams = await Promise.all(getUserTeams); + } catch (err) { + console.log('Teams failed to be found at get-profile'); + return next(err); + } + + const teams = []; + const managedTeams = []; + userTeams.map((t) => { + if (t) { + const teamManagers = t.managers.map((m) => m.toString()); + if (teamManagers.includes(req.user.id)) { + managedTeams.push({ + id: t.id.toString(), + avatar: t.avatar, + name: t.name + }); + } else { + teams.push({ + id: t.id.toString(), + avatar: t.avatar, + name: t.name + }); + } + } + }); + + const getUserEvents = req.user.events.map((e) => Event.findOne({ _id: e })); + let userEvents; + try { + userEvents = await Promise.all(getUserEvents); + } catch (err) { + console.log('Events failed to be found at get-profile'); + return next(err); + } + + const events = []; + const managedEvents = []; + userEvents.map((e) => { + if (e) { + const eventManagers = e.managers.map((m) => m.toString()); + if (eventManagers.includes(req.user.id)) { + managedEvents.push({ + id: e.id.toString(), + endDate: e.endDate, + name: e.name, + poster: e.poster, + startDate: e.startDate + }); + } else { + events.push({ + id: e.id.toString(), + endDate: e.endDate, + name: e.name, + poster: e.poster, + startDate: e.startDate + }); + } + } + }); + + const userData = { + id: req.user.id, + avatar: req.user.avatar, + description: req.user.description, + disabilities: req.user.disabilities, + email: req.user.email, + events, + firstName: req.user.firstName, + gender: req.user.gender, + isSubscribed: req.user.isSubscribed, + lastName: req.user.lastName, + managedEvents, + managedTeams, + phone: req.user.phone, + reviewFieldsAmount: req.user.reviewFieldsAmount, + reviewsAmount: req.user.reviewsAmount, + showDisabilities: req.user.showDisabilities, + showEmail: req.user.showEmail, + showPhone: req.user.showPhone, + teams, + username: req.user.username, + zip: req.user.zip + }; + return res.status(200).json(userData); +}; diff --git a/src/routes/users/get-user.js b/src/routes/users/get-user.js index a24972f..f6d7a08 100644 --- a/src/routes/users/get-user.js +++ b/src/routes/users/get-user.js @@ -1,127 +1,127 @@ -const mongoose = require('mongoose'); - -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - const userId = req.params.userId; - - const userIdObj = mongoose.Types.ObjectId(userId); - let user; - try { - user = await User.aggregate([ - { - $match: { _id: userIdObj } - }, - { - $lookup: { - from: 'events', - let: { events: '$events' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$events'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - endDate: 1, - name: 1, - poster: 1, - startDate: 1 - } - } - ], - as: 'events' - } - }, - { - $lookup: { - from: 'teams', - let: { teams: '$teams' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$teams'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - name: 1 - } - } - ], - as: 'teams' - } - }, - { - $lookup: { - from: 'users', - let: { reviewsAmount: '$reviewsAmount' }, - pipeline: [ - { - $match: { - $expr: { - $gt: ['$reviewsAmount', '$$reviewsAmount'] - } - } - }, - { - $count: 'ranking' - } - ], - as: 'ranking' - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - description: 1, - disabilities: 1, - email: 1, - events: 1, - firstName: 1, - gender: 1, - isSubscribed: 1, - language: 1, - lastName: 1, - phone: 1, - ranking: 1, - reviewsAmount: 1, - showDisabilities: 1, - showEmail: 1, - showPhone: 1, - teams: 1, - username: 1, - zip: 1 - } - } - ]); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); - } - - console.log(`User ${userId} failed to be found at get-user`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'User not found' }); - } - - const dataResponse = Object.assign({}, user[0], { - ranking: user[0].ranking.length ? user[0].ranking[0].ranking + 1 : 1 - }); - return res.status(200).json(dataResponse); -}; +const mongoose = require('mongoose'); + +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + const userId = req.params.userId; + + const userIdObj = new mongoose.Types.ObjectId(userId); + let user; + try { + user = await User.aggregate([ + { + $match: { _id: userIdObj } + }, + { + $lookup: { + from: 'events', + let: { events: '$events' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$events'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + endDate: 1, + name: 1, + poster: 1, + startDate: 1 + } + } + ], + as: 'events' + } + }, + { + $lookup: { + from: 'teams', + let: { teams: '$teams' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$teams'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + name: 1 + } + } + ], + as: 'teams' + } + }, + { + $lookup: { + from: 'users', + let: { reviewsAmount: '$reviewsAmount' }, + pipeline: [ + { + $match: { + $expr: { + $gt: ['$reviewsAmount', '$$reviewsAmount'] + } + } + }, + { + $count: 'ranking' + } + ], + as: 'ranking' + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + description: 1, + disabilities: 1, + email: 1, + events: 1, + firstName: 1, + gender: 1, + isSubscribed: 1, + language: 1, + lastName: 1, + phone: 1, + ranking: 1, + reviewsAmount: 1, + showDisabilities: 1, + showEmail: 1, + showPhone: 1, + teams: 1, + username: 1, + zip: 1 + } + } + ]); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'User not found' }); + } + + console.log(`User ${userId} failed to be found at get-user`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'User not found' }); + } + + const dataResponse = Object.assign({}, user[0], { + ranking: user[0].ranking.length ? user[0].ranking[0].ranking + 1 : 1 + }); + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/users/index.js b/src/routes/users/index.js index ec792de..eb38e7a 100644 --- a/src/routes/users/index.js +++ b/src/routes/users/index.js @@ -1,43 +1,43 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const archiveUser = require('./archive-user'); -const blockUser = require('./block-user'); -const changePassword = require('./change-password'); -const createUser = require('./create-user'); -const deleteUser = require('./delete-user'); -const editUser = require('./edit-user'); -const getUser = require('./get-user'); -const getProfile = require('./get-profile'); -const listUsers = require('./list-users'); -const unblockUser = require('./unblock-user'); -const deactivateUser = require('./deactivate-user'); - -const router = new express.Router(); - -router.get('/profile', isAuthenticated({ isOptional: false }), getProfile); -router.put('/password', isAuthenticated({ isOptional: false }), changePassword); -router.get('', isAuthenticated({ isOptional: false }), listUsers); -router.post('', isAuthenticated({ isOptional: false }), createUser); -router.get('/:userId', getUser); -router.put('/:userId', isAuthenticated({ isOptional: false }), editUser); -router.delete( - '/deactivate', - isAuthenticated({ isOptional: false }), - deactivateUser -); -router.delete('/:userId', isAuthenticated({ isOptional: false }), deleteUser); -router.put( - '/:userId/archive', - isAuthenticated({ isOptional: false }), - archiveUser -); -router.put('/:userId/block', isAuthenticated({ isOptional: false }), blockUser); -router.put( - '/:userId/unblock', - isAuthenticated({ isOptional: false }), - unblockUser -); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const archiveUser = require('./archive-user'); +const blockUser = require('./block-user'); +const changePassword = require('./change-password'); +const createUser = require('./create-user'); +const deleteUser = require('./delete-user'); +const editUser = require('./edit-user'); +const getUser = require('./get-user'); +const getProfile = require('./get-profile'); +const listUsers = require('./list-users'); +const unblockUser = require('./unblock-user'); +const deactivateUser = require('./deactivate-user'); + +const router = new express.Router(); + +router.get('/profile', isAuthenticated({ isOptional: false }), getProfile); +router.put('/password', isAuthenticated({ isOptional: false }), changePassword); +router.get('', isAuthenticated({ isOptional: false }), listUsers); +router.post('', isAuthenticated({ isOptional: false }), createUser); +router.get('/:userId', getUser); +router.put('/:userId', isAuthenticated({ isOptional: false }), editUser); +router.delete( + '/deactivate', + isAuthenticated({ isOptional: false }), + deactivateUser +); +router.delete('/:userId', isAuthenticated({ isOptional: false }), deleteUser); +router.put( + '/:userId/archive', + isAuthenticated({ isOptional: false }), + archiveUser +); +router.put('/:userId/block', isAuthenticated({ isOptional: false }), blockUser); +router.put( + '/:userId/unblock', + isAuthenticated({ isOptional: false }), + unblockUser +); + +module.exports = router; diff --git a/src/routes/users/list-users.js b/src/routes/users/list-users.js index 543cd98..a3d7e7b 100644 --- a/src/routes/users/list-users.js +++ b/src/routes/users/list-users.js @@ -1,75 +1,75 @@ -const { User } = require('../../models/user'); - -const { validateListUsers } = require('./validations'); - -module.exports = async (req, res, next) => { - const { errors, isValid } = validateListUsers(req.query); - if (!isValid) return res.status(400).json(errors); - - const queryParams = req.query; - - const usersQuery = { isArchived: false }; - usersQuery.$text = { $search: queryParams.keywords || '' }; - - const sort = queryParams.sortBy || { - score: { $meta: 'textScore' } - }; - let page = queryParams.page ? parseInt(queryParams.page, 10) - 1 : 1; - const pageLimit = queryParams.pageLimit - ? parseInt(queryParams.pageLimit, 10) - : 12; - - let total; - let users; - try { - [users, total] = await Promise.all([ - User.aggregate() - .match(usersQuery) - .project({ - _id: 0, - id: '$_id', - avatar: 1, - email: 1, - firstName: 1, - lastName: 1, - score: { $meta: 'textScore' }, - username: 1 - }) - .match({ score: { $gt: 1 } }) - .sort(sort) - .skip(page * pageLimit) - .limit(pageLimit), - User.find(usersQuery).count() - ]); - } catch (err) { - console.log( - `Users failed to be found or count at list-users.\nusersQuery: ${JSON.stringify( - usersQuery - )}` - ); - return next(err); - } - - let lastPage = Math.ceil(total / pageLimit); - if (lastPage > 0) { - page += 1; - if (page > lastPage) { - return res - .status(400) - .json({ page: `Should be less than or equal to ${lastPage}` }); - } - } else { - page = null; - lastPage = null; - } - - const dataResponse = { - page, - lastPage, - pageLimit, - total, - sortBy: queryParams.sortBy, - results: users - }; - return res.status(200).json(dataResponse); -}; +const { User } = require('../../models/user'); + +const { validateListUsers } = require('./validations'); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateListUsers(req.query); + if (!isValid) return res.status(400).json(errors); + + const queryParams = req.query; + + const usersQuery = { isArchived: false }; + usersQuery.$text = { $search: queryParams.keywords || '' }; + + const sort = queryParams.sortBy || { + score: { $meta: 'textScore' } + }; + let page = queryParams.page ? parseInt(queryParams.page, 10) - 1 : 1; + const pageLimit = queryParams.pageLimit + ? parseInt(queryParams.pageLimit, 10) + : 12; + + let total; + let users; + try { + [users, total] = await Promise.all([ + User.aggregate() + .match(usersQuery) + .project({ + _id: 0, + id: '$_id', + avatar: 1, + email: 1, + firstName: 1, + lastName: 1, + score: { $meta: 'textScore' }, + username: 1 + }) + .match({ score: { $gt: 1 } }) + .sort(sort) + .skip(page * pageLimit) + .limit(pageLimit), + User.find(usersQuery).count() + ]); + } catch (err) { + console.log( + `Users failed to be found or count at list-users.\nusersQuery: ${JSON.stringify( + usersQuery + )}` + ); + return next(err); + } + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + page += 1; + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be less than or equal to ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + + const dataResponse = { + page, + lastPage, + pageLimit, + total, + sortBy: queryParams.sortBy, + results: users + }; + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/users/unblock-user.js b/src/routes/users/unblock-user.js index 88a9c17..3340936 100644 --- a/src/routes/users/unblock-user.js +++ b/src/routes/users/unblock-user.js @@ -1,41 +1,41 @@ -const moment = require('moment'); - -const { User } = require('../../models/user'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const userId = req.params.userId; - - let user; - try { - user = await User.findOne({ _id: userId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); - } - - console.log(`User with Id ${userId} failed to be found at unblock-user.`); - return next(err); - } - - if (!user) { - return res.status(404).json({ general: 'User not found' }); - } - - user.isBlocked = false; - user.updatedAt = moment.utc().toDate(); - - try { - await user.save(); - } catch (err) { - console.log( - `User with Id ${user.id} failed to be updated at unblock-user.` - ); - return next(err); - } - - return res.status(200).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { User } = require('../../models/user'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const userId = req.params.userId; + + let user; + try { + user = await User.findOne({ _id: userId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'User not found' }); + } + + console.log(`User with Id ${userId} failed to be found at unblock-user.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: 'User not found' }); + } + + user.isBlocked = false; + user.updatedAt = moment.utc().toDate(); + + try { + await user.save(); + } catch (err) { + console.log( + `User with Id ${user.id} failed to be updated at unblock-user.` + ); + return next(err); + } + + return res.status(200).json({ general: 'Success' }); +}; diff --git a/src/routes/users/validations.js b/src/routes/users/validations.js index 66236ae..d59b5f9 100644 --- a/src/routes/users/validations.js +++ b/src/routes/users/validations.js @@ -1,299 +1,299 @@ -const freemail = require('freemail'); -const { isEmail, isInt } = require('validator'); -const { isEmpty } = require('lodash'); -const slugify = require('speakingurl'); - -const { cleanSpaces } = require('../../helpers'); -const { User } = require('../../models/user'); - -module.exports = { - validateChangePassword(data) { - const errors = {}; - - if (!data.oldPassword) { - errors.oldPassword = 'Is required'; - } else if (typeof data.oldPassword !== 'string') { - errors.oldPassword = 'Should be a string'; - } - - if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; - } else if (data.password.length < 8) { - errors.password = 'Should have more than 7 characters'; - } else if (data.password.length > 30) { - errors.password = 'Should have less than 31 characters'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateCreateUser(data) { - const errors = {}; - - if (data.description) { - if (typeof data.description !== 'string') { - errors.description = 'Should be a string'; - } else if (cleanSpaces(data.description).length > 2000) { - errors.description = 'Should have less than 2001 characters'; - } - } - - if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; - } else if (cleanSpaces(data.email).length > 254) { - errors.email = 'Should have less than 255 characters'; - } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { - errors.email = 'Is not a valid email'; - } - - if (!data.firstName) { - errors.firstName = 'Is required'; - } else if (typeof data.firstName !== 'string') { - errors.firstName = 'Should be a string'; - } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName)) { - errors.firstName = 'Should only have letters'; - } else if (cleanSpaces(data.firstName).length > 24) { - errors.firstName = 'Should have less than 25 characters'; - } else { - const firstName = cleanSpaces(data.firstName); - - if (firstName.split(' ').length > 1) { - errors.firstName = 'Should only be one name'; - } - } - - if (!data.lastName) { - errors.lastName = 'Is required'; - } else if (typeof data.lastName !== 'string') { - errors.lastName = 'Should be a string'; - } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { - errors.lastName = 'Should only have letters'; - } else if (cleanSpaces(data.lastName).length > 36) { - errors.lastName = 'Should have less than 37 characters'; - } else { - const lastName = cleanSpaces(data.lastName); - - if (lastName.split(' ').length > 1) { - errors.lastName = 'Should only be one last name'; - } - } - - if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; - } else if (data.password.length < 8) { - errors.password = 'Should be more than 7 characters'; - } else if (data.password.length > 30) { - errors.password = 'Should be less than 31 characters'; - } - - if (data.phone) { - if (typeof data.phone !== 'string') { - errors.phone = 'Should be a string'; - } else if (cleanSpaces(data.phone).length > 50) { - errors.phone = 'Should have less than 51 characters'; - } - } - - if (data.username) { - if (typeof data.username !== 'string') { - errors.username = 'Should be a string'; - } else if (cleanSpaces(data.username).length > 67) { - errors.username = 'Should have less than 68 characters'; - } else { - const username = slugify(data.username); - - if (username !== data.username) { - errors.username = 'Should only have lowercase letters and hyphens'; - } - } - } - - if (data.zip) { - if (typeof data.zip !== 'string') { - errors.zip = 'Should be a string'; - } else if (cleanSpaces(data.zip).length > 32) { - errors.zip = 'Should have less than 33 characters'; - } - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateEditUser(data) { - const errors = {}; - - if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { - errors.avatar = 'Should be a string'; - } - - if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' - ) { - errors.description = 'Should be a string'; - } - - if (typeof data.disabilities !== 'undefined') { - if (!Array.isArray(data.disabilities)) { - errors.disabilities = 'Should be an array'; - } else { - const disabilitiesTypes = [ - 'brain', - 'cognitive', - 'hearing', - 'invisible', - 'none', - 'other', - 'physical', - 'private', - 'psychological', - 'spinal-cord', - 'vision' - ]; - data.disabilities.some(d => { - if (typeof d !== 'string') { - errors.disabilities = 'All values should be strings'; - return true; - } else if (!disabilitiesTypes.includes(d)) { - errors.disabilities = 'All values should be valid disabilities'; - return true; - } - }); - } - } - - if (typeof data.firstName !== 'undefined') { - if (typeof data.firstName !== 'string') { - errors.firstName = 'Should be a string'; - } else if (data.firstName === '') { - errors.firstName = 'Is required'; - } else if ( - /[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName) - ) { - errors.firstName = 'Should only have letters'; - } else { - const firstName = cleanSpaces(data.firstName); - - if (firstName.split(' ').length > 1) { - errors.firstName = 'Should only be one first name'; - } - } - } - - if (typeof data.gender !== 'undefined') { - const gendersTypes = User.schema.path('gender').enumValues; - if (typeof data.gender !== 'string') { - errors.gender = 'Should be a string'; - } else if (data.gender === '') { - errors.gender = 'Is required'; - } else if (!gendersTypes.includes(data.gender)) { - errors.gender = 'Should be a valid gender'; - } - } - - if ( - typeof data.isSubscribed !== 'undefined' && - typeof data.isSubscribed !== 'boolean' - ) { - errors.isSubscribed = 'Should be a boolean'; - } - - if (typeof data.lastName !== 'undefined') { - if (typeof data.lastName !== 'string') { - errors.lastName = 'Should be a string'; - } else if (data.lastName === '') { - errors.lastName = 'Is required'; - } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { - errors.lastName = 'Should only have letters'; - } else { - const lastName = cleanSpaces(data.lastName); - - if (lastName.split(' ').length > 1) { - errors.lastName = 'Should only be one last name'; - } - } - } - - if (typeof data.phone !== 'undefined' && typeof data.phone !== 'string') { - errors.phone = 'Should be a string'; - } - - if ( - typeof data.showDisabilities !== 'undefined' && - typeof data.showDisabilities !== 'boolean' - ) { - errors.showDisabilities = 'Should be a boolean'; - } - - if ( - typeof data.showEmail !== 'undefined' && - typeof data.showEmail !== 'boolean' - ) { - errors.showEmail = 'Should be a boolean'; - } - - if ( - typeof data.showPhone !== 'undefined' && - typeof data.showPhone !== 'boolean' - ) { - errors.showPhone = 'Should be a boolean'; - } - - if (typeof data.username !== 'undefined') { - if (typeof data.username !== 'string') { - errors.username = 'Should be a string'; - } else if (data.username === '') { - errors.username = 'Is required'; - } else { - const username = slugify(data.username); - - if (username !== data.username) { - errors.username = 'Should only have lowercase letters and hyphens'; - } - } - } - - if (typeof data.zip !== 'undefined' && typeof data.zip !== 'string') { - errors.zip = 'Should be a string'; - } - - return { errors, isValid: isEmpty(errors) }; - }, - validateListUsers(queryParams) { - const errors = {}; - - if (queryParams.page && !isInt(queryParams.page)) { - errors.page = 'Should be a integer'; - } else if (parseInt(queryParams.page, 10) < 1) { - errors.page = 'Should be greater than or equal to 1'; - } - - if (queryParams.pageLimit && !isInt(queryParams.pageLimit)) { - errors.pageLimit = 'Should be a integer'; - } else if (parseInt(queryParams.pageLimit, 10) < 1) { - errors.pageLimit = 'Should be greater than or equal to 1'; - } else if (parseInt(queryParams.pageLimit, 10) > 12) { - errors.pageLimit = 'Should be less than or equal to 12'; - } - - const sortOptions = [ - 'email', - '-email', - 'firstName', - '-firstName', - 'lastName', - '-lastName', - 'username', - '-username' - ]; - if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { - errors.sortBy = 'Should be a valid sort'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const freemail = require('freemail'); +const { isEmail, isInt } = require('validator'); +const { isEmpty } = require('lodash'); +const slugify = require('speakingurl'); + +const { cleanSpaces } = require('../../helpers'); +const { User } = require('../../models/user'); + +module.exports = { + validateChangePassword(data) { + const errors = {}; + + if (!data.oldPassword) { + errors.oldPassword = 'Is required'; + } else if (typeof data.oldPassword !== 'string') { + errors.oldPassword = 'Should be a string'; + } + + if (!data.password) { + errors.password = 'Is required'; + } else if (typeof data.password !== 'string') { + errors.password = 'Should be a string'; + } else if (data.password.length < 8) { + errors.password = 'Should have more than 7 characters'; + } else if (data.password.length > 30) { + errors.password = 'Should have less than 31 characters'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateCreateUser(data) { + const errors = {}; + + if (data.description) { + if (typeof data.description !== 'string') { + errors.description = 'Should be a string'; + } else if (cleanSpaces(data.description).length > 2000) { + errors.description = 'Should have less than 2001 characters'; + } + } + + if (!data.email) { + errors.email = 'Is required'; + } else if (typeof data.email !== 'string') { + errors.email = 'Should be a string'; + } else if (cleanSpaces(data.email).length > 254) { + errors.email = 'Should have less than 255 characters'; + } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { + errors.email = 'Is not a valid email'; + } + + if (!data.firstName) { + errors.firstName = 'Is required'; + } else if (typeof data.firstName !== 'string') { + errors.firstName = 'Should be a string'; + } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName)) { + errors.firstName = 'Should only have letters'; + } else if (cleanSpaces(data.firstName).length > 24) { + errors.firstName = 'Should have less than 25 characters'; + } else { + const firstName = cleanSpaces(data.firstName); + + if (firstName.split(' ').length > 1) { + errors.firstName = 'Should only be one name'; + } + } + + if (!data.lastName) { + errors.lastName = 'Is required'; + } else if (typeof data.lastName !== 'string') { + errors.lastName = 'Should be a string'; + } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { + errors.lastName = 'Should only have letters'; + } else if (cleanSpaces(data.lastName).length > 36) { + errors.lastName = 'Should have less than 37 characters'; + } else { + const lastName = cleanSpaces(data.lastName); + + if (lastName.split(' ').length > 1) { + errors.lastName = 'Should only be one last name'; + } + } + + if (!data.password) { + errors.password = 'Is required'; + } else if (typeof data.password !== 'string') { + errors.password = 'Should be a string'; + } else if (data.password.length < 8) { + errors.password = 'Should be more than 7 characters'; + } else if (data.password.length > 30) { + errors.password = 'Should be less than 31 characters'; + } + + if (data.phone) { + if (typeof data.phone !== 'string') { + errors.phone = 'Should be a string'; + } else if (cleanSpaces(data.phone).length > 50) { + errors.phone = 'Should have less than 51 characters'; + } + } + + if (data.username) { + if (typeof data.username !== 'string') { + errors.username = 'Should be a string'; + } else if (cleanSpaces(data.username).length > 67) { + errors.username = 'Should have less than 68 characters'; + } else { + const username = slugify(data.username); + + if (username !== data.username) { + errors.username = 'Should only have lowercase letters and hyphens'; + } + } + } + + if (data.zip) { + if (typeof data.zip !== 'string') { + errors.zip = 'Should be a string'; + } else if (cleanSpaces(data.zip).length > 32) { + errors.zip = 'Should have less than 33 characters'; + } + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateEditUser(data) { + const errors = {}; + + if (typeof data.avatar !== 'undefined' && typeof data.avatar !== 'string') { + errors.avatar = 'Should be a string'; + } + + if ( + typeof data.description !== 'undefined' && + typeof data.description !== 'string' + ) { + errors.description = 'Should be a string'; + } + + if (typeof data.disabilities !== 'undefined') { + if (!Array.isArray(data.disabilities)) { + errors.disabilities = 'Should be an array'; + } else { + const disabilitiesTypes = [ + 'brain', + 'cognitive', + 'hearing', + 'invisible', + 'none', + 'other', + 'physical', + 'private', + 'psychological', + 'spinal-cord', + 'vision' + ]; + data.disabilities.some((d) => { + if (typeof d !== 'string') { + errors.disabilities = 'All values should be strings'; + return true; + } else if (!disabilitiesTypes.includes(d)) { + errors.disabilities = 'All values should be valid disabilities'; + return true; + } + }); + } + } + + if (typeof data.firstName !== 'undefined') { + if (typeof data.firstName !== 'string') { + errors.firstName = 'Should be a string'; + } else if (data.firstName === '') { + errors.firstName = 'Is required'; + } else if ( + /[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName) + ) { + errors.firstName = 'Should only have letters'; + } else { + const firstName = cleanSpaces(data.firstName); + + if (firstName.split(' ').length > 1) { + errors.firstName = 'Should only be one first name'; + } + } + } + + if (typeof data.gender !== 'undefined') { + const gendersTypes = User.schema.path('gender').enumValues; + if (typeof data.gender !== 'string') { + errors.gender = 'Should be a string'; + } else if (data.gender === '') { + errors.gender = 'Is required'; + } else if (!gendersTypes.includes(data.gender)) { + errors.gender = 'Should be a valid gender'; + } + } + + if ( + typeof data.isSubscribed !== 'undefined' && + typeof data.isSubscribed !== 'boolean' + ) { + errors.isSubscribed = 'Should be a boolean'; + } + + if (typeof data.lastName !== 'undefined') { + if (typeof data.lastName !== 'string') { + errors.lastName = 'Should be a string'; + } else if (data.lastName === '') { + errors.lastName = 'Is required'; + } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { + errors.lastName = 'Should only have letters'; + } else { + const lastName = cleanSpaces(data.lastName); + + if (lastName.split(' ').length > 1) { + errors.lastName = 'Should only be one last name'; + } + } + } + + if (typeof data.phone !== 'undefined' && typeof data.phone !== 'string') { + errors.phone = 'Should be a string'; + } + + if ( + typeof data.showDisabilities !== 'undefined' && + typeof data.showDisabilities !== 'boolean' + ) { + errors.showDisabilities = 'Should be a boolean'; + } + + if ( + typeof data.showEmail !== 'undefined' && + typeof data.showEmail !== 'boolean' + ) { + errors.showEmail = 'Should be a boolean'; + } + + if ( + typeof data.showPhone !== 'undefined' && + typeof data.showPhone !== 'boolean' + ) { + errors.showPhone = 'Should be a boolean'; + } + + if (typeof data.username !== 'undefined') { + if (typeof data.username !== 'string') { + errors.username = 'Should be a string'; + } else if (data.username === '') { + errors.username = 'Is required'; + } else { + const username = slugify(data.username); + + if (username !== data.username) { + errors.username = 'Should only have lowercase letters and hyphens'; + } + } + } + + if (typeof data.zip !== 'undefined' && typeof data.zip !== 'string') { + errors.zip = 'Should be a string'; + } + + return { errors, isValid: isEmpty(errors) }; + }, + validateListUsers(queryParams) { + const errors = {}; + + if (queryParams.page && !isInt(queryParams.page)) { + errors.page = 'Should be a integer'; + } else if (parseInt(queryParams.page, 10) < 1) { + errors.page = 'Should be greater than or equal to 1'; + } + + if (queryParams.pageLimit && !isInt(queryParams.pageLimit)) { + errors.pageLimit = 'Should be a integer'; + } else if (parseInt(queryParams.pageLimit, 10) < 1) { + errors.pageLimit = 'Should be greater than or equal to 1'; + } else if (parseInt(queryParams.pageLimit, 10) > 12) { + errors.pageLimit = 'Should be less than or equal to 12'; + } + + const sortOptions = [ + 'email', + '-email', + 'firstName', + '-firstName', + 'lastName', + '-lastName', + 'username', + '-username' + ]; + if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { + errors.sortBy = 'Should be a valid sort'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/routes/venues/archive-venue.js b/src/routes/venues/archive-venue.js index af8a0c6..bfaf8b9 100644 --- a/src/routes/venues/archive-venue.js +++ b/src/routes/venues/archive-venue.js @@ -1,39 +1,39 @@ -const moment = require('moment'); - -const { Venue } = require('../../models/venue'); - -module.exports = async (req, res, next) => { - if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); - } - - const venueId = req.params.venueId; - - let venue; - try { - venue = await Venue.findOne({ _id: venueId, isArchived: false }); - } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Venue not found' }); - } - - console.log(`Venue ${venueId} failed to be found at delete-venue`); - return next(err); - } - - if (!venue) { - return res.status(404).json({ general: 'Venue not found' }); - } - - venue.isArchived = true; - venue.updatedAt = moment.utc().toDate(); - - try { - await venue.save(); - } catch (err) { - console.log(`Venue ${venue.id} failed to be updated at delete-venue`); - return next(err); - } - - return res.status(204).json({ general: 'Success' }); -}; +const moment = require('moment'); + +const { Venue } = require('../../models/venue'); + +module.exports = async (req, res, next) => { + if (!req.user.isAdmin) { + return res.status(403).json({ general: 'Forbidden action' }); + } + + const venueId = req.params.venueId; + + let venue; + try { + venue = await Venue.findOne({ _id: venueId, isArchived: false }); + } catch (err) { + if (err.name === 'CastError') { + return res.status(404).json({ general: 'Venue not found' }); + } + + console.log(`Venue ${venueId} failed to be found at delete-venue`); + return next(err); + } + + if (!venue) { + return res.status(404).json({ general: 'Venue not found' }); + } + + venue.isArchived = true; + venue.updatedAt = moment.utc().toDate(); + + try { + await venue.save(); + } catch (err) { + console.log(`Venue ${venue.id} failed to be updated at delete-venue`); + return next(err); + } + + return res.status(204).json({ general: 'Success' }); +}; diff --git a/src/routes/venues/get-venue.js b/src/routes/venues/get-venue.js index d1b3fe8..bc30464 100644 --- a/src/routes/venues/get-venue.js +++ b/src/routes/venues/get-venue.js @@ -1,347 +1,348 @@ -const axios = require('axios'); -const { isEqual } = require('lodash'); -const slugify = require('speakingurl'); - -const { Venue } = require('../../models/venue'); -const venueReviewSummary = require('../../helpers/venue-review-summary.js'); - -module.exports = async (req, res, next) => { - const placeId = req.params.placeId; - - let response; - try { - response = await axios.get( - `https://maps.googleapis.com/maps/api/place/details/json?placeid=${placeId}&key=${ - process.env.PLACES_API_KEY - }` - ); - } catch (err) { - console.log(`Place ${placeId} failed to be found at get-venue.`); - return next(err); - } - - const statusResponse = response.data.status; - if (statusResponse !== 'OK') { - return res.status(404).json({ general: 'Place not found' }); - } - - const placeData = response.data.result; - const dataResponse = {}; - dataResponse.address = placeData.formatted_address; - - let useStreetviewCover = false; - let streetViewError = false; - let streetViewResponse; - try { - streetViewResponse = await axios.get( - `https://maps.googleapis.com/maps/api/streetview/metadata?location=${slugify( - dataResponse.address - )}&key=${process.env.PLACES_API_KEY}` - ); - } catch (err) { - console.log(`Streetview for ${placeId} failed to be found at get-venue.`); - streetViewError = true; - } - - let streetViewPanoId; - if (!streetViewError) { - const streetViewMetadataStatus = streetViewResponse.data.status; - if (streetViewMetadataStatus == 'OK') { - useStreetviewCover = true; - streetViewPanoId = streetViewResponse.data.pano_id; - } - } - - if (useStreetviewCover) { - dataResponse.coverPhoto = `https://maps.googleapis.com/maps/api/streetview?key=${ - process.env.PLACES_API_KEY - }&size=800x400&fov=110&location=${slugify(dataResponse.address)}`; - //}&size=800x400&fov=110&heading=0&pano=${streetViewPanoId}`; - //seems like heading needs to be set when using pano id but not for the address - } else if (placeData.photos && placeData.photos.length > 0) { - dataResponse.coverPhoto = `https://maps.googleapis.com/maps/api/place/photo?key=${ - process.env.PLACES_API_KEY - }&maxwidth=500&photoreference=${placeData.photos[0].photo_reference}`; - } - - let coverPhotoLink = - //(useStreetviewCover) ? - `https://www.google.com/maps/@?api=1&map_action=pano&pano=${streetViewPanoId}&viewpoint=${ - placeData.geometry.location.lat - },${placeData.geometry.location.lng}`; - console.log('Cover photo link: ', coverPhotoLink); - - dataResponse.formattedPhone = placeData.formatted_phone_number; - dataResponse.googleRating = placeData.rating; - dataResponse.googleUrl = placeData.url; - dataResponse.internationalPhone = placeData.international_phone_number; - dataResponse.location = { - lat: placeData.geometry.location.lat, - lng: placeData.geometry.location.lng - }; - dataResponse.name = placeData.name; - dataResponse.placeId = placeId; - dataResponse.types = placeData.types; - dataResponse.website = placeData.website; - - dataResponse.allowsGuideDog = { yes: 0, no: 0 }; - //dataResponse.bathroomReviews = 0; - //dataResponse.bathroomScore = null; - //dataResponse.entryReviews = 0; - //dataResponse.entryScore = null; - dataResponse.hasParking = { yes: 0, no: 0 }; - dataResponse.hasSecondEntry = { yes: 0, no: 0 }; - dataResponse.hasWellLit = { yes: 0, no: 0 }; - dataResponse.isQuiet = { yes: 0, no: 0 }; - dataResponse.isSpacious = { yes: 0, no: 0 }; - dataResponse.steps = { - zero: 0, - one: 0, - two: 0, - moreThanTwo: 0 - }; - - //new expanded fields - dataResponse.hasPermanentRamp = { yes: 0, no: 0 }; - dataResponse.hasPortableRamp = { yes: 0, no: 0 }; - dataResponse.hasWideEntrance = { yes: 0, no: 0 }; - dataResponse.hasAccessibleTableHeight = { yes: 0, no: 0 }; - dataResponse.hasAccessibleElevator = { yes: 0, no: 0 }; - dataResponse.hasInteriorRamp = { yes: 0, no: 0 }; - dataResponse.hasSwingOutDoor = { yes: 0, no: 0 }; - dataResponse.hasLargeStall = { yes: 0, no: 0 }; - dataResponse.hasSupportAroundToilet = { yes: 0, no: 0 }; - dataResponse.hasLoweredSinks = { yes: 0, no: 0 }; - - dataResponse.entranceScore = 0; - dataResponse.entranceGlyphs = ''; - dataResponse.interiorScore = 0; - dataResponse.interiorGlyphs = ''; - dataResponse.restroomScore = 0; - dataResponse.restroomGlyphs = ''; - dataResponse.mapMarkerScore = 0; - - let venue; - let venueToSave; - try { - [venue, venueToSave] = await Promise.all([ - Venue.aggregate([ - { - $match: { placeId, isArchived: false } - }, - { - $lookup: { - from: 'reviews', - let: { reviews: '$reviews' }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$reviews'] - } - } - }, - { - $lookup: { - from: 'users', - let: { user: '$user' }, - pipeline: [ - { - $match: { - $expr: { - $eq: ['$_id', '$$user'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - avatar: 1, - firstName: 1, - lastName: 1 - } - } - ], - as: 'user' - } - }, - { - $project: { - _id: 0, - id: '$_id', - //bathroomScore: 1, - comments: 1, - createdAt: 1, - //entryScore: 1, - user: 1, - voters: 1 - } - } - ], - as: 'reviews' - } - }, - { - $lookup: { - from: 'photos', - let: { photos: { $ifNull: ['$photos', []] } }, - pipeline: [ - { - $match: { - $expr: { - $in: ['$_id', '$$photos'] - } - } - }, - { - $project: { - _id: 0, - id: '$_id', - url: 1 - } - } - ], - as: 'photos' - } - }, - { - $project: { - _id: 0, - id: '$_id', - address: 1, - description: 1, - allowsGuideDog: 1, - //bathroomReviews: 1, - //bathroomScore: 1, - //entryReviews: 1, - //entryScore: 1, - hasParking: 1, - hasSecondEntry: 1, - hasWellLit: 1, - isQuiet: 1, - isSpacious: 1, - location: 1, - name: 1, - photos: 1, - placeId: 1, - steps: 1, - types: 1, - reviews: 1, - hasPermanentRamp: 1, - hasPortableRamp: 1, - hasWideEntrance: 1, - hasAccessibleTableHeight: 1, - hasAccessibleElevator: 1, - hasInteriorRamp: 1, - hasSwingOutDoor: 1, - hasLargeStall: 1, - hasSupportAroundToilet: 1, - hasLoweredSinks: 1 - } - } - ]), - Venue.findOne({ placeId, isArchived: false }) - ]); - } catch (err) { - console.log( - `Venue with placeId ${placeId} failed to be found at get-venue` - ); - return next(err); - } - - if (venue && venue[0]) { - let venueHasUpdates = false; - if (venueToSave.address !== dataResponse.address) { - venueToSave.address = dataResponse.address; - venueHasUpdates = true; - } - if ( - venueToSave.location.coordinates[0] !== dataResponse.location.lng || - venueToSave.location.coordinates[1] !== dataResponse.location.lat - ) { - venueToSave.location.coordinates = [ - dataResponse.location.lng, - dataResponse.location.lat - ]; - venueHasUpdates = true; - } - if (venueToSave.name !== dataResponse.name) { - venueToSave.name = dataResponse.name; - venueHasUpdates = true; - } - if (!isEqual(venueToSave.types, dataResponse.types)) { - venueToSave.types = dataResponse.types; - venueHasUpdates = true; - } - - if (venueHasUpdates) { - try { - await venueToSave.save(); - } catch (err) { - console.log( - `Venue with id ${venueToSave.id} failed to be updated at get-venue.` - ); - return next(err); - } - } - - //TEMP: - let scoring; - //console.log('venue0: ', venue[0]); - - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue[0]); - console.log('entrance score: ', scoring); - dataResponse.entranceScore = scoring.ratingLevel; - dataResponse.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue[0]); - console.log('interior score: ', scoring); - dataResponse.interiorScore = scoring.ratingLevel; - dataResponse.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue[0]); - console.log('restroom score: ', scoring); - dataResponse.restroomScore = scoring.ratingLevel; - dataResponse.restroomGlyphs = scoring.ratingGlyphs; - - dataResponse.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - dataResponse.entranceScore, - dataResponse.interiorScore, - dataResponse.restroomScore - ); - - dataResponse.id = venue[0]._id; - - dataResponse.allowsGuideDog = venue[0].allowsGuideDog; - //dataResponse.bathroomReviews = venue[0].bathroomReviews; - //dataResponse.bathroomScore = venue[0].bathroomScore; - //dataResponse.entryReviews = venue[0].entryReviews; - //dataResponse.entryScore = venue[0].entryScore; - dataResponse.hasParking = venue[0].hasParking; - dataResponse.hasSecondEntry = venue[0].hasSecondEntry; - dataResponse.hasWellLit = venue[0].hasWellLit; - dataResponse.isQuiet = venue[0].isQuiet; - dataResponse.isSpacious = venue[0].isSpacious; - dataResponse.photos = venue[0].photos; - dataResponse.steps = venue[0].steps; - //new expanded fields - dataResponse.hasPermanentRamp = venue[0].hasPermanentRamp; - dataResponse.hasPortableRamp = venue[0].hasPortableRamp; - dataResponse.hasWideEntrance = venue[0].hasWideEntrance; - dataResponse.hasAccessibleTableHeight = venue[0].hasAccessibleTableHeight; - dataResponse.hasAccessibleElevator = venue[0].hasAccessibleElevator; - dataResponse.hasInteriorRamp = venue[0].hasInteriorRamp; - dataResponse.hasSwingOutDoor = venue[0].hasSwingOutDoor; - dataResponse.hasLargeStall = venue[0].hasLargeStall; - dataResponse.hasSupportAroundToilet = venue[0].hasSupportAroundToilet; - dataResponse.hasLoweredSinks = venue[0].hasLoweredSinks; - - dataResponse.reviews = venue[0].reviews; - } - - return res.status(200).json(dataResponse); -}; +const axios = require('axios'); +const { isEqual } = require('lodash'); +const slugify = require('speakingurl'); + +const { Venue } = require('../../models/venue'); +const venueReviewSummary = require('../../helpers/venue-review-summary.js'); + +module.exports = async (req, res, next) => { + const placeId = req.params.placeId; + + let response; + try { + response = await axios.get( + `https://maps.googleapis.com/maps/api/place/details/json?placeid=${placeId}&key=${ + process.env.PLACES_API_KEY + }` + ); + } catch (err) { + console.log(`Place ${placeId} failed to be found at get-venue.`); + return next(err); + } + + const statusResponse = response.data.status; + if (statusResponse !== 'OK') { + return res.status(404).json({ general: 'Place not found' }); + } + + const placeData = response.data.result; + const dataResponse = {}; + dataResponse.address = placeData.formatted_address; + + let useStreetviewCover = false; + let streetViewError = false; + let streetViewResponse; + try { + streetViewResponse = await axios.get( + `https://maps.googleapis.com/maps/api/streetview/metadata?location=${slugify( + dataResponse.address + )}&key=${process.env.PLACES_API_KEY}` + ); + } catch (err) { + console.error(err); + console.log(`Streetview for ${placeId} failed to be found at get-venue.`); + streetViewError = true; + } + + let streetViewPanoId; + if (!streetViewError) { + const streetViewMetadataStatus = streetViewResponse.data.status; + if (streetViewMetadataStatus == 'OK') { + useStreetviewCover = true; + streetViewPanoId = streetViewResponse.data.pano_id; + } + } + + if (useStreetviewCover) { + dataResponse.coverPhoto = `https://maps.googleapis.com/maps/api/streetview?key=${ + process.env.PLACES_API_KEY + }&size=800x400&fov=110&location=${slugify(dataResponse.address)}`; + //}&size=800x400&fov=110&heading=0&pano=${streetViewPanoId}`; + //seems like heading needs to be set when using pano id but not for the address + } else if (placeData.photos && placeData.photos.length > 0) { + dataResponse.coverPhoto = `https://maps.googleapis.com/maps/api/place/photo?key=${ + process.env.PLACES_API_KEY + }&maxwidth=500&photoreference=${placeData.photos[0].photo_reference}`; + } + + let coverPhotoLink = + //(useStreetviewCover) ? + `https://www.google.com/maps/@?api=1&map_action=pano&pano=${streetViewPanoId}&viewpoint=${ + placeData.geometry.location.lat + },${placeData.geometry.location.lng}`; + console.log('Cover photo link: ', coverPhotoLink); + + dataResponse.formattedPhone = placeData.formatted_phone_number; + dataResponse.googleRating = placeData.rating; + dataResponse.googleUrl = placeData.url; + dataResponse.internationalPhone = placeData.international_phone_number; + dataResponse.location = { + lat: placeData.geometry.location.lat, + lng: placeData.geometry.location.lng + }; + dataResponse.name = placeData.name; + dataResponse.placeId = placeId; + dataResponse.types = placeData.types; + dataResponse.website = placeData.website; + + dataResponse.allowsGuideDog = { yes: 0, no: 0 }; + //dataResponse.bathroomReviews = 0; + //dataResponse.bathroomScore = null; + //dataResponse.entryReviews = 0; + //dataResponse.entryScore = null; + dataResponse.hasParking = { yes: 0, no: 0 }; + dataResponse.hasSecondEntry = { yes: 0, no: 0 }; + dataResponse.hasWellLit = { yes: 0, no: 0 }; + dataResponse.isQuiet = { yes: 0, no: 0 }; + dataResponse.isSpacious = { yes: 0, no: 0 }; + dataResponse.steps = { + zero: 0, + one: 0, + two: 0, + moreThanTwo: 0 + }; + + //new expanded fields + dataResponse.hasPermanentRamp = { yes: 0, no: 0 }; + dataResponse.hasPortableRamp = { yes: 0, no: 0 }; + dataResponse.hasWideEntrance = { yes: 0, no: 0 }; + dataResponse.hasAccessibleTableHeight = { yes: 0, no: 0 }; + dataResponse.hasAccessibleElevator = { yes: 0, no: 0 }; + dataResponse.hasInteriorRamp = { yes: 0, no: 0 }; + dataResponse.hasSwingOutDoor = { yes: 0, no: 0 }; + dataResponse.hasLargeStall = { yes: 0, no: 0 }; + dataResponse.hasSupportAroundToilet = { yes: 0, no: 0 }; + dataResponse.hasLoweredSinks = { yes: 0, no: 0 }; + + dataResponse.entranceScore = 0; + dataResponse.entranceGlyphs = ''; + dataResponse.interiorScore = 0; + dataResponse.interiorGlyphs = ''; + dataResponse.restroomScore = 0; + dataResponse.restroomGlyphs = ''; + dataResponse.mapMarkerScore = 0; + + let venue; + let venueToSave; + try { + [venue, venueToSave] = await Promise.all([ + Venue.aggregate([ + { + $match: { placeId, isArchived: false } + }, + { + $lookup: { + from: 'reviews', + let: { reviews: '$reviews' }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$reviews'] + } + } + }, + { + $lookup: { + from: 'users', + let: { user: '$user' }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$_id', '$$user'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + avatar: 1, + firstName: 1, + lastName: 1 + } + } + ], + as: 'user' + } + }, + { + $project: { + _id: 0, + id: '$_id', + //bathroomScore: 1, + comments: 1, + createdAt: 1, + //entryScore: 1, + user: 1, + voters: 1 + } + } + ], + as: 'reviews' + } + }, + { + $lookup: { + from: 'photos', + let: { photos: { $ifNull: ['$photos', []] } }, + pipeline: [ + { + $match: { + $expr: { + $in: ['$_id', '$$photos'] + } + } + }, + { + $project: { + _id: 0, + id: '$_id', + url: 1 + } + } + ], + as: 'photos' + } + }, + { + $project: { + _id: 0, + id: '$_id', + address: 1, + description: 1, + allowsGuideDog: 1, + //bathroomReviews: 1, + //bathroomScore: 1, + //entryReviews: 1, + //entryScore: 1, + hasParking: 1, + hasSecondEntry: 1, + hasWellLit: 1, + isQuiet: 1, + isSpacious: 1, + location: 1, + name: 1, + photos: 1, + placeId: 1, + steps: 1, + types: 1, + reviews: 1, + hasPermanentRamp: 1, + hasPortableRamp: 1, + hasWideEntrance: 1, + hasAccessibleTableHeight: 1, + hasAccessibleElevator: 1, + hasInteriorRamp: 1, + hasSwingOutDoor: 1, + hasLargeStall: 1, + hasSupportAroundToilet: 1, + hasLoweredSinks: 1 + } + } + ]), + Venue.findOne({ placeId, isArchived: false }) + ]); + } catch (err) { + console.log( + `Venue with placeId ${placeId} failed to be found at get-venue` + ); + return next(err); + } + + if (venue && venue[0]) { + let venueHasUpdates = false; + if (venueToSave.address !== dataResponse.address) { + venueToSave.address = dataResponse.address; + venueHasUpdates = true; + } + if ( + venueToSave.location.coordinates[0] !== dataResponse.location.lng || + venueToSave.location.coordinates[1] !== dataResponse.location.lat + ) { + venueToSave.location.coordinates = [ + dataResponse.location.lng, + dataResponse.location.lat + ]; + venueHasUpdates = true; + } + if (venueToSave.name !== dataResponse.name) { + venueToSave.name = dataResponse.name; + venueHasUpdates = true; + } + if (!isEqual(venueToSave.types, dataResponse.types)) { + venueToSave.types = dataResponse.types; + venueHasUpdates = true; + } + + if (venueHasUpdates) { + try { + await venueToSave.save(); + } catch (err) { + console.log( + `Venue with id ${venueToSave.id} failed to be updated at get-venue.` + ); + return next(err); + } + } + + //TEMP: + let scoring; + //console.log('venue0: ', venue[0]); + + //calculate entranceScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('entrance', venue[0]); + console.log('entrance score: ', scoring); + dataResponse.entranceScore = scoring.ratingLevel; + dataResponse.entranceGlyphs = scoring.ratingGlyphs; + + //calculate interiorScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('interior', venue[0]); + console.log('interior score: ', scoring); + dataResponse.interiorScore = scoring.ratingLevel; + dataResponse.interiorGlyphs = scoring.ratingGlyphs; + + //calculate restroomScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('restroom', venue[0]); + console.log('restroom score: ', scoring); + dataResponse.restroomScore = scoring.ratingLevel; + dataResponse.restroomGlyphs = scoring.ratingGlyphs; + + dataResponse.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( + dataResponse.entranceScore, + dataResponse.interiorScore, + dataResponse.restroomScore + ); + + dataResponse.id = venue[0]._id; + + dataResponse.allowsGuideDog = venue[0].allowsGuideDog; + //dataResponse.bathroomReviews = venue[0].bathroomReviews; + //dataResponse.bathroomScore = venue[0].bathroomScore; + //dataResponse.entryReviews = venue[0].entryReviews; + //dataResponse.entryScore = venue[0].entryScore; + dataResponse.hasParking = venue[0].hasParking; + dataResponse.hasSecondEntry = venue[0].hasSecondEntry; + dataResponse.hasWellLit = venue[0].hasWellLit; + dataResponse.isQuiet = venue[0].isQuiet; + dataResponse.isSpacious = venue[0].isSpacious; + dataResponse.photos = venue[0].photos; + dataResponse.steps = venue[0].steps; + //new expanded fields + dataResponse.hasPermanentRamp = venue[0].hasPermanentRamp; + dataResponse.hasPortableRamp = venue[0].hasPortableRamp; + dataResponse.hasWideEntrance = venue[0].hasWideEntrance; + dataResponse.hasAccessibleTableHeight = venue[0].hasAccessibleTableHeight; + dataResponse.hasAccessibleElevator = venue[0].hasAccessibleElevator; + dataResponse.hasInteriorRamp = venue[0].hasInteriorRamp; + dataResponse.hasSwingOutDoor = venue[0].hasSwingOutDoor; + dataResponse.hasLargeStall = venue[0].hasLargeStall; + dataResponse.hasSupportAroundToilet = venue[0].hasSupportAroundToilet; + dataResponse.hasLoweredSinks = venue[0].hasLoweredSinks; + + dataResponse.reviews = venue[0].reviews; + } + + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/venues/index.js b/src/routes/venues/index.js index 2f35371..94fec3d 100644 --- a/src/routes/venues/index.js +++ b/src/routes/venues/index.js @@ -1,19 +1,19 @@ -const express = require('express'); - -const { isAuthenticated } = require('../../helpers'); - -const archiveVenue = require('./archive-venue'); -const getVenue = require('./get-venue'); -const listVenues = require('./list-venues'); - -const router = new express.Router(); - -router.get('', listVenues); -router.get('/:placeId', getVenue); -router.put( - '/:venueId/archive', - isAuthenticated({ isOptional: false }), - archiveVenue -); - -module.exports = router; +const express = require('express'); + +const { isAuthenticated } = require('../../helpers'); + +const archiveVenue = require('./archive-venue'); +const getVenue = require('./get-venue'); +const listVenues = require('./list-venues'); + +const router = new express.Router(); + +router.get('', listVenues); +router.get('/:placeId', getVenue); +router.put( + '/:venueId/archive', + isAuthenticated({ isOptional: false }), + archiveVenue +); + +module.exports = router; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index 306ddd9..81b6821 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -1,642 +1,630 @@ -const axios = require('axios'); -const { find, isEmpty } = require('lodash'); -const slugify = require('speakingurl'); - -const { isNumber } = require('../../helpers'); -const { Venue } = require('../../models/venue'); - -const { validateListVenues } = require('./validations'); -const venueReviewSummary = require('../../helpers/venue-review-summary.js'); - -module.exports = async (req, res, next) => { - const queryParams = req.query; - - const { errors, isValid } = validateListVenues(queryParams); - if (!isValid) return res.status(400).json(errors); - - let coordinates = queryParams.location.split(','); - - //Legacy function from two-bar search, geocodes from string address - if (queryParams.address && !queryParams.page) { - console.log('in address conditional, ', queryParams); - queryParams.name = queryParams.address; - const geocodeParams = `?key=${process.env.PLACES_API_KEY}&address=${slugify( - queryParams.address - )}`; - - let geocodeResponse; - try { - geocodeResponse = await axios.get( - `https://maps.googleapis.com/maps/api/geocode/json${geocodeParams}` - ); - } catch (err) { - console.log( - `Geocode failed to be found at list-venues.\nQuery Params: ${JSON.stringify( - queryParams - )}` - ); - return next(err); - } - - const statusCode = geocodeResponse.data.status; - if (statusCode === 'ZERO_RESULTS') { - return res.status(404).json({ keywords: 'Address not found' }); - } else if (statusCode === 'OVER_QUERY_LIMIT') { - return next(new Error('Over query limit with Google Places API')); - } else if (statusCode === 'REQUEST_DENIED') { - return next(new Error('Request denied with Google Places API')); - } else if (statusCode === 'INVALID_REQUEST') { - return next(new Error('Invalid request with Google Places API')); - } else if (statusCode === 'UNKNOWN_ERROR') { - return next(new Error('Unknown error with Google Places API')); - } - - coordinates = [ - geocodeResponse.data.results[0].geometry.location.lat, - geocodeResponse.data.results[0].geometry.location.lng - ]; - } //end address geocode - - let venuesFilters = {}; - let dbVenuesFilters = {}; - - /* - * Legacy filter string building function, - * has a critical defect condition where if - * no > yes but yes is at least 1, then there - * would be a false match. - */ - if (queryParams.entranceScore) { - venuesFilters.entranceScore = parseFloat(queryParams.entranceScore); - //{ $gte: parseFloat(queryParams.entranceScore) }; - } - - if (queryParams.interiorScore) { - venuesFilters.interiorScore = parseFloat(queryParams.interiorScore); - //{ $gte: parseFloat(queryParams.interiorScore) }; - } - - if (queryParams.restroomScore) { - venuesFilters.restroomScore = parseFloat(queryParams.restroomScore); - //{ $gte: parseFloat(queryParams.restroomScore) }; - } - - if (queryParams.allowsGuideDog) { - venuesFilters.allowsGuideDog = parseFloat(queryParams.allowsGuideDog); - - const allowsGuideDog = parseFloat(queryParams.allowsGuideDog) === 1; - if (allowsGuideDog) { - dbVenuesFilters['allowsGuideDog.yes'] = { $gte: 1 }; - } else { - dbVenuesFilters['allowsGuideDog.no'] = { $gte: 1 }; - } - } - - if (queryParams.hasParking) { - venuesFilters.hasParking = queryParams.hasParking; - - const hasParking = parseFloat(queryParams.hasParking) === 1; - if (hasParking) { - dbVenuesFilters['hasParking.yes'] = { $gte: 1 }; - } else { - dbVenuesFilters['hasParking.no'] = { $gte: 1 }; - } - } - - /* - * Not used - * - if (queryParams.hasRamp) { - const hasRamp = parseFloat(queryParams.hasRamp) === 1; - if (hasRamp) { - venuesFilters['hasRamp.yes'] = { $gte: 1 }; - } else { - venuesFilters['hasRamp.no'] = { $gte: 1 }; - } - } - - if (queryParams.hasSecondEntry) { - const hasSecondEntry = parseFloat(queryParams.hasSecondEntry) === 1; - if (hasSecondEntry) { - venuesFilters['hasSecondEntry.yes'] = { $gte: 1 }; - } else { - venuesFilters['hasSecondEntry.no'] = { $gte: 1 }; - } - } - - if (queryParams.hasWellLit) { - const hasWellLit = parseFloat(queryParams.hasWellLit) === 1; - if (hasWellLit) { - venuesFilters['hasWellLit.yes'] = { $gte: 1 }; - } else { - venuesFilters['hasWellLit.no'] = { $gte: 1 }; - } - } - - if (queryParams.isQuiet) { - const isQuiet = parseFloat(queryParams.isQuiet) === 1; - if (isQuiet) { - venuesFilters['isQuiet.yes'] = { $gte: 1 }; - } else { - venuesFilters['isQuiet.no'] = { $gte: 1 }; - } - } - - if (queryParams.isSpacious) { - const isSpacious = parseFloat(queryParams.isSpacious) === 1; - if (isSpacious) { - venuesFilters['isSpacious.yes'] = { $gte: 1 }; - } else { - venuesFilters['isSpacious.no'] = { $gte: 1 }; - } - } - - if (queryParams.steps) { - if (parseFloat(queryParams.steps) === 0) { - venuesFilters['steps.zero'] = { $gte: 1 }; - } else if (parseFloat(queryParams.steps) === 1) { - venuesFilters['steps.one'] = { $gte: 1 }; - } else if (parseFloat(queryParams.steps) === 2) { - venuesFilters['steps.two'] = { $gte: 1 }; - } else if (parseFloat(queryParams.steps) === 3) { - venuesFilters['steps.moreThanTwo'] = { $gte: 1 }; - } - } - * - */ - - let dataResponse; - - /* - * Legacy filtering function that searches solely on - * AXS Venue data and provides it's own pagination of 20 - * UPDATED 05/2020 TO SUPPORT FILTER ONLY SELF SEARCH - */ - if (!isEmpty(venuesFilters) && isEmpty(queryParams.name)) { - console.log('>> Performing DB search'); - /* - if (queryParams.name) { - //performs literal name match against AXS Venue name - venuesFilters.name = { $regex: queryParams.name, $options: 'i' }; - } - */ - - dbVenuesFilters.location = { - $near: { - $geometry: { - type: 'Point', - coordinates: [coordinates[1], coordinates[0]] - }, - $maxDistance: 50000 - } - }; - - if (queryParams.type) { - dbVenuesFilters.types = queryParams.type; - } - - dbVenuesFilters.isArchived = false; - - let page = 1; - if (isNumber(queryParams.page)) { - page = queryParams.page; - } - - const pageLimit = - venuesFilters.hasOwnProperty('entranceScore') || - venuesFilters.hasOwnProperty('interiorScore') || - venuesFilters.hasOwnProperty('restroomScore') - ? 80 - : 20; - - if (page > 0) { - page -= 1; - } else { - return res - .status(400) - .json({ page: 'Should be equal to or greater than 1' }); - } - - let total; - let venues; - try { - [venues, total] = await Promise.all([ - Venue.find( - dbVenuesFilters - /*,'address allowsGuideDog hasParking hasSecondEntry hasWellLit isQuiet isSpacious location name photos placeId steps types'*/ - ) - .skip(page * pageLimit) - .limit(pageLimit), - Venue.find(dbVenuesFilters).count() - /*TODO: count is deprecated in favor of countDocuments, but that does not support $near - would need to move to GeoWithin but that does not return sorted results - */ - ]); - } catch (err) { - console.log( - `Venues failed to be found or count at list-venues.\nvenuesQuery: ${JSON.stringify( - dbVenuesFilters - )}` - ); - console.log(err); - return next(err); - } - - venues = venues.map(venue => - Object.assign({}, venue.toObject(), { - id: venue._id, - _id: undefined, - location: venue.coordinates - }) - ); - - //+ADDED - //Perform ratings logic on all returned venues - console.log('Raw venues count: ' + venues.length); - venues = venues.filter(venue => { - //console.log('In scoring assignment'); - let scoring; - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); - venue.entranceScore = scoring.ratingLevel; - venue.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); - venue.interiorScore = scoring.ratingLevel; - venue.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); - venue.restroomScore = scoring.ratingLevel; - venue.restroomGlyphs = scoring.ratingGlyphs; - - venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - venue.entranceScore, - venue.interiorScore, - venue.restroomScore - ); - - let passesValidation = true; - if (venuesFilters.hasOwnProperty('entranceScore')) { - if ( - !venue.entranceScore || - venue.entranceScore < venuesFilters.entranceScore - ) { - passesValidation = false; - } - } - - if (passesValidation && venuesFilters.hasOwnProperty('interiorScore')) { - if ( - !venue.interiorScore || - venue.interiorScore < venuesFilters.interiorScore - ) { - passesValidation = false; - } - } - - if (passesValidation && venuesFilters.hasOwnProperty('restroomScore')) { - if ( - !venue.restroomScore || - venue.restroomScore < venuesFilters.restroomScore - ) { - passesValidation = false; - } - } - - if (passesValidation) { - return venue; - } - }); - - const lastPage = Math.ceil(total / pageLimit); - let nextPage; - if (lastPage > 0) { - page += 1; - if (page > lastPage || page > 3) { - return res.status(400).json({ - page: `Should be equal to or less than ${lastPage > 3 ? 3 : lastPage}` - }); - } - } - - dataResponse = { - nextPage, - results: venues - }; - /* - * End legacy filter - */ - } else { - console.log('>> Performing Google search'); - - /* - * Perform Google search when there text entered or no filters selected - */ - let nearbyParams = `?key=${process.env.PLACES_API_KEY}`; - let searchType = queryParams.name ? 'textsearch' : 'nearbysearch'; - - if (!queryParams.page) { - nearbyParams = `${nearbyParams}&location=${coordinates[0]},${ - coordinates[1] - //}&rankby=distance`; - }`; - - if (queryParams.name) { - //nearbyParams = `${nearbyParams}&keyword=${queryParams.name}`; - nearbyParams = `${nearbyParams}&query=${queryParams.name}&radius=5000`; - } else { - //empty search, such as on load - nearbyParams = `${nearbyParams}&rankby=distance`; - } - - if (queryParams.type) { - nearbyParams = `${nearbyParams}&type=${queryParams.type}`; - } else { - nearbyParams = `${nearbyParams}&type=establishment`; - } - } else { - nearbyParams = `${nearbyParams}&pagetoken=${queryParams.page}`; - } - - if (queryParams.rankby) { - nearbyParams = `${nearbyParams}&rankby=${queryParams.rankby}`; - } - if (queryParams.opennow) { - nearbyParams = `${nearbyParams}&opennow=${queryParams.opennow}`; - } - if (queryParams.minprice) { - nearbyParams = `${nearbyParams}&minprice=${queryParams.minprice}`; - } - if (queryParams.maxprice) { - nearbyParams = `${nearbyParams}&maxprice=${queryParams.maxprice}`; - } - - let placesResponse; - try { - console.log( - 'performing google search: ' + - `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` - ); - placesResponse = await axios.get( - `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` - ); - } catch (err) { - console.log( - `Places failed to be found at list-venues.\nQuery Params: ${JSON.stringify( - queryParams - )}` - ); - return next(err); - } - - const statusCode = placesResponse.data.status; - if (statusCode === 'OVER_QUERY_LIMIT') { - return next(new Error('Over query limit with Google Places API')); - } else if (statusCode === 'REQUEST_DENIED') { - return next(new Error('Request denied with Google Places API')); - } else if (statusCode === 'INVALID_REQUEST') { - return next(new Error('Invalid request with Google Places API')); - } else if (statusCode === 'UNKNOWN_ERROR') { - return next(new Error('Unknown error with Google Places API')); - } - //do we need to check for 0? - - if (placesResponse.data.results.length == 1) { - if (placesResponse.data.results[0].types[0] == 'locality') { - console.log( - 'Found a city only: ', - placesResponse.data.results[0].geometry.location - ); - //TODO: redo search with new coordinates and no query/name or change/add "places in " to the first part of the string - } - } - - //Format Google Places results and get array of IDs - let places = []; - const placesIds = []; - placesResponse.data.results.forEach(place => { - let photo = ''; - if (place.photos) { - photo = `https://maps.googleapis.com/maps/api/place/photo?key=${ - process.env.PLACES_API_KEY - }&maxwidth=300&photoreference=${place.photos[0].photo_reference}`; - } - - places.push({ - //address: place.vicinity, - address: place.formatted_address, - location: { - lat: place.geometry.location.lat, - lng: place.geometry.location.lng - }, - name: place.name, - photo, - placeId: place.place_id, - types: place.types - }); - placesIds.push(place.place_id); - }); - - //Use array of Google Place IDs to find AXS Venues - let venues; - try { - venues = await Venue.find({ placeId: { $in: placesIds } }); - } catch (err) { - console.log( - `Venues failed to be found at list-venues.\nPlaces ids: [${placesIds}]` - ); - return next(err); - } - - //Perform ratings logic on all returned venues - venues.forEach(venue => { - //console.log('In scoring assignment'); - let scoring; - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); - venue.entranceScore = scoring.ratingLevel; - venue.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); - venue.interiorScore = scoring.ratingLevel; - venue.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); - venue.restroomScore = scoring.ratingLevel; - venue.restroomGlyphs = scoring.ratingGlyphs; - - venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - venue.entranceScore, - venue.interiorScore, - venue.restroomScore - ); - }); - - //Filter out, remove, Google Places that are not AXS Venues - // Can't use hasOwnProperty() on mongoose model objects // - if (!isEmpty(venuesFilters)) { - console.log('>> Performing secondary DB filtering'); - places = places.filter(place => { - const venue = find(venues, venue => venue.placeId === place.placeId); - if (venue) { - //console.log('In verification of filters'); - let passesValidation = true; - if ( - passesValidation && - venuesFilters.hasOwnProperty('allowsGuideDog') - ) { - if ( - !venue.allowsGuideDog || - venue.allowsGuideDog.yes < venue.allowsGuideDog.no || - venue.allowsGuideDog.yes == 0 - ) { - passesValidation = false; - } - } - - if (passesValidation && venuesFilters.hasOwnProperty('hasParking')) { - if ( - !venue.hasParking || - venue.hasParking.yes < venue.hasParking.no || - venue.hasParking.yes == 0 - ) { - passesValidation = false; - } - } - - if ( - passesValidation && - venuesFilters.hasOwnProperty('entranceScore') - ) { - if ( - !venue.entranceScore || - venue.entranceScore < venuesFilters.entranceScore - ) { - passesValidation = false; - } - } - - if ( - passesValidation && - venuesFilters.hasOwnProperty('interiorScore') - ) { - if ( - !venue.interiorScore || - venue.interiorScore < venuesFilters.interiorScore - ) { - passesValidation = false; - } - } - - if ( - passesValidation && - venuesFilters.hasOwnProperty('restroomScore') - ) { - if ( - !venue.restroomScore || - venue.restroomScore < venuesFilters.restroomScore - ) { - passesValidation = false; - } - } - - if (passesValidation) { - return venue; - } - } - }); - } //end filtering Google results - - // - places = places.map(place => { - const venue = find(venues, venue => venue.placeId === place.placeId); - if (venue) { - return Object.assign({}, place, { - //new expanded fields - hasPermanentRamp: venue.hasPermanentRamp, - hasPortableRamp: venue.hasPortableRamp, - hasWideEntrance: venue.hasWideEntrance, - hasAccessibleTableHeight: venue.hasAccessibleTableHeight, - hasAccessibleElevator: venue.hasAccessibleElevator, - hasInteriorRamp: venue.hasInteriorRamp, - hasSwingInDoor: venue.hasSwingInDoor, - hasSwingOutDoor: venue.hasSwingOutDoor, - hasLargeStall: venue.hasLargeStall, - hasSupportAroundToilet: venue.hasSupportAroundToilet, - hasLoweredSinks: venue.hasLoweredSinks, - - entranceScore: venue.entranceScore, - entranceGlyphs: venue.entranceGlyphs, - interiorScore: venue.interiorScore, - interiorGlyphs: venue.interiorGlyphs, - restroomScore: venue.restroomScore, - restroomGlyphs: venue.restroomGlyphs, - mapMarkerScore: venue.mapMarkerScore, - - //original fields - allowsGuideDog: venue.allowsGuideDog, - //_bathroomScore: venue.bathroomScore, - //_entryScore: venue.entryScore, - hasParking: venue.hasParking, - hasSecondEntry: venue.hasSecondEntry, - hasWellLit: venue.hasWellLit, - isQuiet: venue.isQuiet, - isSpacious: venue.isSpacious, - steps: venue.steps - }); - } - - //venue not found - return Object.assign({}, place, { - //new expanded fields - hasPermanentRamp: { yes: 0, no: 0 }, - hasPortableRamp: { yes: 0, no: 0 }, - hasWideEntrance: { yes: 0, no: 0 }, - hasAccessibleTableHeight: { yes: 0, no: 0 }, - hasAccessibleElevator: { yes: 0, no: 0 }, - hasInteriorRamp: { yes: 0, no: 0 }, - hasSwingInDoor: { yes: 0, no: 0 }, - hasSwingOutDoor: { yes: 0, no: 0 }, - hasLargeStall: { yes: 0, no: 0 }, - hasSupportAroundToilet: { yes: 0, no: 0 }, - hasLoweredSinks: { yes: 0, no: 0 }, - interiorScore: 0, - interiorGlyphs: 'interior', - restroomScore: 0, - restroomGlyphs: 'restroom', - entranceScore: 0, - entranceGlyphs: 'entrylg', - mapMarkerScore: 0, - - //original fields - allowsGuideDog: { yes: 0, no: 0 }, - //_bathroomReviews: 0, - //_bathroomScore: null, - //_entryReviews: 0, - //_entryScore: null, - hasParking: { yes: 0, no: 0 }, - hasSecondEntry: { yes: 0, no: 0 }, - hasWellLit: { yes: 0, no: 0 }, - isQuiet: { yes: 0, no: 0 }, - isSpacious: { yes: 0, no: 0 }, - steps: { - zero: 0, - one: 0, - two: 0, - moreThanTwo: 0 - } - }); - }); - - dataResponse = { - nextPage: placesResponse.data.next_page_token, - results: places - }; - } //ends legacy filter logic, false conditional - - return res.status(200).json(dataResponse); -}; +const axios = require('axios'); +const { find, isEmpty } = require('lodash'); +const slugify = require('speakingurl'); + +const { isNumber } = require('../../helpers'); +const { Venue } = require('../../models/venue'); + +const { validateListVenues } = require('./validations'); +const venueReviewSummary = require('../../helpers/venue-review-summary.js'); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + + const { errors, isValid } = validateListVenues(queryParams); + if (!isValid) return res.status(400).json(errors); + + let coordinates = queryParams.location.split(','); + + //Legacy function from two-bar search, geocodes from string address + if (queryParams.address && !queryParams.page) { + console.log('in address conditional, ', queryParams); + queryParams.name = queryParams.address; + const geocodeParams = `?key=${process.env.PLACES_API_KEY}&address=${slugify( + queryParams.address + )}`; + + let geocodeResponse; + try { + geocodeResponse = await axios.get( + `https://maps.googleapis.com/maps/api/geocode/json${geocodeParams}` + ); + } catch (err) { + console.log( + `Geocode failed to be found at list-venues.\nQuery Params: ${JSON.stringify( + queryParams + )}` + ); + return next(err); + } + + const statusCode = geocodeResponse.data.status; + if (statusCode === 'ZERO_RESULTS') { + return res.status(404).json({ keywords: 'Address not found' }); + } else if (statusCode === 'OVER_QUERY_LIMIT') { + return next(new Error('Over query limit with Google Places API')); + } else if (statusCode === 'REQUEST_DENIED') { + return next(new Error('Request denied with Google Places API')); + } else if (statusCode === 'INVALID_REQUEST') { + return next(new Error('Invalid request with Google Places API')); + } else if (statusCode === 'UNKNOWN_ERROR') { + return next(new Error('Unknown error with Google Places API')); + } + + coordinates = [ + geocodeResponse.data.results[0].geometry.location.lat, + geocodeResponse.data.results[0].geometry.location.lng + ]; + } //end address geocode + + let venuesFilters = {}; + let dbVenuesFilters = {}; + + /* + * Legacy filter string building function, + * has a critical defect condition where if + * no > yes but yes is at least 1, then there + * would be a false match. + */ + if (queryParams.entranceScore) { + venuesFilters.entranceScore = parseFloat(queryParams.entranceScore); + //{ $gte: parseFloat(queryParams.entranceScore) }; + } + + if (queryParams.interiorScore) { + venuesFilters.interiorScore = parseFloat(queryParams.interiorScore); + //{ $gte: parseFloat(queryParams.interiorScore) }; + } + + if (queryParams.restroomScore) { + venuesFilters.restroomScore = parseFloat(queryParams.restroomScore); + //{ $gte: parseFloat(queryParams.restroomScore) }; + } + + if (queryParams.allowsGuideDog) { + venuesFilters.allowsGuideDog = parseFloat(queryParams.allowsGuideDog); + + const allowsGuideDog = parseFloat(queryParams.allowsGuideDog) === 1; + if (allowsGuideDog) { + dbVenuesFilters['allowsGuideDog.yes'] = { $gte: 1 }; + } else { + dbVenuesFilters['allowsGuideDog.no'] = { $gte: 1 }; + } + } + + if (queryParams.hasParking) { + venuesFilters.hasParking = queryParams.hasParking; + + const hasParking = parseFloat(queryParams.hasParking) === 1; + if (hasParking) { + dbVenuesFilters['hasParking.yes'] = { $gte: 1 }; + } else { + dbVenuesFilters['hasParking.no'] = { $gte: 1 }; + } + } + + /* + * Not used + * + if (queryParams.hasRamp) { + const hasRamp = parseFloat(queryParams.hasRamp) === 1; + if (hasRamp) { + venuesFilters['hasRamp.yes'] = { $gte: 1 }; + } else { + venuesFilters['hasRamp.no'] = { $gte: 1 }; + } + } + + if (queryParams.hasSecondEntry) { + const hasSecondEntry = parseFloat(queryParams.hasSecondEntry) === 1; + if (hasSecondEntry) { + venuesFilters['hasSecondEntry.yes'] = { $gte: 1 }; + } else { + venuesFilters['hasSecondEntry.no'] = { $gte: 1 }; + } + } + + if (queryParams.hasWellLit) { + const hasWellLit = parseFloat(queryParams.hasWellLit) === 1; + if (hasWellLit) { + venuesFilters['hasWellLit.yes'] = { $gte: 1 }; + } else { + venuesFilters['hasWellLit.no'] = { $gte: 1 }; + } + } + + if (queryParams.isQuiet) { + const isQuiet = parseFloat(queryParams.isQuiet) === 1; + if (isQuiet) { + venuesFilters['isQuiet.yes'] = { $gte: 1 }; + } else { + venuesFilters['isQuiet.no'] = { $gte: 1 }; + } + } + + if (queryParams.isSpacious) { + const isSpacious = parseFloat(queryParams.isSpacious) === 1; + if (isSpacious) { + venuesFilters['isSpacious.yes'] = { $gte: 1 }; + } else { + venuesFilters['isSpacious.no'] = { $gte: 1 }; + } + } + + if (queryParams.steps) { + if (parseFloat(queryParams.steps) === 0) { + venuesFilters['steps.zero'] = { $gte: 1 }; + } else if (parseFloat(queryParams.steps) === 1) { + venuesFilters['steps.one'] = { $gte: 1 }; + } else if (parseFloat(queryParams.steps) === 2) { + venuesFilters['steps.two'] = { $gte: 1 }; + } else if (parseFloat(queryParams.steps) === 3) { + venuesFilters['steps.moreThanTwo'] = { $gte: 1 }; + } + } + * + */ + + let dataResponse; + + /* + * Legacy filtering function that searches solely on + * AXS Venue data and provides it's own pagination of 20 + * UPDATED 05/2020 TO SUPPORT FILTER ONLY SELF SEARCH + */ + if (!isEmpty(venuesFilters) && isEmpty(queryParams.name)) { + console.log('>> Performing DB search'); + /* + if (queryParams.name) { + //performs literal name match against AXS Venue name + venuesFilters.name = { $regex: queryParams.name, $options: 'i' }; + } + */ + + dbVenuesFilters.location = { + $near: { + $geometry: { + type: 'Point', + coordinates: [coordinates[1], coordinates[0]] + }, + $maxDistance: 50000 + } + }; + + if (queryParams.type) { + dbVenuesFilters.types = queryParams.type; + } + + dbVenuesFilters.isArchived = false; + + let page = 1; + if (isNumber(queryParams.page)) { + page = queryParams.page; + } + + const pageLimit = + 'entranceScore' in venuesFilters || + 'interiorScore' in venuesFilters || + 'restroomScore' in venuesFilters + ? 80 + : 20; + + if (page > 0) { + page -= 1; + } else { + return res + .status(400) + .json({ page: 'Should be equal to or greater than 1' }); + } + + let total; + let venues; + try { + [venues, total] = await Promise.all([ + Venue.find( + dbVenuesFilters + /*,'address allowsGuideDog hasParking hasSecondEntry hasWellLit isQuiet isSpacious location name photos placeId steps types'*/ + ) + .skip(page * pageLimit) + .limit(pageLimit), + Venue.find(dbVenuesFilters).count() + /*TODO: count is deprecated in favor of countDocuments, but that does not support $near + would need to move to GeoWithin but that does not return sorted results + */ + ]); + } catch (err) { + console.log( + `Venues failed to be found or count at list-venues.\nvenuesQuery: ${JSON.stringify( + dbVenuesFilters + )}` + ); + console.log(err); + return next(err); + } + + venues = venues.map((venue) => + Object.assign({}, venue.toObject(), { + id: venue._id, + _id: undefined, + location: venue.coordinates + }) + ); + + //+ADDED + //Perform ratings logic on all returned venues + console.log('Raw venues count: ' + venues.length); + venues = venues.filter((venue) => { + //console.log('In scoring assignment'); + let scoring; + //calculate entranceScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); + venue.entranceScore = scoring.ratingLevel; + venue.entranceGlyphs = scoring.ratingGlyphs; + + //calculate interiorScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('interior', venue); + venue.interiorScore = scoring.ratingLevel; + venue.interiorGlyphs = scoring.ratingGlyphs; + + //calculate restroomScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); + venue.restroomScore = scoring.ratingLevel; + venue.restroomGlyphs = scoring.ratingGlyphs; + + venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( + venue.entranceScore, + venue.interiorScore, + venue.restroomScore + ); + + let passesValidation = true; + if ('entranceScore' in venuesFilters) { + if ( + !venue.entranceScore || + venue.entranceScore < venuesFilters.entranceScore + ) { + passesValidation = false; + } + } + + if (passesValidation && 'interiorScore' in venuesFilters) { + if ( + !venue.interiorScore || + venue.interiorScore < venuesFilters.interiorScore + ) { + passesValidation = false; + } + } + + if (passesValidation && 'restroomScore' in venuesFilters) { + if ( + !venue.restroomScore || + venue.restroomScore < venuesFilters.restroomScore + ) { + passesValidation = false; + } + } + + if (passesValidation) { + return venue; + } + }); + + const lastPage = Math.ceil(total / pageLimit); + let nextPage; + if (lastPage > 0) { + page += 1; + if (page > lastPage || page > 3) { + return res.status(400).json({ + page: `Should be equal to or less than ${lastPage > 3 ? 3 : lastPage}` + }); + } + } + + dataResponse = { + nextPage, + results: venues + }; + /* + * End legacy filter + */ + } else { + console.log('>> Performing Google search'); + + /* + * Perform Google search when there text entered or no filters selected + */ + let nearbyParams = `?key=${process.env.PLACES_API_KEY}`; + let searchType = queryParams.name ? 'textsearch' : 'nearbysearch'; + + if (!queryParams.page) { + nearbyParams = `${nearbyParams}&location=${coordinates[0]},${ + coordinates[1] + //}&rankby=distance`; + }`; + + if (queryParams.name) { + //nearbyParams = `${nearbyParams}&keyword=${queryParams.name}`; + nearbyParams = `${nearbyParams}&query=${queryParams.name}&radius=5000`; + } else { + //empty search, such as on load + nearbyParams = `${nearbyParams}&rankby=distance`; + } + + if (queryParams.type) { + nearbyParams = `${nearbyParams}&type=${queryParams.type}`; + } else { + nearbyParams = `${nearbyParams}&type=establishment`; + } + } else { + nearbyParams = `${nearbyParams}&pagetoken=${queryParams.page}`; + } + + if (queryParams.rankby) { + nearbyParams = `${nearbyParams}&rankby=${queryParams.rankby}`; + } + if (queryParams.opennow) { + nearbyParams = `${nearbyParams}&opennow=${queryParams.opennow}`; + } + if (queryParams.minprice) { + nearbyParams = `${nearbyParams}&minprice=${queryParams.minprice}`; + } + if (queryParams.maxprice) { + nearbyParams = `${nearbyParams}&maxprice=${queryParams.maxprice}`; + } + + let placesResponse; + try { + console.log( + 'performing google search: ' + + `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` + ); + placesResponse = await axios.get( + `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` + ); + } catch (err) { + console.log( + `Places failed to be found at list-venues.\nQuery Params: ${JSON.stringify( + queryParams + )}` + ); + return next(err); + } + + const statusCode = placesResponse.data.status; + if (statusCode === 'OVER_QUERY_LIMIT') { + return next(new Error('Over query limit with Google Places API')); + } else if (statusCode === 'REQUEST_DENIED') { + return next(new Error('Request denied with Google Places API')); + } else if (statusCode === 'INVALID_REQUEST') { + return next(new Error('Invalid request with Google Places API')); + } else if (statusCode === 'UNKNOWN_ERROR') { + return next(new Error('Unknown error with Google Places API')); + } + //do we need to check for 0? + + if (placesResponse.data.results.length == 1) { + if (placesResponse.data.results[0].types[0] == 'locality') { + console.log( + 'Found a city only: ', + placesResponse.data.results[0].geometry.location + ); + //TODO: redo search with new coordinates and no query/name or change/add "places in " to the first part of the string + } + } + + //Format Google Places results and get array of IDs + let places = []; + const placesIds = []; + placesResponse.data.results.forEach((place) => { + let photo = ''; + if (place.photos) { + photo = `https://maps.googleapis.com/maps/api/place/photo?key=${ + process.env.PLACES_API_KEY + }&maxwidth=300&photoreference=${place.photos[0].photo_reference}`; + } + + places.push({ + //address: place.vicinity, + address: place.formatted_address, + location: { + lat: place.geometry.location.lat, + lng: place.geometry.location.lng + }, + name: place.name, + photo, + placeId: place.place_id, + types: place.types + }); + placesIds.push(place.place_id); + }); + + //Use array of Google Place IDs to find AXS Venues + let venues; + try { + venues = await Venue.find({ placeId: { $in: placesIds } }); + } catch (err) { + console.log( + `Venues failed to be found at list-venues.\nPlaces ids: [${placesIds}]` + ); + return next(err); + } + + //Perform ratings logic on all returned venues + venues.forEach((venue) => { + //console.log('In scoring assignment'); + let scoring; + //calculate entranceScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); + venue.entranceScore = scoring.ratingLevel; + venue.entranceGlyphs = scoring.ratingGlyphs; + + //calculate interiorScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('interior', venue); + venue.interiorScore = scoring.ratingLevel; + venue.interiorGlyphs = scoring.ratingGlyphs; + + //calculate restroomScore, glyphs + scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); + venue.restroomScore = scoring.ratingLevel; + venue.restroomGlyphs = scoring.ratingGlyphs; + + venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( + venue.entranceScore, + venue.interiorScore, + venue.restroomScore + ); + }); + + //Filter out, remove, Google Places that are not AXS Venues + // Can't use hasOwnProperty() on mongoose model objects // + if (!isEmpty(venuesFilters)) { + console.log('>> Performing secondary DB filtering'); + places = places.filter((place) => { + const venue = find(venues, (venue) => venue.placeId === place.placeId); + if (venue) { + //console.log('In verification of filters'); + let passesValidation = true; + if (passesValidation && 'allowsGuideDog' in venuesFilters) { + if ( + !venue.allowsGuideDog || + venue.allowsGuideDog.yes < venue.allowsGuideDog.no || + venue.allowsGuideDog.yes == 0 + ) { + passesValidation = false; + } + } + + if (passesValidation && 'hasParking' in venuesFilters) { + if ( + !venue.hasParking || + venue.hasParking.yes < venue.hasParking.no || + venue.hasParking.yes == 0 + ) { + passesValidation = false; + } + } + + if (passesValidation && 'entranceScore' in venuesFilters) { + if ( + !venue.entranceScore || + venue.entranceScore < venuesFilters.entranceScore + ) { + passesValidation = false; + } + } + + if (passesValidation && 'interiorScore' in venuesFilters) { + if ( + !venue.interiorScore || + venue.interiorScore < venuesFilters.interiorScore + ) { + passesValidation = false; + } + } + + if (passesValidation && 'restroomScore' in venuesFilters) { + if ( + !venue.restroomScore || + venue.restroomScore < venuesFilters.restroomScore + ) { + passesValidation = false; + } + } + + if (passesValidation) { + return venue; + } + } + }); + } //end filtering Google results + + // + places = places.map((place) => { + const venue = find(venues, (venue) => venue.placeId === place.placeId); + if (venue) { + return Object.assign({}, place, { + //new expanded fields + hasPermanentRamp: venue.hasPermanentRamp, + hasPortableRamp: venue.hasPortableRamp, + hasWideEntrance: venue.hasWideEntrance, + hasAccessibleTableHeight: venue.hasAccessibleTableHeight, + hasAccessibleElevator: venue.hasAccessibleElevator, + hasInteriorRamp: venue.hasInteriorRamp, + hasSwingInDoor: venue.hasSwingInDoor, + hasSwingOutDoor: venue.hasSwingOutDoor, + hasLargeStall: venue.hasLargeStall, + hasSupportAroundToilet: venue.hasSupportAroundToilet, + hasLoweredSinks: venue.hasLoweredSinks, + + entranceScore: venue.entranceScore, + entranceGlyphs: venue.entranceGlyphs, + interiorScore: venue.interiorScore, + interiorGlyphs: venue.interiorGlyphs, + restroomScore: venue.restroomScore, + restroomGlyphs: venue.restroomGlyphs, + mapMarkerScore: venue.mapMarkerScore, + + //original fields + allowsGuideDog: venue.allowsGuideDog, + //_bathroomScore: venue.bathroomScore, + //_entryScore: venue.entryScore, + hasParking: venue.hasParking, + hasSecondEntry: venue.hasSecondEntry, + hasWellLit: venue.hasWellLit, + isQuiet: venue.isQuiet, + isSpacious: venue.isSpacious, + steps: venue.steps + }); + } + + //venue not found + return Object.assign({}, place, { + //new expanded fields + hasPermanentRamp: { yes: 0, no: 0 }, + hasPortableRamp: { yes: 0, no: 0 }, + hasWideEntrance: { yes: 0, no: 0 }, + hasAccessibleTableHeight: { yes: 0, no: 0 }, + hasAccessibleElevator: { yes: 0, no: 0 }, + hasInteriorRamp: { yes: 0, no: 0 }, + hasSwingInDoor: { yes: 0, no: 0 }, + hasSwingOutDoor: { yes: 0, no: 0 }, + hasLargeStall: { yes: 0, no: 0 }, + hasSupportAroundToilet: { yes: 0, no: 0 }, + hasLoweredSinks: { yes: 0, no: 0 }, + interiorScore: 0, + interiorGlyphs: 'interior', + restroomScore: 0, + restroomGlyphs: 'restroom', + entranceScore: 0, + entranceGlyphs: 'entrylg', + mapMarkerScore: 0, + + //original fields + allowsGuideDog: { yes: 0, no: 0 }, + //_bathroomReviews: 0, + //_bathroomScore: null, + //_entryReviews: 0, + //_entryScore: null, + hasParking: { yes: 0, no: 0 }, + hasSecondEntry: { yes: 0, no: 0 }, + hasWellLit: { yes: 0, no: 0 }, + isQuiet: { yes: 0, no: 0 }, + isSpacious: { yes: 0, no: 0 }, + steps: { + zero: 0, + one: 0, + two: 0, + moreThanTwo: 0 + } + }); + }); + + dataResponse = { + nextPage: placesResponse.data.next_page_token, + results: places + }; + } //ends legacy filter logic, false conditional + + return res.status(200).json(dataResponse); +}; diff --git a/src/routes/venues/validations.js b/src/routes/venues/validations.js index 6d393cc..a234600 100644 --- a/src/routes/venues/validations.js +++ b/src/routes/venues/validations.js @@ -1,154 +1,154 @@ -const { isEmpty } = require('lodash'); - -const { isNumber } = require('../../helpers'); -const { placesTypes } = require('../../helpers/constants'); - -module.exports = { - validateListVenues(queryParams) { - const errors = {}; - - if (!queryParams.location) { - errors.location = 'Is required'; - } else { - const location = queryParams.location.split(','); - - if (location.length !== 2) { - errors.location = 'Should have two coordinates'; - } else if (!location[0]) { - errors.location = 'Latitude is required'; - } else if (!isNumber(location[0])) { - errors.location = 'Latitude should be a number'; - } else if ( - parseFloat(location[0]) < -90 || - parseFloat(location[0]) > 90 - ) { - errors.location = 'Latitude value out of bounds'; - } else if (!location[1]) { - errors.location = 'Longitude is required'; - } else if (!isNumber(location[1])) { - errors.location = 'Longitude should be a number'; - } else if ( - parseFloat(location[1]) < -180 || - parseFloat(location[1]) > 180 - ) { - errors.location = 'Longitude value out of bounds'; - } - } - - if (queryParams.bathroomScore) { - if (!isNumber(queryParams.bathroomScore)) { - errors.bathroomScore = 'Should be a number'; - } else if ( - parseFloat(queryParams.bathroomScore) < 1 || - parseFloat(queryParams.bathroomScore) > 5 - ) { - errors.bathroomScore = 'Should be between 1 and 5'; - } - } - - if (queryParams.entryScore) { - if (!isNumber(queryParams.entryScore)) { - errors.entryScore = 'Should be a number'; - } else if ( - parseFloat(queryParams.entryScore) < 1 || - parseFloat(queryParams.entryScore) > 5 - ) { - errors.entryScore = 'Should be between 1 and 5'; - } - } - - if (queryParams.allowsGuideDog) { - if (!isNumber(queryParams.allowsGuideDog)) { - errors.allowsGuideDog = 'Should be a number'; - } else if ( - parseFloat(queryParams.allowsGuideDog) !== 0 && - parseFloat(queryParams.allowsGuideDog) !== 1 - ) { - errors.allowsGuideDog = 'Should be 0 or 1'; - } - } - - if (queryParams.hasParking) { - if (!isNumber(queryParams.hasParking)) { - errors.hasParking = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasParking) !== 0 && - parseFloat(queryParams.hasParking) !== 1 - ) { - errors.hasParking = 'Should be 0 or 1'; - } - } - - if (queryParams.hasRamp) { - if (!isNumber(queryParams.hasRamp)) { - errors.hasRamp = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasRamp) !== 0 && - parseFloat(queryParams.hasRamp) !== 1 - ) { - errors.hasRamp = 'Should be 0 or 1'; - } - } - - if (queryParams.hasSecondEntry) { - if (!isNumber(queryParams.hasSecondEntry)) { - errors.hasSecondEntry = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasSecondEntry) !== 0 && - parseFloat(queryParams.hasSecondEntry) !== 1 - ) { - errors.hasSecondEntry = 'Should be 0 or 1'; - } - } - - if (queryParams.hasWellLit) { - if (!isNumber(queryParams.hasWellLit)) { - errors.hasWellLit = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasWellLit) !== 0 && - parseFloat(queryParams.hasWellLit) !== 1 - ) { - errors.hasWellLit = 'Should be 0 or 1'; - } - } - - if (queryParams.isQuiet) { - if (!isNumber(queryParams.isQuiet)) { - errors.isQuiet = 'Should be a number'; - } else if ( - parseFloat(queryParams.isQuiet) !== 0 && - parseFloat(queryParams.isQuiet) !== 1 - ) { - errors.isQuiet = 'Should be 0 or 1'; - } - } - - if (queryParams.isSpacious) { - if (!isNumber(queryParams.isSpacious)) { - errors.isSpacious = 'Should be a number'; - } else if ( - parseFloat(queryParams.isSpacious) !== 0 && - parseFloat(queryParams.isSpacious) !== 1 - ) { - errors.isSpacious = 'Should be 0 or 1'; - } - } - - if (queryParams.steps) { - if (!isNumber(queryParams.steps)) { - errors.steps = 'Should be a number'; - } else if ( - parseFloat(queryParams.steps) < 0 || - parseFloat(queryParams.steps) > 3 - ) { - errors.steps = 'Should be between 0 and 3'; - } - } - - if (queryParams.type && !placesTypes.includes(queryParams.type)) { - errors.type = 'Should be a valid type'; - } - - return { errors, isValid: isEmpty(errors) }; - } -}; +const { isEmpty } = require('lodash'); + +const { isNumber } = require('../../helpers'); +const { placesTypes } = require('../../helpers/constants'); + +module.exports = { + validateListVenues(queryParams) { + const errors = {}; + + if (!queryParams.location) { + errors.location = 'Is required'; + } else { + const location = queryParams.location.split(','); + + if (location.length !== 2) { + errors.location = 'Should have two coordinates'; + } else if (!location[0]) { + errors.location = 'Latitude is required'; + } else if (!isNumber(location[0])) { + errors.location = 'Latitude should be a number'; + } else if ( + parseFloat(location[0]) < -90 || + parseFloat(location[0]) > 90 + ) { + errors.location = 'Latitude value out of bounds'; + } else if (!location[1]) { + errors.location = 'Longitude is required'; + } else if (!isNumber(location[1])) { + errors.location = 'Longitude should be a number'; + } else if ( + parseFloat(location[1]) < -180 || + parseFloat(location[1]) > 180 + ) { + errors.location = 'Longitude value out of bounds'; + } + } + + if (queryParams.bathroomScore) { + if (!isNumber(queryParams.bathroomScore)) { + errors.bathroomScore = 'Should be a number'; + } else if ( + parseFloat(queryParams.bathroomScore) < 1 || + parseFloat(queryParams.bathroomScore) > 5 + ) { + errors.bathroomScore = 'Should be between 1 and 5'; + } + } + + if (queryParams.entryScore) { + if (!isNumber(queryParams.entryScore)) { + errors.entryScore = 'Should be a number'; + } else if ( + parseFloat(queryParams.entryScore) < 1 || + parseFloat(queryParams.entryScore) > 5 + ) { + errors.entryScore = 'Should be between 1 and 5'; + } + } + + if (queryParams.allowsGuideDog) { + if (!isNumber(queryParams.allowsGuideDog)) { + errors.allowsGuideDog = 'Should be a number'; + } else if ( + parseFloat(queryParams.allowsGuideDog) !== 0 && + parseFloat(queryParams.allowsGuideDog) !== 1 + ) { + errors.allowsGuideDog = 'Should be 0 or 1'; + } + } + + if (queryParams.hasParking) { + if (!isNumber(queryParams.hasParking)) { + errors.hasParking = 'Should be a number'; + } else if ( + parseFloat(queryParams.hasParking) !== 0 && + parseFloat(queryParams.hasParking) !== 1 + ) { + errors.hasParking = 'Should be 0 or 1'; + } + } + + if (queryParams.hasRamp) { + if (!isNumber(queryParams.hasRamp)) { + errors.hasRamp = 'Should be a number'; + } else if ( + parseFloat(queryParams.hasRamp) !== 0 && + parseFloat(queryParams.hasRamp) !== 1 + ) { + errors.hasRamp = 'Should be 0 or 1'; + } + } + + if (queryParams.hasSecondEntry) { + if (!isNumber(queryParams.hasSecondEntry)) { + errors.hasSecondEntry = 'Should be a number'; + } else if ( + parseFloat(queryParams.hasSecondEntry) !== 0 && + parseFloat(queryParams.hasSecondEntry) !== 1 + ) { + errors.hasSecondEntry = 'Should be 0 or 1'; + } + } + + if (queryParams.hasWellLit) { + if (!isNumber(queryParams.hasWellLit)) { + errors.hasWellLit = 'Should be a number'; + } else if ( + parseFloat(queryParams.hasWellLit) !== 0 && + parseFloat(queryParams.hasWellLit) !== 1 + ) { + errors.hasWellLit = 'Should be 0 or 1'; + } + } + + if (queryParams.isQuiet) { + if (!isNumber(queryParams.isQuiet)) { + errors.isQuiet = 'Should be a number'; + } else if ( + parseFloat(queryParams.isQuiet) !== 0 && + parseFloat(queryParams.isQuiet) !== 1 + ) { + errors.isQuiet = 'Should be 0 or 1'; + } + } + + if (queryParams.isSpacious) { + if (!isNumber(queryParams.isSpacious)) { + errors.isSpacious = 'Should be a number'; + } else if ( + parseFloat(queryParams.isSpacious) !== 0 && + parseFloat(queryParams.isSpacious) !== 1 + ) { + errors.isSpacious = 'Should be 0 or 1'; + } + } + + if (queryParams.steps) { + if (!isNumber(queryParams.steps)) { + errors.steps = 'Should be a number'; + } else if ( + parseFloat(queryParams.steps) < 0 || + parseFloat(queryParams.steps) > 3 + ) { + errors.steps = 'Should be between 0 and 3'; + } + } + + if (queryParams.type && !placesTypes.includes(queryParams.type)) { + errors.type = 'Should be a valid type'; + } + + return { errors, isValid: isEmpty(errors) }; + } +}; diff --git a/src/scripts/db/import-events.js b/src/scripts/db/import-events.js index 6ad0a17..65fa480 100644 --- a/src/scripts/db/import-events.js +++ b/src/scripts/db/import-events.js @@ -1,154 +1,154 @@ -const mongoose = require('mongoose'); - -require('dotenv').config(); - -const { eventSchema } = require('../../models/event'); - -const oldEventsSchema = require('./old-schemas/event'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const oldEvent = oldDb.model('events', oldEventsSchema); - - let totalOldEvents; - try { - totalOldEvents = await oldEvent.count({ name: { $ne: '' } }); - } catch (error) { - console.log('Old events failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old events: ${totalOldEvents}`); - - console.time('createEvents'); - - let page = 0; - const pageLimit = 100; - let i = 0; - do { - let oldEvents; - try { - oldEvents = await oldEvent - .find({ name: { $ne: '' } }) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old events failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const Event = db.model('Event', eventSchema); - - const createEvents = []; - for (let oldEventItem of oldEvents) { - let participants = oldEventItem.members.map(member => member.user); - participants = participants.filter( - p => p.toString() !== oldEventItem.creator.toString() - ); - - const eventData = { - _id: oldEventItem.id, - createdAt: oldEventItem.created_at, - description: oldEventItem.description.substring(0, 300), - endDate: oldEventItem.event_end, - managers: [oldEventItem.creator], - name: oldEventItem.name, - participants, - participantsGoal: oldEventItem.participant_goal - ? oldEventItem.participant_goal > 1000 - ? 1000 - : oldEventItem.participant_goal - : 1, - poster: oldEventItem.image, - reviewsGoal: oldEventItem.mapping_goal - ? oldEventItem.mapping_goal > 10000 - ? 10000 - : oldEventItem.mapping_goal - : 1, - startDate: oldEventItem.event_start, - teams: oldEventItem.teams, - updatedAt: oldEventItem.updated_at, - venue: oldEventItem.location - }; - - createEvents.push(Event.create(eventData)); - } - - try { - await Promise.all(createEvents); - } catch (error) { - console.log( - `Events failed to be created.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + oldEvents.length; - console.log(i); - } while (i < totalOldEvents); - - console.timeEnd('createEvents'); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const mongoose = require('mongoose'); + +require('dotenv').config(); + +const { eventSchema } = require('../../models/event'); + +const oldEventsSchema = require('./old-schemas/event'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const oldEvent = oldDb.model('events', oldEventsSchema); + + let totalOldEvents; + try { + totalOldEvents = await oldEvent.count({ name: { $ne: '' } }); + } catch (error) { + console.log('Old events failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old events: ${totalOldEvents}`); + + console.time('createEvents'); + + let page = 0; + const pageLimit = 100; + let i = 0; + do { + let oldEvents; + try { + oldEvents = await oldEvent + .find({ name: { $ne: '' } }) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old events failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const Event = db.model('Event', eventSchema); + + const createEvents = []; + for (let oldEventItem of oldEvents) { + let participants = oldEventItem.members.map((member) => member.user); + participants = participants.filter( + (p) => p.toString() !== oldEventItem.creator.toString() + ); + + const eventData = { + _id: oldEventItem.id, + createdAt: oldEventItem.created_at, + description: oldEventItem.description.substring(0, 300), + endDate: oldEventItem.event_end, + managers: [oldEventItem.creator], + name: oldEventItem.name, + participants, + participantsGoal: oldEventItem.participant_goal + ? oldEventItem.participant_goal > 1000 + ? 1000 + : oldEventItem.participant_goal + : 1, + poster: oldEventItem.image, + reviewsGoal: oldEventItem.mapping_goal + ? oldEventItem.mapping_goal > 10000 + ? 10000 + : oldEventItem.mapping_goal + : 1, + startDate: oldEventItem.event_start, + teams: oldEventItem.teams, + updatedAt: oldEventItem.updated_at, + venue: oldEventItem.location + }; + + createEvents.push(Event.create(eventData)); + } + + try { + await Promise.all(createEvents); + } catch (error) { + console.log( + `Events failed to be created.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + oldEvents.length; + console.log(i); + } while (i < totalOldEvents); + + console.timeEnd('createEvents'); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/import-reviews.js b/src/scripts/db/import-reviews.js index 4f36291..1e125c3 100644 --- a/src/scripts/db/import-reviews.js +++ b/src/scripts/db/import-reviews.js @@ -1,149 +1,149 @@ -const mongoose = require('mongoose'); - -require('dotenv').config(); - -const { reviewSchema } = require('../../models/review'); - -const oldReviewSchema = require('./old-schemas/review'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const OldReview = oldDb.model('reviews', oldReviewSchema); - - let totalOldReviews; - try { - totalOldReviews = await OldReview.count(); - } catch (error) { - console.log('Old reviews failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old reviews: ${totalOldReviews}`); - - console.time('createReviews'); - - let page = 0; - const pageLimit = 100; - let i = 0; - do { - let oldReviews; - try { - oldReviews = await OldReview.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old reviews failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const Review = db.model('Review', reviewSchema); - - const createReviews = []; - for (let oldReview of oldReviews) { - if (oldReview.venue_id && oldReview.user_id) { - const reviewData = { - _id: oldReview.id, - allowsGuideDog: oldReview.guidedog, - createdAt: oldReview.created_at, - bathroomScore: oldReview.bathroom, - entryScore: oldReview.entry, - event: oldReview.event, - hasParking: oldReview.parking, - hasRamp: oldReview.ramp, - hasSecondEntry: oldReview.secondentrance, - hasWellLit: oldReview.welllit, - isQuiet: oldReview.quiet, - isSpacious: oldReview.spacious, - steps: oldReview.steps, - team: oldReview.team, - updatedAt: oldReview.updated_at, - user: oldReview.user_id, - venue: oldReview.venue_id - }; - - if (oldReview.comment && oldReview.comment.length <= 300) { - reviewData.comments = oldReview.comment; - } - - createReviews.push(Review.create(reviewData)); - } - } - - try { - await Promise.all(createReviews); - } catch (error) { - console.log( - `Reviews failed to be created.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + oldReviews.length; - console.log(i); - } while (i < totalOldReviews); - - console.timeEnd('createReviews'); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const mongoose = require('mongoose'); + +require('dotenv').config(); + +const { reviewSchema } = require('../../models/review'); + +const oldReviewSchema = require('./old-schemas/review'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const OldReview = oldDb.model('reviews', oldReviewSchema); + + let totalOldReviews; + try { + totalOldReviews = await OldReview.count(); + } catch (error) { + console.log('Old reviews failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old reviews: ${totalOldReviews}`); + + console.time('createReviews'); + + let page = 0; + const pageLimit = 100; + let i = 0; + do { + let oldReviews; + try { + oldReviews = await OldReview.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old reviews failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const Review = db.model('Review', reviewSchema); + + const createReviews = []; + for (let oldReview of oldReviews) { + if (oldReview.venue_id && oldReview.user_id) { + const reviewData = { + _id: oldReview.id, + allowsGuideDog: oldReview.guidedog, + createdAt: oldReview.created_at, + bathroomScore: oldReview.bathroom, + entryScore: oldReview.entry, + event: oldReview.event, + hasParking: oldReview.parking, + hasRamp: oldReview.ramp, + hasSecondEntry: oldReview.secondentrance, + hasWellLit: oldReview.welllit, + isQuiet: oldReview.quiet, + isSpacious: oldReview.spacious, + steps: oldReview.steps, + team: oldReview.team, + updatedAt: oldReview.updated_at, + user: oldReview.user_id, + venue: oldReview.venue_id + }; + + if (oldReview.comment && oldReview.comment.length <= 300) { + reviewData.comments = oldReview.comment; + } + + createReviews.push(Review.create(reviewData)); + } + } + + try { + await Promise.all(createReviews); + } catch (error) { + console.log( + `Reviews failed to be created.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + oldReviews.length; + console.log(i); + } while (i < totalOldReviews); + + console.timeEnd('createReviews'); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/import-teams.js b/src/scripts/db/import-teams.js index 4334d0b..b9393ce 100644 --- a/src/scripts/db/import-teams.js +++ b/src/scripts/db/import-teams.js @@ -1,270 +1,270 @@ -const aws = require('aws-sdk'); -const jimp = require('jimp'); -const mongoose = require('mongoose'); -const randomstring = require('randomstring'); - -require('dotenv').config(); - -const { reviewSchema } = require('../../models/review'); -const { teamSchema } = require('../../models/team'); - -const oldTeamSchema = require('./old-schemas/team'); - -mongoose.Promise = global.Promise; - -const s3 = new aws.S3(); - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const OldTeam = oldDb.model('teams', oldTeamSchema); - - let totalOldTeams; - try { - totalOldTeams = await OldTeam.count(); - } catch (error) { - console.log('Old teams failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old teams: ${totalOldTeams}`); - - const Team = db.model('Team', teamSchema); - - console.time('createTeams'); - - let i = 0; - let page = 0; - const pageLimit = 100; - do { - let oldTeams; - try { - oldTeams = await OldTeam.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old teams failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const createTeams = []; - const uploadTeamsAvatars = []; - for (let oldTeam of oldTeams) { - if (oldTeam.name) { - const members = oldTeam.members.filter( - m => m.toString() !== oldTeam.creator.toString() - ); - const teamData = { - _id: oldTeam.id, - createdAt: oldTeam.created_at, - events: oldTeam.events, - managers: [oldTeam.creator], - members: members, - name: - oldTeam.name.length > 35 - ? oldTeam.name.substring(0, 35) - : oldTeam.name, - updatedAt: oldTeam.updated_at - }; - - if (oldTeam.description) { - teamData.description = - oldTeam.description.length <= 300 - ? oldTeam.description - : oldTeam.description.substring(0, 300); - } - - if (oldTeam.image && !oldTeam.image.includes('icon_team.png')) { - let avatarImage; - try { - avatarImage = await jimp.read(encodeURI(oldTeam.image)); - } catch (err) { - console.log('Old team avatar image failed to be read'); - console.log(err); - await closeConnections(db, oldDb); - } - - if (avatarImage) { - const avatarExtension = avatarImage.getExtension(); - const avatarFileName = `${Date.now()}${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}.${avatarExtension}`; - - if ( - avatarExtension === 'png' || - avatarExtension === 'jpeg' || - avatarExtension === 'jpg' || - avatarExtension === 'bmp' - ) { - teamData.avatar = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/teams/avatars/${avatarFileName}`; - avatarImage - .cover(400, 400) - .quality(85) - .getBuffer( - avatarImage.getMIME(), - async (err, avatarBuffer) => { - if (err) { - console.log('Old team avatar buffer failed to be read'); - console.log(err); - await closeConnections(db, oldDb); - } - - uploadTeamsAvatars.push( - s3 - .putObject({ - ACL: 'public-read', - Body: avatarBuffer, - Bucket: process.env.AWS_S3_BUCKET, - ContentType: avatarImage.getMIME(), - Key: `teams/avatars/${avatarFileName}` - }) - .promise() - ); - } - ); - } - } - } - - createTeams.push(Team.create(teamData)); - } - } - - try { - await Promise.all([...createTeams, ...uploadTeamsAvatars]); - } catch (error) { - console.log( - `Teams failed to be created.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + oldTeams.length; - console.log(i); - } while (i < totalOldTeams); - - console.timeEnd('createTeams'); - - const Review = db.model('Review', reviewSchema); - - let totalTeams; - try { - totalTeams = await Team.count(); - } catch (error) { - console.log('Teams failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total teams: ${totalTeams}`); - - i = 0; - page = 0; - do { - let teams; - try { - teams = await Team.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Teams failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const updateTeams = []; - for (let team of teams) { - let teamReviews; - try { - teamReviews = await Review.find({ team: team.id }).count(); - } catch (err) { - console.log('Team reviews failed to be count'); - console.log(err); - await closeConnections(db, oldDb); - } - - team.reviewsAmount = teamReviews; - updateTeams.push(team.save()); - } - - try { - await Promise.all(updateTeams); - } catch (err) { - console.log( - `Teams failed to be updated.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(err); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + teams.length; - console.log(i); - } while (i < totalTeams); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const aws = require('aws-sdk'); +const jimp = require('jimp'); +const mongoose = require('mongoose'); +const randomstring = require('randomstring'); + +require('dotenv').config(); + +const { reviewSchema } = require('../../models/review'); +const { teamSchema } = require('../../models/team'); + +const oldTeamSchema = require('./old-schemas/team'); + +mongoose.Promise = global.Promise; + +const s3 = new aws.S3(); + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const OldTeam = oldDb.model('teams', oldTeamSchema); + + let totalOldTeams; + try { + totalOldTeams = await OldTeam.count(); + } catch (error) { + console.log('Old teams failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old teams: ${totalOldTeams}`); + + const Team = db.model('Team', teamSchema); + + console.time('createTeams'); + + let i = 0; + let page = 0; + const pageLimit = 100; + do { + let oldTeams; + try { + oldTeams = await OldTeam.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old teams failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const createTeams = []; + const uploadTeamsAvatars = []; + for (let oldTeam of oldTeams) { + if (oldTeam.name) { + const members = oldTeam.members.filter( + (m) => m.toString() !== oldTeam.creator.toString() + ); + const teamData = { + _id: oldTeam.id, + createdAt: oldTeam.created_at, + events: oldTeam.events, + managers: [oldTeam.creator], + members: members, + name: + oldTeam.name.length > 35 + ? oldTeam.name.substring(0, 35) + : oldTeam.name, + updatedAt: oldTeam.updated_at + }; + + if (oldTeam.description) { + teamData.description = + oldTeam.description.length <= 300 + ? oldTeam.description + : oldTeam.description.substring(0, 300); + } + + if (oldTeam.image && !oldTeam.image.includes('icon_team.png')) { + let avatarImage; + try { + avatarImage = await jimp.read(encodeURI(oldTeam.image)); + } catch (err) { + console.log('Old team avatar image failed to be read'); + console.log(err); + await closeConnections(db, oldDb); + } + + if (avatarImage) { + const avatarExtension = avatarImage.getExtension(); + const avatarFileName = `${Date.now()}${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}.${avatarExtension}`; + + if ( + avatarExtension === 'png' || + avatarExtension === 'jpeg' || + avatarExtension === 'jpg' || + avatarExtension === 'bmp' + ) { + teamData.avatar = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/teams/avatars/${avatarFileName}`; + avatarImage + .cover(400, 400) + .quality(85) + .getBuffer( + avatarImage.getMIME(), + async (err, avatarBuffer) => { + if (err) { + console.log('Old team avatar buffer failed to be read'); + console.log(err); + await closeConnections(db, oldDb); + } + + uploadTeamsAvatars.push( + s3 + .putObject({ + ACL: 'public-read', + Body: avatarBuffer, + Bucket: process.env.AWS_S3_BUCKET, + ContentType: avatarImage.getMIME(), + Key: `teams/avatars/${avatarFileName}` + }) + .promise() + ); + } + ); + } + } + } + + createTeams.push(Team.create(teamData)); + } + } + + try { + await Promise.all([...createTeams, ...uploadTeamsAvatars]); + } catch (error) { + console.log( + `Teams failed to be created.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + oldTeams.length; + console.log(i); + } while (i < totalOldTeams); + + console.timeEnd('createTeams'); + + const Review = db.model('Review', reviewSchema); + + let totalTeams; + try { + totalTeams = await Team.count(); + } catch (error) { + console.log('Teams failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total teams: ${totalTeams}`); + + i = 0; + page = 0; + do { + let teams; + try { + teams = await Team.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Teams failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const updateTeams = []; + for (let team of teams) { + let teamReviews; + try { + teamReviews = await Review.find({ team: team.id }).count(); + } catch (err) { + console.log('Team reviews failed to be count'); + console.log(err); + await closeConnections(db, oldDb); + } + + team.reviewsAmount = teamReviews; + updateTeams.push(team.save()); + } + + try { + await Promise.all(updateTeams); + } catch (err) { + console.log( + `Teams failed to be updated.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(err); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + teams.length; + console.log(i); + } while (i < totalTeams); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/import-users.js b/src/scripts/db/import-users.js index ed75da7..55fdd69 100644 --- a/src/scripts/db/import-users.js +++ b/src/scripts/db/import-users.js @@ -1,275 +1,275 @@ -const mongoose = require('mongoose'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); - -require('dotenv').config(); - -const { cleanSpaces } = require('../../helpers'); -const { reviewSchema } = require('../../models/review'); -const { userSchema } = require('../../models/user'); - -const oldUserSchema = require('./old-schemas/user'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const OldUser = oldDb.model('users', oldUserSchema); - - let totalOldUsers; - try { - totalOldUsers = await OldUser.count(); - } catch (error) { - console.log('Old users failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old users: ${totalOldUsers}`); - - const User = db.model('User', userSchema); - - console.time('createUsers'); - - let page = 0; - const pageLimit = 100; - let i = 0; - do { - let oldUsers; - try { - oldUsers = await OldUser.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old users failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const createUsers = []; - for (let oldUser of oldUsers) { - if (oldUser.isactive) { - const userData = { - _id: oldUser.id, - createdAt: oldUser.createdAt, - description: oldUser.description - ? cleanSpaces(oldUser.description) - : '', - email: oldUser.email, - events: oldUser.events, - facebookId: oldUser.facebookAuth, - firstName: - oldUser.name.first && cleanSpaces(oldUser.name.first) - ? cleanSpaces(oldUser.name.first) - : 'first', - hashedPassword: oldUser.hash, - isSubscribed: oldUser.newsletter, - lastName: - oldUser.name.last && cleanSpaces(oldUser.name.last) - ? cleanSpaces(oldUser.name.last) - : 'last', - phone: oldUser.phone ? cleanSpaces(oldUser.phone) : '', - showEmail: oldUser.showEmail, - showPhone: oldUser.showPhone, - teams: oldUser.teams, - updatedAt: oldUser.updatedAt, - username: `${slugify(oldUser.name.first)}-${slugify( - oldUser.name.last - )}-${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}` - }; - - switch (oldUser.disabilitytype.toLowerCase()) { - case 'audio': - userData.disabilities = ['audio']; - break; - - case 'other': - userData.disabilities = ['other']; - break; - - case 'private': - userData.disabilities = ['private']; - break; - - case 'visual': - userData.disabilities = ['vision']; - break; - - case 'wheelchair': - userData.disabilities = ['physical']; - break; - - default: - userData.disabilities = ['none']; - } - - switch (oldUser.gender.toLowerCase()) { - case 'female': - userData.gender = 'female'; - break; - - case 'male': - userData.gender = 'male'; - break; - - case 'other': - userData.gender = 'other'; - break; - - case 'transgender': - userData.gender = 'transgender'; - break; - - default: - userData.gender = 'private'; - } - - if (oldUser.zip && oldUser.zip.length <= 32) { - userData.zip = oldUser.zip; - } - - createUsers.push(User.create(userData)); - } - } - - try { - await Promise.all(createUsers); - } catch (error) { - console.log( - `Users failed to be created.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + oldUsers.length; - console.log(i); - } while (i < totalOldUsers); - - console.timeEnd('createUsers'); - - const Review = db.model('Review', reviewSchema); - - let totalUsers; - try { - totalUsers = await User.count(); - } catch (error) { - console.log('Users failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total users: ${totalUsers}`); - - console.time('updateReviewsAmount'); - - i = 0; - page = 0; - do { - let users; - try { - users = await User.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Users failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const updateUsers = []; - for (let user of users) { - let userReviews; - try { - userReviews = await Review.find({ user: user.id }).count(); - } catch (err) { - console.log('User reviews failed to be count'); - console.log(err); - await closeConnections(db, oldDb); - } - - user.reviewsAmount = userReviews; - updateUsers.push(user.save()); - } - - try { - await Promise.all(updateUsers); - } catch (err) { - console.log( - `Users failed to be updated.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(err); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + users.length; - console.log(i); - } while (i < totalUsers); - - console.timeEnd('updateReviewsAmount'); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const mongoose = require('mongoose'); +const randomstring = require('randomstring'); +const slugify = require('speakingurl'); + +require('dotenv').config(); + +const { cleanSpaces } = require('../../helpers'); +const { reviewSchema } = require('../../models/review'); +const { userSchema } = require('../../models/user'); + +const oldUserSchema = require('./old-schemas/user'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const OldUser = oldDb.model('users', oldUserSchema); + + let totalOldUsers; + try { + totalOldUsers = await OldUser.count(); + } catch (error) { + console.log('Old users failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old users: ${totalOldUsers}`); + + const User = db.model('User', userSchema); + + console.time('createUsers'); + + let page = 0; + const pageLimit = 100; + let i = 0; + do { + let oldUsers; + try { + oldUsers = await OldUser.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old users failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const createUsers = []; + for (let oldUser of oldUsers) { + if (oldUser.isactive) { + const userData = { + _id: oldUser.id, + createdAt: oldUser.createdAt, + description: oldUser.description + ? cleanSpaces(oldUser.description) + : '', + email: oldUser.email, + events: oldUser.events, + facebookId: oldUser.facebookAuth, + firstName: + oldUser.name.first && cleanSpaces(oldUser.name.first) + ? cleanSpaces(oldUser.name.first) + : 'first', + hashedPassword: oldUser.hash, + isSubscribed: oldUser.newsletter, + lastName: + oldUser.name.last && cleanSpaces(oldUser.name.last) + ? cleanSpaces(oldUser.name.last) + : 'last', + phone: oldUser.phone ? cleanSpaces(oldUser.phone) : '', + showEmail: oldUser.showEmail, + showPhone: oldUser.showPhone, + teams: oldUser.teams, + updatedAt: oldUser.updatedAt, + username: `${slugify(oldUser.name.first)}-${slugify( + oldUser.name.last + )}-${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}` + }; + + switch (oldUser.disabilitytype.toLowerCase()) { + case 'audio': + userData.disabilities = ['audio']; + break; + + case 'other': + userData.disabilities = ['other']; + break; + + case 'private': + userData.disabilities = ['private']; + break; + + case 'visual': + userData.disabilities = ['vision']; + break; + + case 'wheelchair': + userData.disabilities = ['physical']; + break; + + default: + userData.disabilities = ['none']; + } + + switch (oldUser.gender.toLowerCase()) { + case 'female': + userData.gender = 'female'; + break; + + case 'male': + userData.gender = 'male'; + break; + + case 'other': + userData.gender = 'other'; + break; + + case 'transgender': + userData.gender = 'transgender'; + break; + + default: + userData.gender = 'private'; + } + + if (oldUser.zip && oldUser.zip.length <= 32) { + userData.zip = oldUser.zip; + } + + createUsers.push(User.create(userData)); + } + } + + try { + await Promise.all(createUsers); + } catch (error) { + console.log( + `Users failed to be created.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + oldUsers.length; + console.log(i); + } while (i < totalOldUsers); + + console.timeEnd('createUsers'); + + const Review = db.model('Review', reviewSchema); + + let totalUsers; + try { + totalUsers = await User.count(); + } catch (error) { + console.log('Users failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total users: ${totalUsers}`); + + console.time('updateReviewsAmount'); + + i = 0; + page = 0; + do { + let users; + try { + users = await User.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Users failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const updateUsers = []; + for (let user of users) { + let userReviews; + try { + userReviews = await Review.find({ user: user.id }).count(); + } catch (err) { + console.log('User reviews failed to be count'); + console.log(err); + await closeConnections(db, oldDb); + } + + user.reviewsAmount = userReviews; + updateUsers.push(user.save()); + } + + try { + await Promise.all(updateUsers); + } catch (err) { + console.log( + `Users failed to be updated.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(err); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + users.length; + console.log(i); + } while (i < totalUsers); + + console.timeEnd('updateReviewsAmount'); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/import-venues.js b/src/scripts/db/import-venues.js index 331c7b3..bf03081 100644 --- a/src/scripts/db/import-venues.js +++ b/src/scripts/db/import-venues.js @@ -1,182 +1,182 @@ -const mongoose = require('mongoose'); - -require('dotenv').config(); - -const { venueSchema } = require('../../models/venue'); - -const oldVenueSchema = require('./old-schemas/venue'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const OldVenue = oldDb.model('venues', oldVenueSchema); - - let totalOldVenues; - try { - totalOldVenues = await OldVenue.find({ - lngLat: { $exists: true }, - place_id: { $exists: true, $ne: '' }, - types: { $ne: [] } - }).count(); - } catch (error) { - console.log('Old venues failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old venues: ${totalOldVenues}`); - - console.time('createVenues'); - - let page = 0; - const pageLimit = 100; - let i = 0; - do { - let oldVenues; - try { - oldVenues = await OldVenue.find({ - lngLat: { $exists: true }, - place_id: { $exists: true, $ne: '' }, - types: { $ne: [] } - }) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old venues failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const Venue = db.model('Venue', venueSchema); - - const createVenues = []; - for (let oldVenue of oldVenues) { - const addressOne = oldVenue.addr1; - const addressTwo = oldVenue.addr2 ? ` ${oldVenue.addr2}` : ''; - const city = oldVenue.city ? `, ${oldVenue.city}` : ''; - const state = oldVenue.state ? `, ${oldVenue.state}` : ''; - const address = `${addressOne}${addressTwo}${city}${state}`; - - const bathroomScore = - oldVenue.bathroom >= 1 ? oldVenue.bathroom : undefined; - const entryScore = oldVenue.entry >= 1 ? oldVenue.entry : undefined; - - let longitude; - if (oldVenue.lngLat[1] >= -180 && oldVenue.lngLat[1] <= 180) { - longitude = oldVenue.lngLat[1]; - } - let latitude; - if (oldVenue.lngLat[0] >= -90 && oldVenue.lngLat[0] <= 90) { - latitude = oldVenue.lngLat[0]; - } else { - longitude = oldVenue.lngLat[0]; - latitude = oldVenue.lngLat[1]; - } - - const venueData = { - _id: oldVenue.id, - address: oldVenue.addr1 ? address : '', - allowsGuideDog: { yes: oldVenue.guidedog }, - bathroomReviews: oldVenue.b_reviews, - bathroomScore, - createdAt: oldVenue.created_at, - entryReviews: oldVenue.e_reviews, - entryScore, - hasParking: { yes: oldVenue.parking }, - hasRamp: { yes: oldVenue.ramp }, - hasSecondEntry: { yes: oldVenue.secondentrance }, - hasWellLit: { yes: oldVenue.welllit }, - isQuiet: { yes: oldVenue.quiet }, - isSpacious: { yes: oldVenue.spacious }, - location: { coordinates: [longitude, latitude] }, - name: oldVenue.name, - placeId: oldVenue.place_id, - reviews: oldVenue.reviewdata, - steps: { - zero: oldVenue.steps_0, - one: oldVenue.steps_1, - two: oldVenue.steps_2, - moreThanTwo: oldVenue.steps_3 - }, - types: oldVenue.types, - updatedAt: oldVenue.updated_at - }; - - createVenues.push(Venue.create(venueData)); - } - - try { - await Promise.all(createVenues); - } catch (error) { - console.log( - `Venues failed to be created.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - page = page + 1; - i = i + oldVenues.length; - console.log(i); - } while (i < totalOldVenues); - - console.timeEnd('createVenues'); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const mongoose = require('mongoose'); + +require('dotenv').config(); + +const { venueSchema } = require('../../models/venue'); + +const oldVenueSchema = require('./old-schemas/venue'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const OldVenue = oldDb.model('venues', oldVenueSchema); + + let totalOldVenues; + try { + totalOldVenues = await OldVenue.find({ + lngLat: { $exists: true }, + place_id: { $exists: true, $ne: '' }, + types: { $ne: [] } + }).count(); + } catch (error) { + console.log('Old venues failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old venues: ${totalOldVenues}`); + + console.time('createVenues'); + + let page = 0; + const pageLimit = 100; + let i = 0; + do { + let oldVenues; + try { + oldVenues = await OldVenue.find({ + lngLat: { $exists: true }, + place_id: { $exists: true, $ne: '' }, + types: { $ne: [] } + }) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old venues failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const Venue = db.model('Venue', venueSchema); + + const createVenues = []; + for (let oldVenue of oldVenues) { + const addressOne = oldVenue.addr1; + const addressTwo = oldVenue.addr2 ? ` ${oldVenue.addr2}` : ''; + const city = oldVenue.city ? `, ${oldVenue.city}` : ''; + const state = oldVenue.state ? `, ${oldVenue.state}` : ''; + const address = `${addressOne}${addressTwo}${city}${state}`; + + const bathroomScore = + oldVenue.bathroom >= 1 ? oldVenue.bathroom : undefined; + const entryScore = oldVenue.entry >= 1 ? oldVenue.entry : undefined; + + let longitude; + if (oldVenue.lngLat[1] >= -180 && oldVenue.lngLat[1] <= 180) { + longitude = oldVenue.lngLat[1]; + } + let latitude; + if (oldVenue.lngLat[0] >= -90 && oldVenue.lngLat[0] <= 90) { + latitude = oldVenue.lngLat[0]; + } else { + longitude = oldVenue.lngLat[0]; + latitude = oldVenue.lngLat[1]; + } + + const venueData = { + _id: oldVenue.id, + address: oldVenue.addr1 ? address : '', + allowsGuideDog: { yes: oldVenue.guidedog }, + bathroomReviews: oldVenue.b_reviews, + bathroomScore, + createdAt: oldVenue.created_at, + entryReviews: oldVenue.e_reviews, + entryScore, + hasParking: { yes: oldVenue.parking }, + hasRamp: { yes: oldVenue.ramp }, + hasSecondEntry: { yes: oldVenue.secondentrance }, + hasWellLit: { yes: oldVenue.welllit }, + isQuiet: { yes: oldVenue.quiet }, + isSpacious: { yes: oldVenue.spacious }, + location: { coordinates: [longitude, latitude] }, + name: oldVenue.name, + placeId: oldVenue.place_id, + reviews: oldVenue.reviewdata, + steps: { + zero: oldVenue.steps_0, + one: oldVenue.steps_1, + two: oldVenue.steps_2, + moreThanTwo: oldVenue.steps_3 + }, + types: oldVenue.types, + updatedAt: oldVenue.updated_at + }; + + createVenues.push(Venue.create(venueData)); + } + + try { + await Promise.all(createVenues); + } catch (error) { + console.log( + `Venues failed to be created.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + page = page + 1; + i = i + oldVenues.length; + console.log(i); + } while (i < totalOldVenues); + + console.timeEnd('createVenues'); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/old-schemas/event.js b/src/scripts/db/old-schemas/event.js index cd99ce5..370e451 100644 --- a/src/scripts/db/old-schemas/event.js +++ b/src/scripts/db/old-schemas/event.js @@ -1,83 +1,83 @@ -const mongoose = require('mongoose'); - -const Schema = mongoose.Schema; -const ObjectId = Schema.ObjectId; - -const schema = new Schema({ - name: { - type: String, - required: true - }, - description: { - type: String, - required: true - }, - creator: { - type: ObjectId, - ref: 'users', - required: true - }, - approved: { - type: Boolean, - default: true - }, - event_start: { - type: Date, - required: true - }, - event_end: { - type: Date, - required: true - }, - created_at: { - type: Date, - default: Date.now - }, - updated_at: { - type: Date, - default: Date.now - }, - location: { - type: ObjectId, - ref: 'venues' - }, - goal: Number, - mapping_goal: Number, - participant_goal: Number, - participant_limit: Number, - type: String, - image: { - type: String, - default: '/images/icon_pin_mapathon_water.png' - }, - company: { - name: String, - address: String - }, - charity: { - name: String, - email: String, - website: String - }, - teams: [ - { - type: ObjectId, - ref: 'teams' - } - ], - members: [ - { - _id: false, - user: { - type: ObjectId, - ref: 'users' - }, - team: { - type: ObjectId, - ref: 'teams' - } - } - ] -}); - -module.exports = schema; +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; +const ObjectId = Schema.ObjectId; + +const schema = new Schema({ + name: { + type: String, + required: true + }, + description: { + type: String, + required: true + }, + creator: { + type: ObjectId, + ref: 'users', + required: true + }, + approved: { + type: Boolean, + default: true + }, + event_start: { + type: Date, + required: true + }, + event_end: { + type: Date, + required: true + }, + created_at: { + type: Date, + default: Date.now + }, + updated_at: { + type: Date, + default: Date.now + }, + location: { + type: ObjectId, + ref: 'venues' + }, + goal: Number, + mapping_goal: Number, + participant_goal: Number, + participant_limit: Number, + type: String, + image: { + type: String, + default: '/images/icon_pin_mapathon_water.png' + }, + company: { + name: String, + address: String + }, + charity: { + name: String, + email: String, + website: String + }, + teams: [ + { + type: ObjectId, + ref: 'teams' + } + ], + members: [ + { + _id: false, + user: { + type: ObjectId, + ref: 'users' + }, + team: { + type: ObjectId, + ref: 'teams' + } + } + ] +}); + +module.exports = schema; diff --git a/src/scripts/db/old-schemas/photo.js b/src/scripts/db/old-schemas/photo.js index d6cf920..e416234 100644 --- a/src/scripts/db/old-schemas/photo.js +++ b/src/scripts/db/old-schemas/photo.js @@ -1,37 +1,37 @@ -const mongoose = require('mongoose'); - -const reviewSchema = new mongoose.Schema({ - review_id: { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'reviews' - }, - venue_id: { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'venues' - }, - user_id: { - type: mongoose.Schema.ObjectId, - index: true - }, - flag: Number, - flaggers: [ - { - type: mongoose.Schema.ObjectId, - index: true - } - ], - s3_id: String, - url: String, - created_at: { - type: Date, - default: Date.now - }, - updated_at: { - type: Date, - default: Date.now - } -}); - -module.exports = reviewSchema; +const mongoose = require('mongoose'); + +const reviewSchema = new mongoose.Schema({ + review_id: { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'reviews' + }, + venue_id: { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'venues' + }, + user_id: { + type: mongoose.Schema.ObjectId, + index: true + }, + flag: Number, + flaggers: [ + { + type: mongoose.Schema.ObjectId, + index: true + } + ], + s3_id: String, + url: String, + created_at: { + type: Date, + default: Date.now + }, + updated_at: { + type: Date, + default: Date.now + } +}); + +module.exports = reviewSchema; diff --git a/src/scripts/db/old-schemas/review.js b/src/scripts/db/old-schemas/review.js index 23ba9a9..2e9e45a 100644 --- a/src/scripts/db/old-schemas/review.js +++ b/src/scripts/db/old-schemas/review.js @@ -1,81 +1,81 @@ -const mongoose = require('mongoose'); - -const reviewSchema = new mongoose.Schema({ - venue_id: { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'venues' - }, - user_id: { - type: mongoose.Schema.ObjectId, - index: true - }, - team: { - type: mongoose.Schema.ObjectId, - ref: 'teams' - }, - event: { - type: mongoose.Schema.ObjectId, - ref: 'events' - }, - entry: Number, - bathroom: Number, - spacious: { - type: Boolean, - default: false - }, - quiet: { - type: Boolean, - default: false - }, - parking: { - type: Boolean, - default: false - }, - ramp: { - type: Boolean, - default: false - }, - secondentrance: { - type: Boolean, - default: false - }, - guidedog: { - type: Boolean, - default: false - }, - welllit: { - type: Boolean, - default: false - }, - comment: String, - username: String, - abuse: Number, - flag: Number, - flaggers: [ - { - type: mongoose.Schema.ObjectId, - index: true - } - ], - deleted: Boolean, - steps: Number, - votes: Number, - images: [ - { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'photos' - } - ], - created_at: { - type: Date, - default: Date.now - }, - updated_at: { - type: Date, - default: Date.now - } -}); - -module.exports = reviewSchema; +const mongoose = require('mongoose'); + +const reviewSchema = new mongoose.Schema({ + venue_id: { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'venues' + }, + user_id: { + type: mongoose.Schema.ObjectId, + index: true + }, + team: { + type: mongoose.Schema.ObjectId, + ref: 'teams' + }, + event: { + type: mongoose.Schema.ObjectId, + ref: 'events' + }, + entry: Number, + bathroom: Number, + spacious: { + type: Boolean, + default: false + }, + quiet: { + type: Boolean, + default: false + }, + parking: { + type: Boolean, + default: false + }, + ramp: { + type: Boolean, + default: false + }, + secondentrance: { + type: Boolean, + default: false + }, + guidedog: { + type: Boolean, + default: false + }, + welllit: { + type: Boolean, + default: false + }, + comment: String, + username: String, + abuse: Number, + flag: Number, + flaggers: [ + { + type: mongoose.Schema.ObjectId, + index: true + } + ], + deleted: Boolean, + steps: Number, + votes: Number, + images: [ + { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'photos' + } + ], + created_at: { + type: Date, + default: Date.now + }, + updated_at: { + type: Date, + default: Date.now + } +}); + +module.exports = reviewSchema; diff --git a/src/scripts/db/old-schemas/team.js b/src/scripts/db/old-schemas/team.js index be70c88..85581c3 100644 --- a/src/scripts/db/old-schemas/team.js +++ b/src/scripts/db/old-schemas/team.js @@ -1,49 +1,49 @@ -const mongoose = require('mongoose'); - -const venueSchema = new mongoose.Schema({ - name: String, - goal: Number, - corporation: String, - description: String, - password: String, - image: { - type: String, - default: '/images/icon_team.png' - }, - creator: { - type: mongoose.Schema.ObjectId, - ref: 'users' - }, - events: [ - { - type: mongoose.Schema.ObjectId, - ref: 'events' - } - ], - updated_at: { - type: Date, - default: Date.now - }, - created_at: { - type: Date, - default: Date.now - }, - members: [ - { - type: mongoose.Schema.ObjectId, - ref: 'users' - } - ], - invites: [ - { - type: mongoose.Schema.ObjectId, - ref: 'invites' - } - ], - approved: { - type: Boolean, - default: true - } -}); - -module.exports = venueSchema; +const mongoose = require('mongoose'); + +const venueSchema = new mongoose.Schema({ + name: String, + goal: Number, + corporation: String, + description: String, + password: String, + image: { + type: String, + default: '/images/icon_team.png' + }, + creator: { + type: mongoose.Schema.ObjectId, + ref: 'users' + }, + events: [ + { + type: mongoose.Schema.ObjectId, + ref: 'events' + } + ], + updated_at: { + type: Date, + default: Date.now + }, + created_at: { + type: Date, + default: Date.now + }, + members: [ + { + type: mongoose.Schema.ObjectId, + ref: 'users' + } + ], + invites: [ + { + type: mongoose.Schema.ObjectId, + ref: 'invites' + } + ], + approved: { + type: Boolean, + default: true + } +}); + +module.exports = venueSchema; diff --git a/src/scripts/db/old-schemas/user.js b/src/scripts/db/old-schemas/user.js index 311e828..46664c3 100644 --- a/src/scripts/db/old-schemas/user.js +++ b/src/scripts/db/old-schemas/user.js @@ -1,125 +1,125 @@ -const mongoose = require('mongoose'); - -const userSchema = new mongoose.Schema({ - schema_version: Number, - name: { - first: { - type: String, - required: true - }, - last: { - type: String, - required: true - } - }, - fullName: String, - type: String, - description: String, - showEmail: { - type: Boolean, - default: true - }, - showPhone: { - type: Boolean, - default: true - }, - image: { - type: String, - default: '/images/icon_guy.png' - }, - company: { - name: String, - address: String - }, - email: { - type: String, - unique: true, - required: true - }, - phone: { - type: String - }, - location: { - type: String - }, - zip: { - type: String - }, - gender: { - type: String, - default: '' - }, - disabilitytype: { - type: String, - default: '' - }, - newsletter: { - type: Boolean, - default: true - }, - isactive: { - type: Boolean, - default: false - }, - isadmin: { - type: Boolean, - default: false - }, - salt: { - type: String - }, - hash: { - type: String - }, - token: { - type: String, - default: false - }, - activatedAt: { - type: Date - }, - createdAt: { - type: Date, - default: Date.now - }, - updatedAt: { - type: Date, - default: Date.now - }, - events: [ - { - type: mongoose.Schema.ObjectId, - ref: 'events' - } - ], - images: [ - { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'photos' - } - ], - teams: [ - { - type: mongoose.Schema.ObjectId, - ref: 'teams' - } - ], - reset: { - createdAt: Date, - link: mongoose.Schema.ObjectId - }, - foursquareId: String, - facebookAuth: String, - foursquareVerified: { - type: Boolean, - default: false - }, - facebookVerified: { - type: Boolean, - default: false - }, - username: String -}); - -module.exports = userSchema; +const mongoose = require('mongoose'); + +const userSchema = new mongoose.Schema({ + schema_version: Number, + name: { + first: { + type: String, + required: true + }, + last: { + type: String, + required: true + } + }, + fullName: String, + type: String, + description: String, + showEmail: { + type: Boolean, + default: true + }, + showPhone: { + type: Boolean, + default: true + }, + image: { + type: String, + default: '/images/icon_guy.png' + }, + company: { + name: String, + address: String + }, + email: { + type: String, + unique: true, + required: true + }, + phone: { + type: String + }, + location: { + type: String + }, + zip: { + type: String + }, + gender: { + type: String, + default: '' + }, + disabilitytype: { + type: String, + default: '' + }, + newsletter: { + type: Boolean, + default: true + }, + isactive: { + type: Boolean, + default: false + }, + isadmin: { + type: Boolean, + default: false + }, + salt: { + type: String + }, + hash: { + type: String + }, + token: { + type: String, + default: false + }, + activatedAt: { + type: Date + }, + createdAt: { + type: Date, + default: Date.now + }, + updatedAt: { + type: Date, + default: Date.now + }, + events: [ + { + type: mongoose.Schema.ObjectId, + ref: 'events' + } + ], + images: [ + { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'photos' + } + ], + teams: [ + { + type: mongoose.Schema.ObjectId, + ref: 'teams' + } + ], + reset: { + createdAt: Date, + link: mongoose.Schema.ObjectId + }, + foursquareId: String, + facebookAuth: String, + foursquareVerified: { + type: Boolean, + default: false + }, + facebookVerified: { + type: Boolean, + default: false + }, + username: String +}); + +module.exports = userSchema; diff --git a/src/scripts/db/old-schemas/venue.js b/src/scripts/db/old-schemas/venue.js index 490278f..fe44826 100644 --- a/src/scripts/db/old-schemas/venue.js +++ b/src/scripts/db/old-schemas/venue.js @@ -1,119 +1,119 @@ -const mongoose = require('mongoose'); - -const venueSchema = new mongoose.Schema({ - schema_version: Number, - google_id: { - type: String, - index: true - }, - google_ref: String, - place_id: { - type: String, - index: true - }, - name: String, - addr1: String, - addr2: String, - city: String, - state: String, - ph: String, - url: String, - types: Array, - ll: Array, - lngLat: { - type: Array, - index: '2d' - }, - google_rating: { - type: Number, - default: 0 - }, - google_url: String, - entry: { - type: Number, - default: 0 - }, - e_reviews: { - type: Number, - default: 0 - }, - bathroom: { - type: Number, - default: 0 - }, - b_reviews: { - type: Number, - default: 0 - }, - welllit: { - type: Number, - default: 0 - }, - spacious: { - type: Number, - default: 0 - }, - quiet: { - type: Number, - default: 0 - }, - parking: { - type: Number, - default: 0 - }, - ramp: { - type: Number, - default: 0 - }, - secondentrance: { - type: Number, - default: 0 - }, - guidedog: { - type: Number, - default: 0 - }, - steps: { - type: Number, - default: -1 - }, - steps_0: { - type: Number, - default: 0 - }, - steps_1: { - type: Number, - default: 0 - }, - steps_2: { - type: Number, - default: 0 - }, - steps_3: { - type: Number, - default: 0 - }, - created_at: { - type: Date, - default: Date.now - }, - updated_at: { - type: Date, - default: Date.now - }, - reviewdata: [ - { - type: mongoose.Schema.ObjectId, - ref: 'reviews' - } - ], - images: [ - { - type: mongoose.Schema.ObjectId, - index: true, - ref: 'photos' - } - ] -}); - -module.exports = venueSchema; +const mongoose = require('mongoose'); + +const venueSchema = new mongoose.Schema({ + schema_version: Number, + google_id: { + type: String, + index: true + }, + google_ref: String, + place_id: { + type: String, + index: true + }, + name: String, + addr1: String, + addr2: String, + city: String, + state: String, + ph: String, + url: String, + types: Array, + ll: Array, + lngLat: { + type: Array, + index: '2d' + }, + google_rating: { + type: Number, + default: 0 + }, + google_url: String, + entry: { + type: Number, + default: 0 + }, + e_reviews: { + type: Number, + default: 0 + }, + bathroom: { + type: Number, + default: 0 + }, + b_reviews: { + type: Number, + default: 0 + }, + welllit: { + type: Number, + default: 0 + }, + spacious: { + type: Number, + default: 0 + }, + quiet: { + type: Number, + default: 0 + }, + parking: { + type: Number, + default: 0 + }, + ramp: { + type: Number, + default: 0 + }, + secondentrance: { + type: Number, + default: 0 + }, + guidedog: { + type: Number, + default: 0 + }, + steps: { + type: Number, + default: -1 + }, + steps_0: { + type: Number, + default: 0 + }, + steps_1: { + type: Number, + default: 0 + }, + steps_2: { + type: Number, + default: 0 + }, + steps_3: { + type: Number, + default: 0 + }, + created_at: { + type: Date, + default: Date.now + }, + updated_at: { + type: Date, + default: Date.now + }, + reviewdata: [ + { + type: mongoose.Schema.ObjectId, + ref: 'reviews' + } + ], + images: [ + { + type: mongoose.Schema.ObjectId, + index: true, + ref: 'photos' + } + ] +}); + +module.exports = venueSchema; diff --git a/src/scripts/db/update-events-locations.js b/src/scripts/db/update-events-locations.js index 57ff40b..ead1a7f 100644 --- a/src/scripts/db/update-events-locations.js +++ b/src/scripts/db/update-events-locations.js @@ -1,150 +1,150 @@ -const axios = require('axios'); -const mongoose = require('mongoose'); - -require('dotenv').config(); - -const { eventSchema } = require('../../models/event'); -const { venueSchema } = require('../../models/venue'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db) { - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const Event = db.model('Event', eventSchema); - const Venue = db.model('Venue', venueSchema); - - let totalEvents; - try { - totalEvents = await Event.count(); - } catch (error) { - console.log('Events failed to be count'); - console.log(error); - await closeConnections(db); - } - - console.log(`Total events: ${totalEvents}`); - - let i = 0; - let page = 0; - const pageLimit = 100; - do { - let events; - try { - events = await Event.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Events failed to be found'); - console.log(error); - await closeConnections(db); - } - - console.log(`${events.length} events found`); - - const getVenues = events.map(e => Venue.findOne({ _id: e.venue })); - let venues; - try { - venues = await Promise.all(getVenues); - } catch (err) { - console.log('Venues failed to be found'); - console.log(err); - await closeConnections(db); - } - - console.log(`${venues.length} venues found`); - - const getPlaces = venues.map(v => { - if (v) { - return axios.get( - `https://maps.googleapis.com/maps/api/place/details/json?placeid=${ - v.placeId - }&key=${process.env.PLACES_API_KEY}` - ); - } - }); - let places; - try { - places = await Promise.all(getPlaces); - } catch (err) { - console.log('Places failed to be found'); - console.log(err); - await closeConnections(db); - } - - console.log(`${places.length} places found`); - - const updateEvents = []; - const removeEvents = []; - places.map((p, i) => { - if ((p && p.data && p.data.result) || venues[i]) { - const place = p && p.data && p.data.result ? p.data.result : undefined; - const event = events[i]; - event.address = place ? place.formatted_address : venues[i].address; - event.location.coordinates = place - ? [place.geometry.location.lng, place.geometry.location.lat] - : venues[i].location.coordinates; - updateEvents.push(event.save()); - } else { - const event = events[i]; - removeEvents.push(event.remove()); - } - }); - try { - await Promise.all([...updateEvents, ...removeEvents]); - } catch (err) { - console.log( - `Events failed to be updated.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(err); - await closeConnections(db); - } - - console.log('Events updated'); - - page = page + 1; - i = i + events.length; - console.log(i); - - try { - totalEvents = await Event.count(); - } catch (error) { - console.log('Events failed to be count'); - console.log(error); - await closeConnections(db); - } - } while (i < totalEvents); - - await closeConnections(db); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const axios = require('axios'); +const mongoose = require('mongoose'); + +require('dotenv').config(); + +const { eventSchema } = require('../../models/event'); +const { venueSchema } = require('../../models/venue'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db) { + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const Event = db.model('Event', eventSchema); + const Venue = db.model('Venue', venueSchema); + + let totalEvents; + try { + totalEvents = await Event.count(); + } catch (error) { + console.log('Events failed to be count'); + console.log(error); + await closeConnections(db); + } + + console.log(`Total events: ${totalEvents}`); + + let i = 0; + let page = 0; + const pageLimit = 100; + do { + let events; + try { + events = await Event.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Events failed to be found'); + console.log(error); + await closeConnections(db); + } + + console.log(`${events.length} events found`); + + const getVenues = events.map((e) => Venue.findOne({ _id: e.venue })); + let venues; + try { + venues = await Promise.all(getVenues); + } catch (err) { + console.log('Venues failed to be found'); + console.log(err); + await closeConnections(db); + } + + console.log(`${venues.length} venues found`); + + const getPlaces = venues.map((v) => { + if (v) { + return axios.get( + `https://maps.googleapis.com/maps/api/place/details/json?placeid=${ + v.placeId + }&key=${process.env.PLACES_API_KEY}` + ); + } + }); + let places; + try { + places = await Promise.all(getPlaces); + } catch (err) { + console.log('Places failed to be found'); + console.log(err); + await closeConnections(db); + } + + console.log(`${places.length} places found`); + + const updateEvents = []; + const removeEvents = []; + places.map((p, i) => { + if ((p && p.data && p.data.result) || venues[i]) { + const place = p && p.data && p.data.result ? p.data.result : undefined; + const event = events[i]; + event.address = place ? place.formatted_address : venues[i].address; + event.location.coordinates = place + ? [place.geometry.location.lng, place.geometry.location.lat] + : venues[i].location.coordinates; + updateEvents.push(event.save()); + } else { + const event = events[i]; + removeEvents.push(event.remove()); + } + }); + try { + await Promise.all([...updateEvents, ...removeEvents]); + } catch (err) { + console.log( + `Events failed to be updated.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(err); + await closeConnections(db); + } + + console.log('Events updated'); + + page = page + 1; + i = i + events.length; + console.log(i); + + try { + totalEvents = await Event.count(); + } catch (error) { + console.log('Events failed to be count'); + console.log(error); + await closeConnections(db); + } + } while (i < totalEvents); + + await closeConnections(db); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/update-events-posters.js b/src/scripts/db/update-events-posters.js index 8159465..03c2df0 100644 --- a/src/scripts/db/update-events-posters.js +++ b/src/scripts/db/update-events-posters.js @@ -1,160 +1,160 @@ -const aws = require('aws-sdk'); -const jimp = require('jimp'); -const mongoose = require('mongoose'); -const randomstring = require('randomstring'); - -require('dotenv').config(); - -const { eventSchema } = require('../../models/event'); - -mongoose.Promise = global.Promise; - -const s3 = new aws.S3(); - -async function closeConnections(db) { - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const Event = db.model('Event', eventSchema); - - let totalEvents; - try { - totalEvents = await Event.count(); - } catch (error) { - console.log('Events failed to be count'); - console.log(error); - await closeConnections(db); - } - - console.log(`Total events: ${totalEvents}`); - - let i = 0; - let page = 0; - const pageLimit = 100; - do { - let events; - try { - events = await Event.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Teams failed to be found'); - console.log(error); - await closeConnections(db); - } - - const updateEvents = []; - const uploadEventsPosters = []; - for (let event of events) { - if (event.poster && !event.poster.includes('icon_guy')) { - let posterImage; - try { - posterImage = await jimp.read(encodeURI(event.poster)); - } catch (err) { - console.log('Event poster image failed to be read'); - console.log(err); - await closeConnections(db); - } - - if (posterImage) { - const posterExtension = posterImage.getExtension(); - const posterFileName = `${Date.now()}${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}.${posterExtension}`; - - if ( - posterExtension === 'png' || - posterExtension === 'jpeg' || - posterExtension === 'jpg' || - posterExtension === 'bmp' - ) { - const posterMIME = posterImage.getMIME(); - if (posterMIME) { - event.poster = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/events/posters/${posterFileName}`; - posterImage - .cover(400, 400) - .quality(85) - .getBuffer(posterMIME, async (err, posterBuffer) => { - if (err) { - console.log('Event poster buffer failed to be read'); - console.log(err); - await closeConnections(db); - } - - uploadEventsPosters.push( - s3 - .putObject({ - ACL: 'public-read', - Body: posterBuffer, - Bucket: process.env.AWS_S3_BUCKET, - ContentType: posterImage.getMIME(), - Key: `events/posters/${posterFileName}` - }) - .promise() - ); - }); - } else { - event.poster = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/events/posters/default.png`; - } - } - } - } else { - event.poster = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/events/posters/default.png`; - } - updateEvents.push(event.save()); - } - - try { - await Promise.all([...updateEvents, ...uploadEventsPosters]); - } catch (err) { - console.log( - `Events failed to be updated.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(err); - await closeConnections(db); - } - - page = page + 1; - i = i + events.length; - console.log(i); - } while (i < totalEvents); - - await closeConnections(db); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const aws = require('aws-sdk'); +const jimp = require('jimp'); +const mongoose = require('mongoose'); +const randomstring = require('randomstring'); + +require('dotenv').config(); + +const { eventSchema } = require('../../models/event'); + +mongoose.Promise = global.Promise; + +const s3 = new aws.S3(); + +async function closeConnections(db) { + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const Event = db.model('Event', eventSchema); + + let totalEvents; + try { + totalEvents = await Event.count(); + } catch (error) { + console.log('Events failed to be count'); + console.log(error); + await closeConnections(db); + } + + console.log(`Total events: ${totalEvents}`); + + let i = 0; + let page = 0; + const pageLimit = 100; + do { + let events; + try { + events = await Event.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Teams failed to be found'); + console.log(error); + await closeConnections(db); + } + + const updateEvents = []; + const uploadEventsPosters = []; + for (let event of events) { + if (event.poster && !event.poster.includes('icon_guy')) { + let posterImage; + try { + posterImage = await jimp.read(encodeURI(event.poster)); + } catch (err) { + console.log('Event poster image failed to be read'); + console.log(err); + await closeConnections(db); + } + + if (posterImage) { + const posterExtension = posterImage.getExtension(); + const posterFileName = `${Date.now()}${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}.${posterExtension}`; + + if ( + posterExtension === 'png' || + posterExtension === 'jpeg' || + posterExtension === 'jpg' || + posterExtension === 'bmp' + ) { + const posterMIME = posterImage.getMIME(); + if (posterMIME) { + event.poster = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/events/posters/${posterFileName}`; + posterImage + .cover(400, 400) + .quality(85) + .getBuffer(posterMIME, async (err, posterBuffer) => { + if (err) { + console.log('Event poster buffer failed to be read'); + console.log(err); + await closeConnections(db); + } + + uploadEventsPosters.push( + s3 + .putObject({ + ACL: 'public-read', + Body: posterBuffer, + Bucket: process.env.AWS_S3_BUCKET, + ContentType: posterImage.getMIME(), + Key: `events/posters/${posterFileName}` + }) + .promise() + ); + }); + } else { + event.poster = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/events/posters/default.png`; + } + } + } + } else { + event.poster = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/events/posters/default.png`; + } + updateEvents.push(event.save()); + } + + try { + await Promise.all([...updateEvents, ...uploadEventsPosters]); + } catch (err) { + console.log( + `Events failed to be updated.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(err); + await closeConnections(db); + } + + page = page + 1; + i = i + events.length; + console.log(i); + } while (i < totalEvents); + + await closeConnections(db); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/update-events-reviews.js b/src/scripts/db/update-events-reviews.js index b2e2afe..bf9950e 100644 --- a/src/scripts/db/update-events-reviews.js +++ b/src/scripts/db/update-events-reviews.js @@ -1,104 +1,104 @@ -const mongoose = require('mongoose'); - -require('dotenv').config(); - -const { eventSchema } = require('../../models/event'); -const { reviewSchema } = require('../../models/review'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db) { - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const Event = db.model('Event', eventSchema); - const Review = db.model('Review', reviewSchema); - - let totalEvents; - try { - totalEvents = await Event.count(); - } catch (error) { - console.log('Events failed to be count'); - console.log(error); - await closeConnections(db); - } - - console.log(`Total events: ${totalEvents}`); - - let i = 0; - let page = 0; - const pageLimit = 100; - do { - let events; - try { - events = await Event.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Teams failed to be found'); - console.log(error); - await closeConnections(db); - } - - const updateEvents = []; - for (let event of events) { - let eventReviews; - try { - eventReviews = await Review.find({ event: event.id }).count(); - } catch (err) { - console.log('Event reviews failed to be count'); - console.log(err); - await closeConnections(db); - } - - event.reviewsAmount = eventReviews; - updateEvents.push(event.save()); - } - - try { - await Promise.all(updateEvents); - } catch (err) { - console.log( - `Events failed to be updated.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(err); - await closeConnections(db); - } - - page = page + 1; - i = i + events.length; - console.log(i); - } while (i < totalEvents); - - await closeConnections(db); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); +const mongoose = require('mongoose'); + +require('dotenv').config(); + +const { eventSchema } = require('../../models/event'); +const { reviewSchema } = require('../../models/review'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db) { + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const Event = db.model('Event', eventSchema); + const Review = db.model('Review', reviewSchema); + + let totalEvents; + try { + totalEvents = await Event.count(); + } catch (error) { + console.log('Events failed to be count'); + console.log(error); + await closeConnections(db); + } + + console.log(`Total events: ${totalEvents}`); + + let i = 0; + let page = 0; + const pageLimit = 100; + do { + let events; + try { + events = await Event.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Teams failed to be found'); + console.log(error); + await closeConnections(db); + } + + const updateEvents = []; + for (let event of events) { + let eventReviews; + try { + eventReviews = await Review.find({ event: event.id }).count(); + } catch (err) { + console.log('Event reviews failed to be count'); + console.log(err); + await closeConnections(db); + } + + event.reviewsAmount = eventReviews; + updateEvents.push(event.save()); + } + + try { + await Promise.all(updateEvents); + } catch (err) { + console.log( + `Events failed to be updated.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(err); + await closeConnections(db); + } + + page = page + 1; + i = i + events.length; + console.log(i); + } while (i < totalEvents); + + await closeConnections(db); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); diff --git a/src/scripts/db/update-users-avatars.js b/src/scripts/db/update-users-avatars.js index 59e21c5..5df6f61 100644 --- a/src/scripts/db/update-users-avatars.js +++ b/src/scripts/db/update-users-avatars.js @@ -1,206 +1,206 @@ -const aws = require('aws-sdk'); -const jimp = require('jimp'); -const mongoose = require('mongoose'); -const randomstring = require('randomstring'); - -require('dotenv').config(); - -const { userSchema } = require('../../models/user'); - -const oldUserSchema = require('./old-schemas/user'); - -mongoose.Promise = global.Promise; - -async function closeConnections(db, oldDb) { - try { - await oldDb.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - try { - await db.close(); - } catch (error) { - console.log(error); - process.exit(0); - } - - process.exit(0); -} - -const uri = process.env.MONGODB_URI; -const options = { - useMongoClient: true, - socketTimeoutMS: 0, - keepAlive: 2000 -}; -const db = mongoose.createConnection(uri, options); - -db.on('connected', async () => { - console.log('Connection to DB established successfully'); - - const oldUri = process.env.OLD_DB_URI; - const oldDb = mongoose.createConnection(oldUri, options); - - oldDb.on('connected', async () => { - console.log('Connection to old DB established successfully'); - - const OldUser = oldDb.model('users', oldUserSchema); - - let totalOldUsers; - try { - totalOldUsers = await OldUser.count(); - } catch (error) { - console.log('Old users failed to be count'); - console.log(error); - await closeConnections(db, oldDb); - } - - console.log(`Total old users: ${totalOldUsers}`); - - let page = 0; - const pageLimit = 100; - let i = 0; - do { - let oldUsers; - try { - oldUsers = await OldUser.find({}) - .skip(page * pageLimit) - .limit(pageLimit); - } catch (error) { - console.log('Old users failed to be found'); - console.log(error); - await closeConnections(db, oldDb); - } - - const User = db.model('User', userSchema); - - const getUsersImages = []; - const usersToUpdate = []; - for (let oldUser of oldUsers) { - if (oldUser.isactive) { - if (oldUser.image && !oldUser.image.includes('icon_guy.png')) { - getUsersImages.push(jimp.read(encodeURI(oldUser.image))); - usersToUpdate.push(oldUser.id); - } - } - } - - if (getUsersImages.length > 0) { - let usersImages; - try { - usersImages = await Promise.all(getUsersImages); - } catch (error) { - console.log( - `Old users images failed to be found.\nData: ${JSON.stringify({ - page, - i - })}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - - const usersAvatars = []; - for (let i = 0; i < usersImages.length; i++) { - usersImages[i].cover(400, 400).quality(60); - usersImages[i].getBuffer( - usersImages[i].getMIME(), - (error, bufferImage) => { - if (error) { - console.log(error); - } - - const extension = usersImages[i].getExtension(); - if ( - extension === 'png' || - extension === 'jpeg' || - extension === 'jpg' || - extension === 'bmp' - ) { - usersAvatars.push({ - body: bufferImage, - extension: extension, - mime: usersImages[i].getMIME(), - userId: usersToUpdate[i] - }); - } - } - ); - } - - const s3 = new aws.S3(); - const uploadUsersAvatars = []; - const updateUsersAvatars = []; - for (let userAvatar of usersAvatars) { - let fileName = `${Date.now()}${randomstring.generate({ - length: 5, - capitalization: 'lowercase' - })}.${userAvatar.extension}`; - - uploadUsersAvatars.push( - s3 - .putObject({ - ACL: 'public-read', - Body: userAvatar.body, - Bucket: process.env.AWS_S3_BUCKET, - ContentType: userAvatar.mime, - Key: `users/avatars/${fileName}` - }) - .promise() - ); - - let avatar = `https://s3.amazonaws.com/${ - process.env.AWS_S3_BUCKET - }/users/avatars/${fileName}`; - - updateUsersAvatars.push( - User.update({ _id: userAvatar.userId }, { $set: { avatar } }) - ); - } - - try { - await Promise.all([...uploadUsersAvatars, ...updateUsersAvatars]); - } catch (error) { - console.log( - `Users images failed to be uploaded or updated.\nData: ${JSON.stringify( - { - page, - i - } - )}` - ); - console.log(error); - await closeConnections(db, oldDb); - } - } - - page = page + 1; - i = i + oldUsers.length; - console.log(i); - } while (i < totalOldUsers); - - await closeConnections(db, oldDb); - }); - - oldDb.on('error', err => { - console.log('Connection to old DB failed ' + err); - process.exit(0); - }); - - oldDb.on('disconnected', () => { - console.log('Connection from old DB closed'); - }); -}); - -db.on('error', err => { - console.log('Connection to DB failed ' + err); - process.exit(0); -}); - -db.on('disconnected', () => { - console.log('Connection from DB closed'); -}); - -process.on('SIGINT', () => db.close()); +const aws = require('aws-sdk'); +const jimp = require('jimp'); +const mongoose = require('mongoose'); +const randomstring = require('randomstring'); + +require('dotenv').config(); + +const { userSchema } = require('../../models/user'); + +const oldUserSchema = require('./old-schemas/user'); + +mongoose.Promise = global.Promise; + +async function closeConnections(db, oldDb) { + try { + await oldDb.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + try { + await db.close(); + } catch (error) { + console.log(error); + process.exit(0); + } + + process.exit(0); +} + +const uri = process.env.MONGODB_URI; +const options = { + useMongoClient: true, + socketTimeoutMS: 0, + keepAlive: 2000 +}; +const db = mongoose.createConnection(uri, options); + +db.on('connected', async () => { + console.log('Connection to DB established successfully'); + + const oldUri = process.env.OLD_DB_URI; + const oldDb = mongoose.createConnection(oldUri, options); + + oldDb.on('connected', async () => { + console.log('Connection to old DB established successfully'); + + const OldUser = oldDb.model('users', oldUserSchema); + + let totalOldUsers; + try { + totalOldUsers = await OldUser.count(); + } catch (error) { + console.log('Old users failed to be count'); + console.log(error); + await closeConnections(db, oldDb); + } + + console.log(`Total old users: ${totalOldUsers}`); + + let page = 0; + const pageLimit = 100; + let i = 0; + do { + let oldUsers; + try { + oldUsers = await OldUser.find({}) + .skip(page * pageLimit) + .limit(pageLimit); + } catch (error) { + console.log('Old users failed to be found'); + console.log(error); + await closeConnections(db, oldDb); + } + + const User = db.model('User', userSchema); + + const getUsersImages = []; + const usersToUpdate = []; + for (let oldUser of oldUsers) { + if (oldUser.isactive) { + if (oldUser.image && !oldUser.image.includes('icon_guy.png')) { + getUsersImages.push(jimp.read(encodeURI(oldUser.image))); + usersToUpdate.push(oldUser.id); + } + } + } + + if (getUsersImages.length > 0) { + let usersImages; + try { + usersImages = await Promise.all(getUsersImages); + } catch (error) { + console.log( + `Old users images failed to be found.\nData: ${JSON.stringify({ + page, + i + })}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + + const usersAvatars = []; + for (let i = 0; i < usersImages.length; i++) { + usersImages[i].cover(400, 400).quality(60); + usersImages[i].getBuffer( + usersImages[i].getMIME(), + (error, bufferImage) => { + if (error) { + console.log(error); + } + + const extension = usersImages[i].getExtension(); + if ( + extension === 'png' || + extension === 'jpeg' || + extension === 'jpg' || + extension === 'bmp' + ) { + usersAvatars.push({ + body: bufferImage, + extension: extension, + mime: usersImages[i].getMIME(), + userId: usersToUpdate[i] + }); + } + } + ); + } + + const s3 = new aws.S3(); + const uploadUsersAvatars = []; + const updateUsersAvatars = []; + for (let userAvatar of usersAvatars) { + let fileName = `${Date.now()}${randomstring.generate({ + length: 5, + capitalization: 'lowercase' + })}.${userAvatar.extension}`; + + uploadUsersAvatars.push( + s3 + .putObject({ + ACL: 'public-read', + Body: userAvatar.body, + Bucket: process.env.AWS_S3_BUCKET, + ContentType: userAvatar.mime, + Key: `users/avatars/${fileName}` + }) + .promise() + ); + + let avatar = `https://s3.amazonaws.com/${ + process.env.AWS_S3_BUCKET + }/users/avatars/${fileName}`; + + updateUsersAvatars.push( + User.update({ _id: userAvatar.userId }, { $set: { avatar } }) + ); + } + + try { + await Promise.all([...uploadUsersAvatars, ...updateUsersAvatars]); + } catch (error) { + console.log( + `Users images failed to be uploaded or updated.\nData: ${JSON.stringify( + { + page, + i + } + )}` + ); + console.log(error); + await closeConnections(db, oldDb); + } + } + + page = page + 1; + i = i + oldUsers.length; + console.log(i); + } while (i < totalOldUsers); + + await closeConnections(db, oldDb); + }); + + oldDb.on('error', (err) => { + console.log('Connection to old DB failed ' + err); + process.exit(0); + }); + + oldDb.on('disconnected', () => { + console.log('Connection from old DB closed'); + }); +}); + +db.on('error', (err) => { + console.log('Connection to DB failed ' + err); + process.exit(0); +}); + +db.on('disconnected', () => { + console.log('Connection from DB closed'); +}); + +process.on('SIGINT', () => db.close()); From 6e79fb2211717bfbd254127be6e6fe3dd868b25e Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 20 Feb 2025 19:42:12 +0500 Subject: [PATCH 02/67] minor issues fixed --- src/index.js | 84 +++++++------ src/routes/auth/sign-up.js | 54 ++++----- src/routes/events/list-events.js | 3 +- src/routes/photos/delete-photo.js | 18 +-- src/routes/photos/index.js | 12 +- src/routes/teams/list-teams.js | 32 ++--- src/routes/users/get-profile.js | 20 ++-- src/routes/venues/list-venues.js | 190 +++++++++++++++++------------- 8 files changed, 228 insertions(+), 185 deletions(-) diff --git a/src/index.js b/src/index.js index 6c650e1..efdd209 100644 --- a/src/index.js +++ b/src/index.js @@ -1,81 +1,89 @@ -const fs = require('fs'); -const https = require('https'); +const fs = require("fs"); +const https = require("https"); -const bodyParser = require('body-parser'); -const cors = require('cors'); -const express = require('express'); -const helmet = require('helmet'); -const ip = require('ip'); -const morgan = require('morgan'); -const raven = require('raven'); +const bodyParser = require("body-parser"); +const cors = require("cors"); +const express = require("express"); +const helmet = require("helmet"); +const ip = require("ip"); +const morgan = require("morgan"); +const raven = require("raven"); // Fill process.env with environment variables -require('dotenv').config(); +require("dotenv").config(); //console.log(process.env) const port = process.env.PORT || 8000; - -const connectToDB = require('./helpers/db-connector'); -const routes = require('./routes'); +const connectToDB = require("./helpers/db-connector"); +const routes = require("./routes"); function connectedToDB() { const app = express(); raven .config(process.env.SENTRY_URL, { - captureUnhandledRejections: true + captureUnhandledRejections: true, }) .install(); // Middlewares app.use(raven.requestHandler()); app.use(cors()); - app.use(morgan('dev')); + app.use(morgan("dev")); app.use(bodyParser.json()); app.use(helmet()); // Routes - app.set('strict routing', true); - app.use('/', routes); + app.set("strict routing", true); + app.get("/", (req, res) => { + console.log("calling / route"); + res.send("server is up"); + }); + app.use("/", routes); // Error handling app.use(raven.errorHandler()); - app.use((req, res) => res.status(404).json({ general: 'Not found' })); + app.use((req, res) => res.status(404).json({ general: "Not found" })); app.use((err, req, res) => { if (err instanceof SyntaxError) { - return res.status(400).json({ general: 'Invalid JSON format' }); + return res.status(400).json({ general: "Invalid JSON format" }); } console.error(err.stack); - return res.status(500).json({ general: 'Something went wrong' }); + return res.status(500).json({ general: "Something went wrong" }); }); - process.on('uncaughtException', (err) => { + process.on("uncaughtException", (err) => { console.error(err); raven.captureException(err); }); - process.on('unhandledRejection', (err) => { + process.on("unhandledRejection", (err) => { console.error(err); raven.captureException(err); }); - // App Initialization - if (process.env.NODE_ENV === 'production') { + app.listen(port, () => { console.log(`Listening on http://${ip.address()}:${port}`); - app.listen(port); - } else { - https - .createServer( - { - key: fs.readFileSync('./certificates/server.key'), - cert: fs.readFileSync('./certificates/server.crt') - }, - app - ) - .listen(port, () => - console.log(`Listening on https://${ip.address()}:${port}`) - ); - } + }); + + // App Initialization + // if (process.env.NODE_ENV === "production") { + // app.listen(port, () => { + // console.log(`Listening on http://${ip.address()}:${port}`); + // }); + // } else { + // https + // .createServer( + // { + // key: fs.readFileSync("./certificates/server.key"), + // cert: fs.readFileSync("./certificates/server.crt"), + // }, + // app + // ) + // .listen(port, () => + // console.log(`Listening on https://${ip.address()}:${port}`) + // ); + // } } connectToDB(connectedToDB); diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 6bdf8a7..6367411 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -1,15 +1,15 @@ -const crypto = require('crypto'); +const crypto = require("crypto"); -const moment = require('moment'); -const { pick } = require('lodash'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); +const moment = require("moment"); +const { pick } = require("lodash"); +const randomstring = require("randomstring"); +const slugify = require("speakingurl"); -const { ActivationTicket } = require('../../models/activation-ticket'); -const { cleanSpaces, sendEmail } = require('../../helpers'); -const { User } = require('../../models/user'); +const { ActivationTicket } = require("../../models/activation-ticket"); +const { cleanSpaces, sendEmail } = require("../../helpers"); +const { User } = require("../../models/user"); -const { validateSignUp } = require('./validations'); +const { validateSignUp } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateSignUp(req.body); @@ -18,11 +18,11 @@ module.exports = async (req, res, next) => { } const data = pick(req.body, [ - 'email', - 'firstName', - 'isSubscribed', - 'lastName', - 'password' + "email", + "firstName", + "isSubscribed", + "lastName", + "password", ]); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); @@ -45,7 +45,7 @@ module.exports = async (req, res, next) => { const today = moment.utc(); if (expiresAt.isBefore(today)) { try { - await activationTicket.remove(); + await ActivationTicket.deleteOne({ _id: activationTicket._id }); } catch (err) { console.log( `Activation ticket with email ${ @@ -61,17 +61,17 @@ module.exports = async (req, res, next) => { try { repeatedUsers = await User.find({ $or: [{ email: data.email }, { username: data.username }], - isArchived: false + isArchived: false, }); } catch (err) { - console.log('Users failed to be found at sign-up.'); + console.log("Users failed to be found at sign-up."); return next(err); } if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === data.email) { - return res.status(400).json({ email: 'Is already taken' }); + return res.status(400).json({ email: "Is already taken" }); } let repeatedUser; @@ -80,13 +80,13 @@ module.exports = async (req, res, next) => { data.lastName )}-${randomstring.generate({ length: 5, - capitalization: 'lowercase' + capitalization: "lowercase", })}`; try { repeatedUser = await User.findOne({ username: data.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -99,10 +99,10 @@ module.exports = async (req, res, next) => { } const today = moment.utc(); - const expiresAt = today.add(1, 'days').toDate(); + const expiresAt = today.add(1, "days").toDate(); const key = `${crypto .randomBytes(31) - .toString('hex')}${new Date().getTime().toString()}`; + .toString("hex")}${new Date().getTime().toString()}`; const activationTicketData = { email: data.email, @@ -113,8 +113,8 @@ module.exports = async (req, res, next) => { isSubscribed: data.isSubscribed, lastName: data.lastName, password: data.password, - username: data.username - } + username: data.username, + }, }; try { activationTicket = await ActivationTicket.create(activationTicketData); @@ -127,7 +127,7 @@ module.exports = async (req, res, next) => { return next(err); } - const subject = 'Activate Account'; + const subject = "Activate Account"; const htmlContent = `

Welcome to AXS Map!

To activate your account use the link below:

@@ -151,8 +151,8 @@ module.exports = async (req, res, next) => { subject, htmlContent, textContent, - receiversEmails + receiversEmails, }); - return res.status(201).json({ general: 'Success' }); + return res.status(201).json({ general: "Success" }); }; diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 7f75d82..3b29373 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -53,6 +53,7 @@ module.exports = async (req, res, next) => { reviewsAmount: 1, reviewsGoal: 1, startDate: 1, + location: 1, description: 1, }) .sort(sortBy) @@ -76,7 +77,7 @@ module.exports = async (req, res, next) => { page = null; lastPage = null; } - + console.log(events); return res.status(200).json({ page: page + 1, lastPage, diff --git a/src/routes/photos/delete-photo.js b/src/routes/photos/delete-photo.js index a859696..03152f1 100644 --- a/src/routes/photos/delete-photo.js +++ b/src/routes/photos/delete-photo.js @@ -1,6 +1,6 @@ -const aws = require('aws-sdk'); +const aws = require("aws-sdk"); -const { Photo } = require('../../models/photo'); +const { Photo } = require("../../models/photo"); module.exports = async (req, res, next) => { const photoFileName = req.params.photoFileName; @@ -9,8 +9,8 @@ module.exports = async (req, res, next) => { try { photo = await Photo.findOne({ fileName: photoFileName }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Photo not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Photo not found" }); } console.log(`Photo ${photoFileName} failed to be found at delete-photo`); @@ -19,7 +19,7 @@ module.exports = async (req, res, next) => { if (photo) { try { - await photo.remove(); + await photo.deleteOne({ fileName: photoFileName }); } catch (err) { console.log( `Photo ${photoFileName} failed to be deleted at delete-photo` @@ -28,20 +28,20 @@ module.exports = async (req, res, next) => { } } - if (!photoFileName.includes('default')) { + if (!photoFileName.includes("default")) { const s3 = new aws.S3(); try { await s3 .deleteObject({ Bucket: process.env.AWS_S3_BUCKET, - Key: `photos/${photoFileName}` + Key: `photos/${photoFileName}`, }) .promise(); } catch (err) { - console.log('Photo failed to be deleted at delete-photo'); + console.log("Photo failed to be deleted at delete-photo"); return next(err); } } - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); }; diff --git a/src/routes/photos/index.js b/src/routes/photos/index.js index c1c7280..d5640d2 100644 --- a/src/routes/photos/index.js +++ b/src/routes/photos/index.js @@ -1,15 +1,15 @@ -const express = require('express'); +const express = require("express"); -const { isAuthenticated } = require('../../helpers'); +const { isAuthenticated } = require("../../helpers"); -const createPhoto = require('./create-photo'); -const deletePhoto = require('./delete-photo'); +const createPhoto = require("./create-photo"); +const deletePhoto = require("./delete-photo"); const router = new express.Router(); -router.post('', isAuthenticated({ isOptional: false }), createPhoto); +router.post("", isAuthenticated({ isOptional: false }), createPhoto); router.delete( - '/:photoFileName', + "/:photoFileName", isAuthenticated({ isOptional: false }), deletePhoto ); diff --git a/src/routes/teams/list-teams.js b/src/routes/teams/list-teams.js index 605bcf6..f3a9938 100644 --- a/src/routes/teams/list-teams.js +++ b/src/routes/teams/list-teams.js @@ -1,9 +1,9 @@ -const mongoose = require('mongoose'); -const { toBoolean } = require('validator'); +const mongoose = require("mongoose"); +const { toBoolean } = require("validator"); -const { Team } = require('../../models/team'); +const { Team } = require("../../models/team"); -const { validateListTeams } = require('./validations'); +const { validateListTeams } = require("./validations"); module.exports = async (req, res, next) => { const queryParams = req.query; @@ -21,18 +21,20 @@ module.exports = async (req, res, next) => { if (!req.user) { return res .status(400) - .json({ general: 'You cannot use managed filter as anonymous' }); + .json({ general: "You cannot use managed filter as anonymous" }); } const managed = toBoolean(queryParams.managed); if (managed) { teamsQuery.managers = { $in: [new mongoose.Types.ObjectId(req.user.id)] }; } else { - teamsQuery.managers = { $nin: [new mongoose.Types.ObjectId(req.user.id)] }; + teamsQuery.managers = { + $nin: [new mongoose.Types.ObjectId(req.user.id)], + }; } } - let sortBy = queryParams.sortBy || '-reviewsAmount'; + let sortBy = queryParams.sortBy || "-reviewsAmount"; let page = queryParams.page ? Number(queryParams.page) - 1 : 0; const pageLimit = Number(queryParams.pageLimit) || 12; @@ -44,31 +46,31 @@ module.exports = async (req, res, next) => { .match(teamsQuery) .project({ _id: 0, - id: '$_id', + id: "$_id", avatar: 1, description: 1, name: 1, - reviewsAmount: 1 + reviewsAmount: 1, }) .sort(sortBy) .skip(page * pageLimit) .limit(pageLimit), - Team.find(teamsQuery).count() + Team.countDocuments(teamsQuery), ]); } catch (err) { - console.log('Teams failed to be found or count at list-teams'); + console.log("Teams failed to be found or count at list-teams"); return next(err); } const getTeamsRankings = teams.map((t) => - Team.find({ reviewsAmount: { $gt: t.reviewsAmount } }).count() + Team.countDocuments({ reviewsAmount: { $gt: t.reviewsAmount } }) ); let teamsRankings; try { teamsRankings = await Promise.all(getTeamsRankings); } catch (err) { - console.log('Teams rankings failed to be count at list-teams'); + console.log("Teams rankings failed to be count at list-teams"); return next(err); } @@ -78,7 +80,7 @@ module.exports = async (req, res, next) => { description: t.description, name: t.name, ranking: teamsRankings[i] + 1, - reviewsAmount: t.reviewsAmount + reviewsAmount: t.reviewsAmount, })); let lastPage = Math.ceil(total / pageLimit); @@ -99,6 +101,6 @@ module.exports = async (req, res, next) => { pageLimit, total, sortBy, - results: teams + results: teams, }); }; diff --git a/src/routes/users/get-profile.js b/src/routes/users/get-profile.js index f9685c0..a231a20 100644 --- a/src/routes/users/get-profile.js +++ b/src/routes/users/get-profile.js @@ -1,13 +1,14 @@ -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); +const { Event } = require("../../models/event"); +const { Team } = require("../../models/team"); module.exports = async (req, res, next) => { + console.log(req.user.teams); const getUserTeams = req.user.teams.map((t) => Team.findOne({ _id: t })); let userTeams; try { userTeams = await Promise.all(getUserTeams); } catch (err) { - console.log('Teams failed to be found at get-profile'); + console.log("Teams failed to be found at get-profile"); return next(err); } @@ -20,13 +21,13 @@ module.exports = async (req, res, next) => { managedTeams.push({ id: t.id.toString(), avatar: t.avatar, - name: t.name + name: t.name, }); } else { teams.push({ id: t.id.toString(), avatar: t.avatar, - name: t.name + name: t.name, }); } } @@ -37,7 +38,7 @@ module.exports = async (req, res, next) => { try { userEvents = await Promise.all(getUserEvents); } catch (err) { - console.log('Events failed to be found at get-profile'); + console.log("Events failed to be found at get-profile"); return next(err); } @@ -52,7 +53,7 @@ module.exports = async (req, res, next) => { endDate: e.endDate, name: e.name, poster: e.poster, - startDate: e.startDate + startDate: e.startDate, }); } else { events.push({ @@ -60,7 +61,7 @@ module.exports = async (req, res, next) => { endDate: e.endDate, name: e.name, poster: e.poster, - startDate: e.startDate + startDate: e.startDate, }); } } @@ -87,7 +88,8 @@ module.exports = async (req, res, next) => { showPhone: req.user.showPhone, teams, username: req.user.username, - zip: req.user.zip + zip: req.user.zip, }; + console.log(userData); return res.status(200).json(userData); }; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index 81b6821..ca7dd4b 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -1,24 +1,46 @@ -const axios = require('axios'); -const { find, isEmpty } = require('lodash'); -const slugify = require('speakingurl'); +const axios = require("axios"); +const { find, isEmpty } = require("lodash"); +const slugify = require("speakingurl"); -const { isNumber } = require('../../helpers'); -const { Venue } = require('../../models/venue'); +const { isNumber } = require("../../helpers"); +const { Venue } = require("../../models/venue"); -const { validateListVenues } = require('./validations'); -const venueReviewSummary = require('../../helpers/venue-review-summary.js'); +const { validateListVenues } = require("./validations"); +const venueReviewSummary = require("../../helpers/venue-review-summary.js"); + +function getDistanceFromLatLng(lat1, lng1, lat2, lng2) { + const R = 6371; // Earth’s radius in km + + const dLat = (lat2 - lat1) * (Math.PI / 180); + const dLng = (lng2 - lng1) * (Math.PI / 180); + + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(lat1 * (Math.PI / 180)) * + Math.cos(lat2 * (Math.PI / 180)) * + Math.sin(dLng / 2) * + Math.sin(dLng / 2); + + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + const distanceInMeter = R * c * 1000; + return `${distanceInMeter.toFixed(0)} ${ + distanceInMeter > 1000 ? "KiloMeter" : "Meter" + }`; // Distance in kilometers +} module.exports = async (req, res, next) => { const queryParams = req.query; + console.log(queryParams); + const { errors, isValid } = validateListVenues(queryParams); if (!isValid) return res.status(400).json(errors); - let coordinates = queryParams.location.split(','); + let coordinates = queryParams.location.split(","); //Legacy function from two-bar search, geocodes from string address if (queryParams.address && !queryParams.page) { - console.log('in address conditional, ', queryParams); + console.log("in address conditional, ", queryParams); queryParams.name = queryParams.address; const geocodeParams = `?key=${process.env.PLACES_API_KEY}&address=${slugify( queryParams.address @@ -39,21 +61,21 @@ module.exports = async (req, res, next) => { } const statusCode = geocodeResponse.data.status; - if (statusCode === 'ZERO_RESULTS') { - return res.status(404).json({ keywords: 'Address not found' }); - } else if (statusCode === 'OVER_QUERY_LIMIT') { - return next(new Error('Over query limit with Google Places API')); - } else if (statusCode === 'REQUEST_DENIED') { - return next(new Error('Request denied with Google Places API')); - } else if (statusCode === 'INVALID_REQUEST') { - return next(new Error('Invalid request with Google Places API')); - } else if (statusCode === 'UNKNOWN_ERROR') { - return next(new Error('Unknown error with Google Places API')); + if (statusCode === "ZERO_RESULTS") { + return res.status(404).json({ keywords: "Address not found" }); + } else if (statusCode === "OVER_QUERY_LIMIT") { + return next(new Error("Over query limit with Google Places API")); + } else if (statusCode === "REQUEST_DENIED") { + return next(new Error("Request denied with Google Places API")); + } else if (statusCode === "INVALID_REQUEST") { + return next(new Error("Invalid request with Google Places API")); + } else if (statusCode === "UNKNOWN_ERROR") { + return next(new Error("Unknown error with Google Places API")); } coordinates = [ geocodeResponse.data.results[0].geometry.location.lat, - geocodeResponse.data.results[0].geometry.location.lng + geocodeResponse.data.results[0].geometry.location.lng, ]; } //end address geocode @@ -86,9 +108,9 @@ module.exports = async (req, res, next) => { const allowsGuideDog = parseFloat(queryParams.allowsGuideDog) === 1; if (allowsGuideDog) { - dbVenuesFilters['allowsGuideDog.yes'] = { $gte: 1 }; + dbVenuesFilters["allowsGuideDog.yes"] = { $gte: 1 }; } else { - dbVenuesFilters['allowsGuideDog.no'] = { $gte: 1 }; + dbVenuesFilters["allowsGuideDog.no"] = { $gte: 1 }; } } @@ -97,9 +119,9 @@ module.exports = async (req, res, next) => { const hasParking = parseFloat(queryParams.hasParking) === 1; if (hasParking) { - dbVenuesFilters['hasParking.yes'] = { $gte: 1 }; + dbVenuesFilters["hasParking.yes"] = { $gte: 1 }; } else { - dbVenuesFilters['hasParking.no'] = { $gte: 1 }; + dbVenuesFilters["hasParking.no"] = { $gte: 1 }; } } @@ -173,7 +195,7 @@ module.exports = async (req, res, next) => { * UPDATED 05/2020 TO SUPPORT FILTER ONLY SELF SEARCH */ if (!isEmpty(venuesFilters) && isEmpty(queryParams.name)) { - console.log('>> Performing DB search'); + console.log(">> Performing DB search"); /* if (queryParams.name) { //performs literal name match against AXS Venue name @@ -184,11 +206,11 @@ module.exports = async (req, res, next) => { dbVenuesFilters.location = { $near: { $geometry: { - type: 'Point', - coordinates: [coordinates[1], coordinates[0]] + type: "Point", + coordinates: [coordinates[1], coordinates[0]], }, - $maxDistance: 50000 - } + $maxDistance: 50000, + }, }; if (queryParams.type) { @@ -203,9 +225,9 @@ module.exports = async (req, res, next) => { } const pageLimit = - 'entranceScore' in venuesFilters || - 'interiorScore' in venuesFilters || - 'restroomScore' in venuesFilters + "entranceScore" in venuesFilters || + "interiorScore" in venuesFilters || + "restroomScore" in venuesFilters ? 80 : 20; @@ -214,7 +236,7 @@ module.exports = async (req, res, next) => { } else { return res .status(400) - .json({ page: 'Should be equal to or greater than 1' }); + .json({ page: "Should be equal to or greater than 1" }); } let total; @@ -227,7 +249,7 @@ module.exports = async (req, res, next) => { ) .skip(page * pageLimit) .limit(pageLimit), - Venue.find(dbVenuesFilters).count() + (await Venue.find(dbVenuesFilters)).length, /*TODO: count is deprecated in favor of countDocuments, but that does not support $near would need to move to GeoWithin but that does not return sorted results */ @@ -246,28 +268,28 @@ module.exports = async (req, res, next) => { Object.assign({}, venue.toObject(), { id: venue._id, _id: undefined, - location: venue.coordinates + location: venue.coordinates, }) ); //+ADDED //Perform ratings logic on all returned venues - console.log('Raw venues count: ' + venues.length); + console.log("Raw venues count: " + venues.length); venues = venues.filter((venue) => { //console.log('In scoring assignment'); let scoring; //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); + scoring = venueReviewSummary.calculateRatingLevel("entrance", venue); venue.entranceScore = scoring.ratingLevel; venue.entranceGlyphs = scoring.ratingGlyphs; //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); + scoring = venueReviewSummary.calculateRatingLevel("interior", venue); venue.interiorScore = scoring.ratingLevel; venue.interiorGlyphs = scoring.ratingGlyphs; //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); + scoring = venueReviewSummary.calculateRatingLevel("restroom", venue); venue.restroomScore = scoring.ratingLevel; venue.restroomGlyphs = scoring.ratingGlyphs; @@ -278,7 +300,7 @@ module.exports = async (req, res, next) => { ); let passesValidation = true; - if ('entranceScore' in venuesFilters) { + if ("entranceScore" in venuesFilters) { if ( !venue.entranceScore || venue.entranceScore < venuesFilters.entranceScore @@ -287,7 +309,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'interiorScore' in venuesFilters) { + if (passesValidation && "interiorScore" in venuesFilters) { if ( !venue.interiorScore || venue.interiorScore < venuesFilters.interiorScore @@ -296,7 +318,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'restroomScore' in venuesFilters) { + if (passesValidation && "restroomScore" in venuesFilters) { if ( !venue.restroomScore || venue.restroomScore < venuesFilters.restroomScore @@ -316,38 +338,35 @@ module.exports = async (req, res, next) => { page += 1; if (page > lastPage || page > 3) { return res.status(400).json({ - page: `Should be equal to or less than ${lastPage > 3 ? 3 : lastPage}` + page: `Should be equal to or less than ${lastPage > 3 ? 3 : lastPage}`, }); } } dataResponse = { nextPage, - results: venues + results: venues, }; /* * End legacy filter */ } else { - console.log('>> Performing Google search'); + console.log(">> Performing Google search"); /* * Perform Google search when there text entered or no filters selected */ let nearbyParams = `?key=${process.env.PLACES_API_KEY}`; - let searchType = queryParams.name ? 'textsearch' : 'nearbysearch'; + let searchType = queryParams.name ? "textsearch" : "nearbysearch"; if (!queryParams.page) { nearbyParams = `${nearbyParams}&location=${coordinates[0]},${ coordinates[1] - //}&rankby=distance`; }`; if (queryParams.name) { - //nearbyParams = `${nearbyParams}&keyword=${queryParams.name}`; nearbyParams = `${nearbyParams}&query=${queryParams.name}&radius=5000`; } else { - //empty search, such as on load nearbyParams = `${nearbyParams}&rankby=distance`; } @@ -359,7 +378,6 @@ module.exports = async (req, res, next) => { } else { nearbyParams = `${nearbyParams}&pagetoken=${queryParams.page}`; } - if (queryParams.rankby) { nearbyParams = `${nearbyParams}&rankby=${queryParams.rankby}`; } @@ -376,7 +394,7 @@ module.exports = async (req, res, next) => { let placesResponse; try { console.log( - 'performing google search: ' + + "performing google search: " + `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` ); placesResponse = await axios.get( @@ -392,21 +410,21 @@ module.exports = async (req, res, next) => { } const statusCode = placesResponse.data.status; - if (statusCode === 'OVER_QUERY_LIMIT') { - return next(new Error('Over query limit with Google Places API')); - } else if (statusCode === 'REQUEST_DENIED') { - return next(new Error('Request denied with Google Places API')); - } else if (statusCode === 'INVALID_REQUEST') { - return next(new Error('Invalid request with Google Places API')); - } else if (statusCode === 'UNKNOWN_ERROR') { - return next(new Error('Unknown error with Google Places API')); + if (statusCode === "OVER_QUERY_LIMIT") { + return next(new Error("Over query limit with Google Places API")); + } else if (statusCode === "REQUEST_DENIED") { + return next(new Error("Request denied with Google Places API")); + } else if (statusCode === "INVALID_REQUEST") { + return next(new Error("Invalid request with Google Places API")); + } else if (statusCode === "UNKNOWN_ERROR") { + return next(new Error("Unknown error with Google Places API")); } //do we need to check for 0? if (placesResponse.data.results.length == 1) { - if (placesResponse.data.results[0].types[0] == 'locality') { + if (placesResponse.data.results[0].types[0] == "locality") { console.log( - 'Found a city only: ', + "Found a city only: ", placesResponse.data.results[0].geometry.location ); //TODO: redo search with new coordinates and no query/name or change/add "places in " to the first part of the string @@ -417,24 +435,36 @@ module.exports = async (req, res, next) => { let places = []; const placesIds = []; placesResponse.data.results.forEach((place) => { - let photo = ''; + let photo = ""; if (place.photos) { photo = `https://maps.googleapis.com/maps/api/place/photo?key=${ process.env.PLACES_API_KEY }&maxwidth=300&photoreference=${place.photos[0].photo_reference}`; } + console.log( + place.geometry.location.lat, + place.geometry.location.lng, + coordinates[0], + coordinates[1] + ); places.push({ //address: place.vicinity, address: place.formatted_address, location: { lat: place.geometry.location.lat, - lng: place.geometry.location.lng + lng: place.geometry.location.lng, }, + distance: getDistanceFromLatLng( + place.geometry.location.lat, + place.geometry.location.lng, + coordinates[0], + coordinates[1] + ), name: place.name, photo, placeId: place.place_id, - types: place.types + types: place.types, }); placesIds.push(place.place_id); }); @@ -455,17 +485,17 @@ module.exports = async (req, res, next) => { //console.log('In scoring assignment'); let scoring; //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); + scoring = venueReviewSummary.calculateRatingLevel("entrance", venue); venue.entranceScore = scoring.ratingLevel; venue.entranceGlyphs = scoring.ratingGlyphs; //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); + scoring = venueReviewSummary.calculateRatingLevel("interior", venue); venue.interiorScore = scoring.ratingLevel; venue.interiorGlyphs = scoring.ratingGlyphs; //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); + scoring = venueReviewSummary.calculateRatingLevel("restroom", venue); venue.restroomScore = scoring.ratingLevel; venue.restroomGlyphs = scoring.ratingGlyphs; @@ -479,13 +509,13 @@ module.exports = async (req, res, next) => { //Filter out, remove, Google Places that are not AXS Venues // Can't use hasOwnProperty() on mongoose model objects // if (!isEmpty(venuesFilters)) { - console.log('>> Performing secondary DB filtering'); + console.log(">> Performing secondary DB filtering"); places = places.filter((place) => { const venue = find(venues, (venue) => venue.placeId === place.placeId); if (venue) { //console.log('In verification of filters'); let passesValidation = true; - if (passesValidation && 'allowsGuideDog' in venuesFilters) { + if (passesValidation && "allowsGuideDog" in venuesFilters) { if ( !venue.allowsGuideDog || venue.allowsGuideDog.yes < venue.allowsGuideDog.no || @@ -495,7 +525,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'hasParking' in venuesFilters) { + if (passesValidation && "hasParking" in venuesFilters) { if ( !venue.hasParking || venue.hasParking.yes < venue.hasParking.no || @@ -505,7 +535,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'entranceScore' in venuesFilters) { + if (passesValidation && "entranceScore" in venuesFilters) { if ( !venue.entranceScore || venue.entranceScore < venuesFilters.entranceScore @@ -514,7 +544,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'interiorScore' in venuesFilters) { + if (passesValidation && "interiorScore" in venuesFilters) { if ( !venue.interiorScore || venue.interiorScore < venuesFilters.interiorScore @@ -523,7 +553,7 @@ module.exports = async (req, res, next) => { } } - if (passesValidation && 'restroomScore' in venuesFilters) { + if (passesValidation && "restroomScore" in venuesFilters) { if ( !venue.restroomScore || venue.restroomScore < venuesFilters.restroomScore @@ -574,7 +604,7 @@ module.exports = async (req, res, next) => { hasWellLit: venue.hasWellLit, isQuiet: venue.isQuiet, isSpacious: venue.isSpacious, - steps: venue.steps + steps: venue.steps, }); } @@ -593,11 +623,11 @@ module.exports = async (req, res, next) => { hasSupportAroundToilet: { yes: 0, no: 0 }, hasLoweredSinks: { yes: 0, no: 0 }, interiorScore: 0, - interiorGlyphs: 'interior', + interiorGlyphs: "interior", restroomScore: 0, - restroomGlyphs: 'restroom', + restroomGlyphs: "restroom", entranceScore: 0, - entranceGlyphs: 'entrylg', + entranceGlyphs: "entrylg", mapMarkerScore: 0, //original fields @@ -615,14 +645,14 @@ module.exports = async (req, res, next) => { zero: 0, one: 0, two: 0, - moreThanTwo: 0 - } + moreThanTwo: 0, + }, }); }); dataResponse = { nextPage: placesResponse.data.next_page_token, - results: places + results: places, }; } //ends legacy filter logic, false conditional From 22e2a73e688b5472f890f28c5af71359fc954ef5 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 21 Feb 2025 19:09:13 +0500 Subject: [PATCH 03/67] change app listen flow --- src/index.js | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/index.js b/src/index.js index efdd209..7ebbd16 100644 --- a/src/index.js +++ b/src/index.js @@ -62,28 +62,24 @@ function connectedToDB() { raven.captureException(err); }); - app.listen(port, () => { - console.log(`Listening on http://${ip.address()}:${port}`); - }); - // App Initialization - // if (process.env.NODE_ENV === "production") { - // app.listen(port, () => { - // console.log(`Listening on http://${ip.address()}:${port}`); - // }); - // } else { - // https - // .createServer( - // { - // key: fs.readFileSync("./certificates/server.key"), - // cert: fs.readFileSync("./certificates/server.crt"), - // }, - // app - // ) - // .listen(port, () => - // console.log(`Listening on https://${ip.address()}:${port}`) - // ); - // } + if (process.env.NODE_ENV === "production") { + app.listen(port, () => { + console.log(`Listening on http://${ip.address()}:${port}`); + }); + } else { + https + .createServer( + { + key: fs.readFileSync("./certificates/server.key"), + cert: fs.readFileSync("./certificates/server.crt"), + }, + app + ) + .listen(port, () => + console.log(`Listening on https://${ip.address()}:${port}`) + ); + } } connectToDB(connectedToDB); From 2797761a45d4731a9e9d164be3fc8756d84d0e7a Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 25 Feb 2025 18:52:50 +0500 Subject: [PATCH 04/67] filter and location issue resolved --- src/index.js | 38 +++++++++--------- src/routes/auth/forgotten-password.js | 26 ++++++------- src/routes/users/edit-user.js | 41 ++++++++++---------- src/routes/venues/list-venues.js | 55 ++++++++++++++++++--------- 4 files changed, 92 insertions(+), 68 deletions(-) diff --git a/src/index.js b/src/index.js index 7ebbd16..98bb8e6 100644 --- a/src/index.js +++ b/src/index.js @@ -61,25 +61,27 @@ function connectedToDB() { console.error(err); raven.captureException(err); }); - + app.listen(port, () => { + console.log(`Listening on http://${ip.address()}:${port}`); + }); // App Initialization - if (process.env.NODE_ENV === "production") { - app.listen(port, () => { - console.log(`Listening on http://${ip.address()}:${port}`); - }); - } else { - https - .createServer( - { - key: fs.readFileSync("./certificates/server.key"), - cert: fs.readFileSync("./certificates/server.crt"), - }, - app - ) - .listen(port, () => - console.log(`Listening on https://${ip.address()}:${port}`) - ); - } + // if (process.env.NODE_ENV === "production") { + // app.listen(port, () => { + // console.log(`Listening on http://${ip.address()}:${port}`); + // }); + // } else { + // https + // .createServer( + // { + // key: fs.readFileSync("./certificates/server.key"), + // cert: fs.readFileSync("./certificates/server.crt"), + // }, + // app + // ) + // .listen(port, () => + // console.log(`Listening on https://${ip.address()}:${port}`) + // ); + // } } connectToDB(connectedToDB); diff --git a/src/routes/auth/forgotten-password.js b/src/routes/auth/forgotten-password.js index e1e18f7..ec73405 100644 --- a/src/routes/auth/forgotten-password.js +++ b/src/routes/auth/forgotten-password.js @@ -1,12 +1,12 @@ -const crypto = require('crypto'); +const crypto = require("crypto"); -const moment = require('moment'); +const moment = require("moment"); -const { PasswordTicket } = require('../../models/password-ticket'); -const { sendEmail } = require('../../helpers'); -const { User } = require('../../models/user'); +const { PasswordTicket } = require("../../models/password-ticket"); +const { sendEmail } = require("../../helpers"); +const { User } = require("../../models/user"); -const { validateForgottenPassword } = require('./validations'); +const { validateForgottenPassword } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateForgottenPassword(req.body); @@ -27,11 +27,11 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); } try { - await PasswordTicket.remove({ email }); + await PasswordTicket.deleteOne({ email }); } catch (err) { console.log( `Password ticket with email ${email} failed to be removed at forgotten-password.` @@ -40,10 +40,10 @@ module.exports = async (req, res, next) => { } const today = moment.utc(); - const expiresAt = today.add(1, 'days').toDate(); + const expiresAt = today.add(1, "days").toDate(); const key = `${crypto .randomBytes(31) - .toString('hex')}${new Date().getTime().toString()}`; + .toString("hex")}${new Date().getTime().toString()}`; let passwordTicket; try { @@ -69,7 +69,7 @@ module.exports = async (req, res, next) => {

Stay awesome.

`; const receiversEmails = [passwordTicket.email]; - const subject = 'Reset Password'; + const subject = "Reset Password"; const textContent = ` Hi from AXS Map! To reset your password use the link below: @@ -81,8 +81,8 @@ module.exports = async (req, res, next) => { receiversEmails, subject, htmlContent, - textContent + textContent, }); - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/users/edit-user.js b/src/routes/users/edit-user.js index f0be2a1..40da38a 100644 --- a/src/routes/users/edit-user.js +++ b/src/routes/users/edit-user.js @@ -1,10 +1,10 @@ -const moment = require('moment'); +const moment = require("moment"); -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { User } = require('../../models/user'); +const { cleanSpaces } = require("../../helpers"); +const { Photo } = require("../../models/photo"); +const { User } = require("../../models/user"); -const { validateEditUser } = require('./validations'); +const { validateEditUser } = require("./validations"); module.exports = async (req, res, next) => { const userId = req.params.userId; @@ -13,8 +13,8 @@ module.exports = async (req, res, next) => { try { user = await User.findOne({ _id: userId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "User not found" }); } console.log(`User with Id ${userId} failed to be found at edit-user.`); @@ -22,11 +22,11 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(404).json({ general: 'User not found' }); + return res.status(404).json({ general: "User not found" }); } if (user.id !== req.user.id && !req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } const data = req.body; @@ -36,7 +36,7 @@ module.exports = async (req, res, next) => { if ( data.avatar && - !data.avatar.includes('default') && + !data.avatar.includes("default") && data.avatar !== user.avatar ) { let avatar; @@ -48,11 +48,11 @@ module.exports = async (req, res, next) => { } if (!avatar) { - return res.status(404).json({ avatar: 'Not found' }); + return res.status(404).json({ avatar: "Not found" }); } user.avatar = data.avatar; - } else if (data.avatar === '') { + } else if (data.avatar === "") { user.avatar = `https://s3.amazonaws.com/${ process.env.AWS_S3_BUCKET }/users/avatars/default.png`; @@ -69,7 +69,7 @@ module.exports = async (req, res, next) => { user.gender = data.gender || user.gender; user.isSubscribed = - typeof data.isSubscribed !== 'undefined' + typeof data.isSubscribed !== "undefined" ? data.isSubscribed : user.isSubscribed; @@ -80,22 +80,22 @@ module.exports = async (req, res, next) => { user.phone = data.phone || user.phone; user.showDisabilities = - typeof data.showDisabilities !== 'undefined' + typeof data.showDisabilities !== "undefined" ? data.showDisabilities : user.showDisabilities; user.showEmail = - typeof data.showEmail !== 'undefined' ? data.showEmail : user.showEmail; + typeof data.showEmail !== "undefined" ? data.showEmail : user.showEmail; user.showPhone = - typeof data.showPhone !== 'undefined' ? data.showPhone : user.showPhone; + typeof data.showPhone !== "undefined" ? data.showPhone : user.showPhone; if (data.username && data.username !== user.username) { let repeatedUser; try { repeatedUser = await User.findOne({ username: data.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -105,7 +105,7 @@ module.exports = async (req, res, next) => { } if (repeatedUser) { - return res.status(400).json({ username: 'Is already taken' }); + return res.status(400).json({ username: "Is already taken" }); } user.username = data.username; @@ -118,7 +118,7 @@ module.exports = async (req, res, next) => { try { await user.save(); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -146,6 +146,7 @@ module.exports = async (req, res, next) => { description: user.description, disabilities: user.disabilities, firstName: user.firstName, + email: user?.email, gender: user.gender, isSubscribed: user.isSubscribed, lastName: user.lastName, @@ -154,7 +155,7 @@ module.exports = async (req, res, next) => { showEmail: user.showEmail, showPhone: user.showPhone, username: user.username, - zip: user.zip + zip: user.zip, }; return res.status(200).json(dataResponse); }; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index ca7dd4b..457693e 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -8,7 +8,22 @@ const { Venue } = require("../../models/venue"); const { validateListVenues } = require("./validations"); const venueReviewSummary = require("../../helpers/venue-review-summary.js"); +const milesTranslations = { + en: "Miles", // English + fr: "Milles", // French + es: "Millas", // Spanish + ja: "マイル", // Japanese +}; + +const feetTranslations = { + en: "Feet", // English + fr: "Pieds", // French + es: "Pies", // Spanish + ja: "フィート", // Japanese +}; + function getDistanceFromLatLng(lat1, lng1, lat2, lng2) { + console.log(lat1, lng1, lat2, lng2); const R = 6371; // Earth’s radius in km const dLat = (lat2 - lat1) * (Math.PI / 180); @@ -22,10 +37,17 @@ function getDistanceFromLatLng(lat1, lng1, lat2, lng2) { Math.sin(dLng / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - const distanceInMeter = R * c * 1000; - return `${distanceInMeter.toFixed(0)} ${ - distanceInMeter > 1000 ? "KiloMeter" : "Meter" - }`; // Distance in kilometers + return R * c * 1000; +} + +function covertDistanceToFeet(distanceInMeter, language = "en") { + const distanceInFeet = distanceInMeter * 3.28084; + const distance = `${(distanceInFeet > 5280 ? distanceInFeet / 5280 : distanceInFeet).toFixed(distanceInFeet > 5280 ? 2 : 0)} ${ + distanceInFeet > 5280 + ? (milesTranslations[language] ?? "Miles") + : (feetTranslations[language] ?? "Feet") + }`; + return distance; } module.exports = async (req, res, next) => { @@ -365,7 +387,7 @@ module.exports = async (req, res, next) => { }`; if (queryParams.name) { - nearbyParams = `${nearbyParams}&query=${queryParams.name}&radius=5000`; + nearbyParams = `${nearbyParams}&query=${queryParams.name}&rankby=distance`; } else { nearbyParams = `${nearbyParams}&rankby=distance`; } @@ -384,6 +406,9 @@ module.exports = async (req, res, next) => { if (queryParams.opennow) { nearbyParams = `${nearbyParams}&opennow=${queryParams.opennow}`; } + if (queryParams.language) { + nearbyParams = `${nearbyParams}&language=${queryParams.language}`; + } if (queryParams.minprice) { nearbyParams = `${nearbyParams}&minprice=${queryParams.minprice}`; } @@ -441,12 +466,6 @@ module.exports = async (req, res, next) => { process.env.PLACES_API_KEY }&maxwidth=300&photoreference=${place.photos[0].photo_reference}`; } - console.log( - place.geometry.location.lat, - place.geometry.location.lng, - coordinates[0], - coordinates[1] - ); places.push({ //address: place.vicinity, @@ -455,11 +474,14 @@ module.exports = async (req, res, next) => { lat: place.geometry.location.lat, lng: place.geometry.location.lng, }, - distance: getDistanceFromLatLng( - place.geometry.location.lat, - place.geometry.location.lng, - coordinates[0], - coordinates[1] + distance: covertDistanceToFeet( + getDistanceFromLatLng( + place.geometry.location.lat, + place.geometry.location.lng, + coordinates[0], + coordinates[1] + ), + queryParams.language ), name: place.name, photo, @@ -509,7 +531,6 @@ module.exports = async (req, res, next) => { //Filter out, remove, Google Places that are not AXS Venues // Can't use hasOwnProperty() on mongoose model objects // if (!isEmpty(venuesFilters)) { - console.log(">> Performing secondary DB filtering"); places = places.filter((place) => { const venue = find(venues, (venue) => venue.placeId === place.placeId); if (venue) { From d26afcef69b45a2814dd3b86f67f79ffc261755b Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 27 Feb 2025 19:37:44 +0500 Subject: [PATCH 05/67] maphathon flow updated --- src/models/user.js | 159 +++++++++++++++++---------- src/routes/auth/activate-account.js | 40 +++---- src/routes/auth/facebook-sign-in.js | 66 +++++------ src/routes/auth/google-sign-in.js | 64 +++++------ src/routes/auth/sign-in.js | 2 +- src/routes/events/index.js | 34 +++--- src/routes/events/list-events.js | 10 +- src/routes/events/list-old-events.js | 79 +++++++++++++ src/routes/users/create-user.js | 99 +++++++++-------- src/routes/users/edit-user.js | 6 + src/routes/users/get-profile.js | 13 ++- src/routes/users/get-user.js | 87 ++++++++------- 12 files changed, 406 insertions(+), 253 deletions(-) create mode 100644 src/routes/events/list-old-events.js diff --git a/src/models/user.js b/src/models/user.js index 949b077..f501210 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -1,5 +1,5 @@ -const bcrypt = require('bcrypt-nodejs'); -const mongoose = require('mongoose'); +const bcrypt = require("bcrypt-nodejs"); +const mongoose = require("mongoose"); const userSchema = new mongoose.Schema( { @@ -8,152 +8,195 @@ const userSchema = new mongoose.Schema( default: `https://s3.amazonaws.com/${ process.env.AWS_S3_BUCKET }/users/avatars/default.png`, - maxlength: [2000, 'Should be less than 2001 characters'], - required: [true, 'Is required'] + maxlength: [2000, "Should be less than 2001 characters"], + required: [true, "Is required"], }, description: { type: String, - maxlength: [2000, 'Should be less than 2001 characters'] + maxlength: [2000, "Should be less than 2001 characters"], }, disabilities: { type: [String], - default: ['none'], + default: ["none"], enum: { values: [ - 'brain', - 'cognitive', - 'hearing', - 'invisible', - 'none', - 'other', - 'physical', - 'private', - 'psychological', - 'spinal-cord', - 'vision' + "brain", + "cognitive", + "hearing", + "invisible", + "none", + "other", + "physical", + "private", + "psychological", + "spinal-cord", + "vision", ], - general: 'Invalid type of disability' + general: "Invalid type of disability", }, - required: [true, 'Is required'] + required: [true, "Is required"], }, email: { type: String, - maxlength: [254, 'Should be less than 255 characters'] + maxlength: [254, "Should be less than 255 characters"], }, events: [ { type: mongoose.Schema.Types.ObjectId, - ref: 'Event' - } + ref: "Event", + }, ], facebookId: String, firstName: { type: String, - maxlength: [24, 'Should be less than 25 characters'], - required: [true, 'Is required'] + maxlength: [24, "Should be less than 25 characters"], + required: [true, "Is required"], }, gender: { type: String, - default: 'private', + default: "not-to-say", enum: { - values: ['female', 'male', 'other', 'private', 'transgender'], - general: 'Invalid type of gender' + values: [ + "female", + "male", + "other", + "private", + "transgender", + "non-binary", + "gender-fluid", + "agender", + "not-to-say", + ], + general: "Invalid type of gender", }, - required: [true, 'Is required'] + required: [true, "Is required"], }, googleId: String, hashedPassword: { type: String, - maxlength: [256, 'Should be less than 255 characters'] + maxlength: [256, "Should be less than 255 characters"], }, isAdmin: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, isArchived: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, isBlocked: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, isSubscribed: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, lastName: { type: String, - maxlength: [36, 'Should be less than 37 characters'], - required: [true, 'Is required'] + maxlength: [36, "Should be less than 37 characters"], + required: [true, "Is required"], }, language: { type: String, - default: 'en', + default: "en", enum: { - values: ['en', 'es'], - general: 'Invalid type of language' + values: ["en", "es"], + general: "Invalid type of language", }, - required: [true, 'Is required'] + required: [true, "Is required"], }, phone: { type: String, - maxlength: [50, 'Should be less than 51 characters'] + maxlength: [50, "Should be less than 51 characters"], }, reviewFieldsAmount: { type: Number, default: 0, - required: [true, 'Is required'] + required: [true, "Is required"], }, reviewsAmount: { type: Number, default: 0, - required: [true, 'Is required'] + required: [true, "Is required"], }, showDisabilities: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, showEmail: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, showPhone: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, teams: [ { type: mongoose.Schema.Types.ObjectId, - ref: 'Team' - } + ref: "Team", + }, ], username: { type: String, - maxlength: [67, 'Should be less than 68 characters'] + maxlength: [67, "Should be less than 68 characters"], }, zip: { type: String, - maxlength: [32, 'Should be less than 33 characters'] - } + maxlength: [32, "Should be less than 33 characters"], + }, + birthday: { + type: Date, + default: null, + required: false, + }, + race: { + type: String, + default: "not-to-disclose", + enum: { + values: [ + "black/african american", + "caucasian", + "indigenous/first nation/native american", + "latino/hispanic", + "middle eastern/north african", + "native hawaiian/pacific islander", + "biracial/multiracial", + "non-naucasian", + "not-to-disclose", + ], + general: "Invalid type of Race", + }, + required: false, + }, + disability: { + type: String, + default: "not-to-say", + enum: { + values: ["yes", "No", "not-to-say"], + general: "Invalid type of Disability", + }, + required: false, + }, }, { timestamps: true } ); userSchema.index( { - email: 'text', - firstName: 'text', - lastName: 'text', - username: 'text', - reviewsAmount: 1 + email: "text", + firstName: "text", + lastName: "text", + username: "text", + reviewsAmount: 1, }, { weights: { email: 5, username: 5 } } ); @@ -184,10 +227,10 @@ function comparePassword(password) { return bcrypt.compareSync(password, this.hashedPassword); } -userSchema.virtual('password').set(hashPassword); +userSchema.virtual("password").set(hashPassword); userSchema.methods.comparePassword = comparePassword; module.exports = { - User: mongoose.model('User', userSchema), - userSchema + User: mongoose.model("User", userSchema), + userSchema, }; diff --git a/src/routes/auth/activate-account.js b/src/routes/auth/activate-account.js index e5a0655..d6885b3 100644 --- a/src/routes/auth/activate-account.js +++ b/src/routes/auth/activate-account.js @@ -1,12 +1,12 @@ -const crypto = require('crypto'); +const crypto = require("crypto"); -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); +const moment = require("moment"); +const randomstring = require("randomstring"); +const slugify = require("speakingurl"); -const { ActivationTicket } = require('../../models/activation-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { ActivationTicket } = require("../../models/activation-ticket"); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { const key = req.params.key; @@ -15,8 +15,8 @@ module.exports = async (req, res, next) => { try { activationTicket = await ActivationTicket.findOne({ key }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Activation ticket not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Activation ticket not found" }); } console.log( @@ -26,7 +26,7 @@ module.exports = async (req, res, next) => { } if (!activationTicket) { - return res.status(404).json({ general: 'Activation ticket not found' }); + return res.status(404).json({ general: "Activation ticket not found" }); } let expiresAt = moment(activationTicket.expiresAt).utc(); @@ -43,28 +43,28 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(400).json({ general: 'Activation ticket expired' }); + return res.status(400).json({ general: "Activation ticket expired" }); } const userData = Object.assign({}, activationTicket.userData, { - email: activationTicket.email + email: activationTicket.email, }); let repeatedUsers; try { repeatedUsers = await User.find({ $or: [{ email: userData.email }, { username: userData.username }], - isArchived: false + isArchived: false, }); } catch (err) { - console.log('Users failed to be found at activate-account.'); + console.log("Users failed to be found at activate-account."); return next(err); } if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === userData.email) { - return res.status(400).json({ email: 'Is already taken' }); + return res.status(400).json({ email: "Is already taken" }); } let repeatedUser; @@ -73,13 +73,13 @@ module.exports = async (req, res, next) => { userData.lastName )}-${randomstring.generate({ length: 5, - capitalization: 'lowercase' + capitalization: "lowercase", })}`; try { repeatedUser = await User.findOne({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -106,11 +106,11 @@ module.exports = async (req, res, next) => { } const today = moment.utc(); - expiresAt = today.add(14, 'days').toDate(); + expiresAt = today.add(30, "days").toDate(); const refreshTokenData = { expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id + key: `${user.id}${crypto.randomBytes(28).toString("hex")}`, + userId: user.id, }; try { diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index d5477ac..3a06a1a 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -1,15 +1,15 @@ -const crypto = require('crypto'); +const crypto = require("crypto"); -const axios = require('axios'); -const jwt = require('jsonwebtoken'); -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); +const axios = require("axios"); +const jwt = require("jsonwebtoken"); +const moment = require("moment"); +const randomstring = require("randomstring"); +const slugify = require("speakingurl"); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); -const { validateFacebookSignIn } = require('./validations'); +const { validateFacebookSignIn } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateFacebookSignIn(req.body); @@ -19,47 +19,47 @@ module.exports = async (req, res, next) => { const code = req.body.code; - const getTokenUrl = 'https://graph.facebook.com/v2.10/oauth/access_token'; + const getTokenUrl = "https://graph.facebook.com/v2.10/oauth/access_token"; const getTokenParams = { code, client_id: process.env.FACEBOOK_CLIENT_ID, client_secret: process.env.FACEBOOK_CLIENT_SECRET, - redirect_uri: `${process.env.APP_URL}/auth/facebook` + redirect_uri: `${process.env.APP_URL}/auth/facebook`, }; let getTokenResponse; try { getTokenResponse = await axios.get(getTokenUrl, { params: getTokenParams }); } catch (err) { console.err(err); - return res.status(400).json({ general: 'Invalid code' }); + return res.status(400).json({ general: "Invalid code" }); } const facebookToken = getTokenResponse.data.access_token; const getProfileUrl = - 'https://graph.facebook.com/v2.10/me?fields=id,email,first_name,last_name,locale'; + "https://graph.facebook.com/v2.10/me?fields=id,email,first_name,last_name,locale"; const getProfileOptions = { params: { - access_token: facebookToken - } + access_token: facebookToken, + }, }; let getProfileResponse; try { getProfileResponse = await axios.get(getProfileUrl, getProfileOptions); } catch (err) { - console.log('Profile data failed to be found at facebook-sign-in.'); + console.log("Profile data failed to be found at facebook-sign-in."); return next(err); } const email = getProfileResponse.data.email ? getProfileResponse.data.email - : ''; + : ""; const facebookId = getProfileResponse.data.id; let user; try { user = await User.findOne({ $or: [{ email }, { facebookId }], - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -74,10 +74,10 @@ module.exports = async (req, res, next) => { if (!user) { console.log(getProfileResponse.data); const userData = { - email: getProfileResponse.data.email ? getProfileResponse.data.email : '', + email: getProfileResponse.data.email ? getProfileResponse.data.email : "", facebookId: getProfileResponse.data.id, firstName: getProfileResponse.data.first_name, - lastName: getProfileResponse.data.last_name + lastName: getProfileResponse.data.last_name, }; userData.username = `${slugify(userData.firstName)}-${slugify( userData.lastName @@ -87,10 +87,10 @@ module.exports = async (req, res, next) => { try { repeatedUsers = await User.find({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { - console.log('Users failed to be found at facebook-sign-in.'); + console.log("Users failed to be found at facebook-sign-in."); return next(err); } @@ -101,13 +101,13 @@ module.exports = async (req, res, next) => { userData.lastName )}-${randomstring.generate({ length: 5, - capitalization: 'lowercase' + capitalization: "lowercase", })}`; try { repeatedUser = await User.findOne({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -127,14 +127,14 @@ module.exports = async (req, res, next) => { params: { access_token: accessToken, redirect: false, - type: 'large' - } + type: "large", + }, }; let getPictureResponse; try { getPictureResponse = await axios.get(getPictureUrl, getPictureOptions); } catch (err) { - console.log('User picture failed to be found at facebook-sign-in.'); + console.log("User picture failed to be found at facebook-sign-in."); return next(err); } @@ -155,11 +155,11 @@ module.exports = async (req, res, next) => { } const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); + const expiresAt = today.add(30, "days").toDate(); const refreshTokenData = { expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id + key: `${user.id}${crypto.randomBytes(28).toString("hex")}`, + userId: user.id, }; try { @@ -175,8 +175,8 @@ module.exports = async (req, res, next) => { } else { const userId = user.id; const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; try { refreshToken = await RefreshToken.findOneAndUpdate( @@ -193,7 +193,7 @@ module.exports = async (req, res, next) => { } const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600 + expiresIn: 3600, }); refreshToken = refreshToken.key; diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 14c2a84..63f7106 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -1,17 +1,17 @@ -const crypto = require('crypto'); -const querystring = require('querystring'); +const crypto = require("crypto"); +const querystring = require("querystring"); -const axios = require('axios'); -const GoogleAuth = require('google-auth-library'); -const jwt = require('jsonwebtoken'); -const moment = require('moment'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); +const axios = require("axios"); +const GoogleAuth = require("google-auth-library"); +const jwt = require("jsonwebtoken"); +const moment = require("moment"); +const randomstring = require("randomstring"); +const slugify = require("speakingurl"); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); -const { validateGoogleSignIn } = require('./validations'); +const { validateGoogleSignIn } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateGoogleSignIn(req.body); @@ -21,13 +21,13 @@ module.exports = async (req, res, next) => { const code = req.body.code; - const getTokenUrl = 'https://www.googleapis.com/oauth2/v4/token'; + const getTokenUrl = "https://www.googleapis.com/oauth2/v4/token"; const getTokenParams = { code, client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, redirect_uri: `${process.env.APP_URL}/auth/google`, - grant_type: 'authorization_code' + grant_type: "authorization_code", }; let getTokenResponse; try { @@ -37,18 +37,18 @@ module.exports = async (req, res, next) => { ); } catch (err) { console.error(err); - return res.status(400).json({ general: 'Invalid code' }); + return res.status(400).json({ general: "Invalid code" }); } const auth = new GoogleAuth(); - const client = new auth.OAuth2(process.env.GOOGLE_CLIENT_ID, '', ''); + const client = new auth.OAuth2(process.env.GOOGLE_CLIENT_ID, "", ""); const idToken = getTokenResponse.data.id_token; client.verifyIdToken( idToken, process.env.GOOGLE_CLIENT_ID, async (err, login) => { if (err) { - return res.status(400).json({ general: 'Invalid token id' }); + return res.status(400).json({ general: "Invalid token id" }); } const payload = login.getPayload(); @@ -59,7 +59,7 @@ module.exports = async (req, res, next) => { try { user = await User.findOne({ $or: [{ email }, { googleId }], - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -75,13 +75,13 @@ module.exports = async (req, res, next) => { email: payload.email, googleId: payload.sub, firstName: payload.given_name, - lastName: payload.family_name + lastName: payload.family_name, }; - if (payload.locale === 'en') { - userData.language = 'en'; - } else if (payload.locale === 'es') { - userData.language = 'es'; + if (payload.locale === "en") { + userData.language = "en"; + } else if (payload.locale === "es") { + userData.language = "es"; } if (payload.picture) { @@ -96,10 +96,10 @@ module.exports = async (req, res, next) => { try { repeatedUsers = await User.find({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { - console.log('Users failed to be found at google-sign-in.'); + console.log("Users failed to be found at google-sign-in."); return next(err); } @@ -110,13 +110,13 @@ module.exports = async (req, res, next) => { userData.lastName )}-${randomstring.generate({ length: 5, - capitalization: 'lowercase' + capitalization: "lowercase", })}`; try { repeatedUser = await User.findOne({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -141,11 +141,11 @@ module.exports = async (req, res, next) => { } const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); + const expiresAt = today.add(30, "days").toDate(); const refreshTokenData = { expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString('hex')}`, - userId: user.id + key: `${user.id}${crypto.randomBytes(28).toString("hex")}`, + userId: user.id, }; try { @@ -161,8 +161,8 @@ module.exports = async (req, res, next) => { } else { const userId = user.id; const today = moment.utc(); - const expiresAt = today.add(14, 'days').toDate(); - const key = `${userId}${crypto.randomBytes(28).toString('hex')}`; + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; try { refreshToken = await RefreshToken.findOneAndUpdate( @@ -179,7 +179,7 @@ module.exports = async (req, res, next) => { } const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600 + expiresIn: 3600, }); refreshToken = refreshToken.key; diff --git a/src/routes/auth/sign-in.js b/src/routes/auth/sign-in.js index 3582e2f..15c4330 100644 --- a/src/routes/auth/sign-in.js +++ b/src/routes/auth/sign-in.js @@ -46,7 +46,7 @@ module.exports = async (req, res, next) => { const userId = user.id; const today = moment.utc(); - const expiresAt = today.add(14, "days").toDate(); + const expiresAt = today.add(30, "days").toDate(); const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; let refreshToken; diff --git a/src/routes/events/index.js b/src/routes/events/index.js index 901a189..33728d3 100644 --- a/src/routes/events/index.js +++ b/src/routes/events/index.js @@ -1,29 +1,31 @@ -const express = require('express'); +const express = require("express"); -const { isAuthenticated } = require('../../helpers'); +const { isAuthenticated } = require("../../helpers"); -const createEvent = require('./create-event'); -const deleteEvent = require('./delete-event'); -const editEvent = require('./edit-event'); -const getEvent = require('./get-event'); -const leaveEvent = require('./leave-event'); -const listEvents = require('./list-events'); -const joinEvent = require('./join-event'); +const createEvent = require("./create-event"); +const deleteEvent = require("./delete-event"); +const editEvent = require("./edit-event"); +const getEvent = require("./get-event"); +const leaveEvent = require("./leave-event"); +const listEvents = require("./list-events"); +const listOldEvents = require("./list-old-events"); +const joinEvent = require("./join-event"); const router = new express.Router(); -router.get('', listEvents); -router.post('', isAuthenticated({ isOptional: false }), createEvent); -router.get('/:eventId', getEvent); -router.put('/:eventId', isAuthenticated({ isOptional: false }), editEvent); -router.delete('/:eventId', isAuthenticated({ isOptional: false }), deleteEvent); +router.get("", listEvents); +router.get("/old", isAuthenticated({ isOptional: false }), listOldEvents); +router.post("", isAuthenticated({ isOptional: false }), createEvent); +router.get("/:eventId", getEvent); +router.put("/:eventId", isAuthenticated({ isOptional: false }), editEvent); +router.delete("/:eventId", isAuthenticated({ isOptional: false }), deleteEvent); router.post( - '/:eventId/join', + "/:eventId/join", isAuthenticated({ isOptional: false }), joinEvent ); router.put( - '/:eventId/leave', + "/:eventId/leave", isAuthenticated({ isOptional: false }), leaveEvent ); diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 3b29373..029bb73 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -7,12 +7,14 @@ const { validateListEvents } = require("./validations"); module.exports = async (req, res, next) => { const queryParams = req.query; + console.log(queryParams); + const { errors, isValid } = validateListEvents(queryParams); if (!isValid) return res.status(400).json(errors); const eventsQuery = {}; - if (queryParams.keywords) { + if (queryParams.keywords && queryParams.keywords !== "") { eventsQuery.$text = { $search: queryParams.keywords }; } @@ -33,9 +35,13 @@ module.exports = async (req, res, next) => { eventsQuery.startDate = { $lte: beforeDate }; } - let sortBy = queryParams.sortBy || "-startDate"; + let sortBy = "-startDate"; let page = queryParams.page ? queryParams.page - 1 : 0; const pageLimit = queryParams.pageLimit || 12; + const currentDate = moment().utc().toDate(); + + eventsQuery.startDate = { $gte: currentDate }; + eventsQuery.endDate = { $lte: currentDate }; let events; let total; diff --git a/src/routes/events/list-old-events.js b/src/routes/events/list-old-events.js new file mode 100644 index 0000000..37cfef8 --- /dev/null +++ b/src/routes/events/list-old-events.js @@ -0,0 +1,79 @@ +const moment = require("moment"); + +const { Event } = require("../../models/event"); + +const { validateListEvents } = require("./validations"); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + + const { errors, isValid } = validateListEvents(queryParams); + if (!isValid) return res.status(400).json(errors); + + const eventsQuery = {}; + + if (queryParams.keywords && queryParams.keywords !== "") { + eventsQuery.$text = { $search: queryParams.keywords }; + } + + let sortBy = "-startDate"; + let page = queryParams.page ? queryParams.page - 1 : 0; + const pageLimit = queryParams.pageLimit || 12; + + const currentDate = moment().utc().toDate(); + eventsQuery.endDate = { $gt: currentDate }; + eventsQuery.$or = [ + { managers: req?.user?.id }, + { participants: req?.user?.id }, + ]; + + let events; + let total; + try { + [events, total] = await Promise.all([ + Event.aggregate() + .match(eventsQuery) + .project({ + _id: 0, + id: "$_id", + address: 1, + endDate: 1, + name: 1, + poster: 1, + reviewsAmount: 1, + reviewsGoal: 1, + startDate: 1, + location: 1, + description: 1, + }) + .sort(sortBy) + .skip(page * pageLimit) + .limit(pageLimit), + Event.countDocuments(eventsQuery), + ]); + } catch (err) { + console.log("Events failed to be found or count at list-events"); + return next(err); + } + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + console.log(events); + return res.status(200).json({ + page: page + 1, + lastPage, + pageLimit, + total, + sortBy, + results: events, + }); +}; diff --git a/src/routes/users/create-user.js b/src/routes/users/create-user.js index 3fb3d2e..eccfd01 100644 --- a/src/routes/users/create-user.js +++ b/src/routes/users/create-user.js @@ -1,19 +1,19 @@ -const crypto = require('crypto'); +const crypto = require("crypto"); -const moment = require('moment'); -const { pick } = require('lodash'); -const randomstring = require('randomstring'); -const slugify = require('speakingurl'); +const moment = require("moment"); +const { pick } = require("lodash"); +const randomstring = require("randomstring"); +const slugify = require("speakingurl"); -const { cleanSpaces } = require('../../helpers'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { cleanSpaces } = require("../../helpers"); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); -const { validateCreateUser } = require('./validations'); +const { validateCreateUser } = require("./validations"); module.exports = async (req, res, next) => { if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } const { errors, isValid } = validateCreateUser(req.body); @@ -22,20 +22,20 @@ module.exports = async (req, res, next) => { } const userData = pick(req.body, [ - 'description', - 'disabilities', - 'email', - 'firstName', - 'gender', - 'isSubscribed', - 'lastName', - 'password', - 'phone', - 'showDisabilities', - 'showEmail', - 'showPhone', - 'username', - 'zip' + "description", + "disabilities", + "email", + "firstName", + "gender", + "isSubscribed", + "lastName", + "password", + "phone", + "showDisabilities", + "showEmail", + "showPhone", + "username", + "zip", ]); userData.firstName = cleanSpaces(userData.firstName); userData.lastName = cleanSpaces(userData.lastName); @@ -53,19 +53,19 @@ module.exports = async (req, res, next) => { try { repeatedUsers = await User.find({ $or: [{ email: userData.email }, { username: userData.username }], - isArchived: false + isArchived: false, }); } catch (err) { - console.log('Users failed to be found at create-user.'); + console.log("Users failed to be found at create-user."); return next(err); } if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === userData.email) { - return res.status(400).json({ email: 'Is already taken' }); + return res.status(400).json({ email: "Is already taken" }); } else if (usernameSent && user.username === userData.username) { - return res.status(400).json({ username: 'Is already taken' }); + return res.status(400).json({ username: "Is already taken" }); } let repeatedUser; @@ -74,13 +74,13 @@ module.exports = async (req, res, next) => { userData.lastName )}-${randomstring.generate({ length: 5, - capitalization: 'lowercase' + capitalization: "lowercase", })}`; try { repeatedUser = await User.findOne({ username: userData.username, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -98,7 +98,7 @@ module.exports = async (req, res, next) => { try { user = await User.create(userData); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -115,9 +115,9 @@ module.exports = async (req, res, next) => { } const refreshTokenData = { - expiresAt: moment.utc().add(14, 'days').toDate(), - key: `${user.id}${crypto.randomBytes(40).toString('hex')}`, - userId: user.id + expiresAt: moment.utc().add(14, "days").toDate(), + key: `${user.id}${crypto.randomBytes(40).toString("hex")}`, + userId: user.id, }; try { await RefreshToken.create(refreshTokenData); @@ -131,20 +131,23 @@ module.exports = async (req, res, next) => { } const dataResponse = pick(user, [ - '_id', - 'description', - 'disabilities', - 'email', - 'firstName', - 'gender', - 'isSubscribed', - 'lastName', - 'phone', - 'showDisabilities', - 'showEmail', - 'showPhone', - 'username', - 'zip' + "_id", + "description", + "disabilities", + "email", + "firstName", + "gender", + "isSubscribed", + "lastName", + "race", + "birthday", + "disability", + "phone", + "showDisabilities", + "showEmail", + "showPhone", + "username", + "zip", ]); return res.status(201).json(dataResponse); }; diff --git a/src/routes/users/edit-user.js b/src/routes/users/edit-user.js index 40da38a..bfc0ca3 100644 --- a/src/routes/users/edit-user.js +++ b/src/routes/users/edit-user.js @@ -61,6 +61,9 @@ module.exports = async (req, res, next) => { user.description = data.description || user.description; user.disabilities = data.disabilities || user.disabilities; + user.disability = data.disability || user.disabilities; + user.birthday = data.birthday || user.birthday; + user.race = data.race || user.race; user.firstName = data.firstName ? cleanSpaces(data.firstName) @@ -144,8 +147,11 @@ module.exports = async (req, res, next) => { id: user.id, avatar: user.avatar, description: user.description, + race: user?.race, + birthday: user?.birthday, disabilities: user.disabilities, firstName: user.firstName, + disability: user.disability, email: user?.email, gender: user.gender, isSubscribed: user.isSubscribed, diff --git a/src/routes/users/get-profile.js b/src/routes/users/get-profile.js index a231a20..6e40fd4 100644 --- a/src/routes/users/get-profile.js +++ b/src/routes/users/get-profile.js @@ -1,5 +1,6 @@ const { Event } = require("../../models/event"); const { Team } = require("../../models/team"); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { console.log(req.user.teams); @@ -66,6 +67,12 @@ module.exports = async (req, res, next) => { } } }); + console.log(req.user.reviewsAmount, typeof req.user.reviewsAmount); + + const ranking = + (await User.countDocuments({ + reviewsAmount: { $gt: req.user.reviewsAmount ?? 0 }, + })) + 1; const userData = { id: req.user.id, @@ -89,7 +96,11 @@ module.exports = async (req, res, next) => { teams, username: req.user.username, zip: req.user.zip, + avatar: req.user.avatar, + race: req.user?.race, + birthday: req.user?.birthday, + disability: req.user.disability, + ranking, }; - console.log(userData); return res.status(200).json(userData); }; diff --git a/src/routes/users/get-user.js b/src/routes/users/get-user.js index f6d7a08..d4a3a21 100644 --- a/src/routes/users/get-user.js +++ b/src/routes/users/get-user.js @@ -1,6 +1,6 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); -const { User } = require('../../models/user'); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { const userId = req.params.userId; @@ -10,81 +10,81 @@ module.exports = async (req, res, next) => { try { user = await User.aggregate([ { - $match: { _id: userIdObj } + $match: { _id: userIdObj }, }, { $lookup: { - from: 'events', - let: { events: '$events' }, + from: "events", + let: { events: "$events" }, pipeline: [ { $match: { $expr: { - $in: ['$_id', '$$events'] - } - } + $in: ["$_id", "$$events"], + }, + }, }, { $project: { _id: 0, - id: '$_id', + id: "$_id", endDate: 1, name: 1, poster: 1, - startDate: 1 - } - } + startDate: 1, + }, + }, ], - as: 'events' - } + as: "events", + }, }, { $lookup: { - from: 'teams', - let: { teams: '$teams' }, + from: "teams", + let: { teams: "$teams" }, pipeline: [ { $match: { $expr: { - $in: ['$_id', '$$teams'] - } - } + $in: ["$_id", "$$teams"], + }, + }, }, { $project: { _id: 0, - id: '$_id', + id: "$_id", avatar: 1, - name: 1 - } - } + name: 1, + }, + }, ], - as: 'teams' - } + as: "teams", + }, }, { $lookup: { - from: 'users', - let: { reviewsAmount: '$reviewsAmount' }, + from: "users", + let: { reviewsAmount: "$reviewsAmount" }, pipeline: [ { $match: { $expr: { - $gt: ['$reviewsAmount', '$$reviewsAmount'] - } - } + $gt: ["$reviewsAmount", "$$reviewsAmount"], + }, + }, }, { - $count: 'ranking' - } + $count: "ranking", + }, ], - as: 'ranking' - } + as: "ranking", + }, }, { $project: { _id: 0, - id: '$_id', + id: "$_id", avatar: 1, description: 1, disabilities: 1, @@ -96,6 +96,9 @@ module.exports = async (req, res, next) => { language: 1, lastName: 1, phone: 1, + race: 1, + birthday: 1, + disability: 1, ranking: 1, reviewsAmount: 1, showDisabilities: 1, @@ -103,13 +106,13 @@ module.exports = async (req, res, next) => { showPhone: 1, teams: 1, username: 1, - zip: 1 - } - } + zip: 1, + }, + }, ]); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "User not found" }); } console.log(`User ${userId} failed to be found at get-user`); @@ -117,11 +120,11 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(404).json({ general: 'User not found' }); + return res.status(404).json({ general: "User not found" }); } const dataResponse = Object.assign({}, user[0], { - ranking: user[0].ranking.length ? user[0].ranking[0].ranking + 1 : 1 + ranking: user[0].ranking.length ? user[0].ranking[0].ranking + 1 : 1, }); return res.status(200).json(dataResponse); }; From 573f002c537bc6d4b7360e692589f9c2346909e2 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 28 Feb 2025 19:21:21 +0500 Subject: [PATCH 06/67] add mapathon issue fix --- src/helpers/Error.js | 13 + src/models/user.js | 4 +- src/routes/events/create-event.js | 59 ++-- src/routes/events/list-events.js | 21 +- src/routes/events/list-old-events.js | 2 +- src/routes/events/validations.js | 385 +++++++++++++-------------- src/routes/venues/list-venues.js | 14 +- 7 files changed, 247 insertions(+), 251 deletions(-) create mode 100644 src/helpers/Error.js diff --git a/src/helpers/Error.js b/src/helpers/Error.js new file mode 100644 index 0000000..dc2e6e7 --- /dev/null +++ b/src/helpers/Error.js @@ -0,0 +1,13 @@ +function sendError(errors) { + let message = ""; + if (typeof errors === "object") { + let error = Object.entries(errors)[0]; + message = `${error[0]} ${error[1]}`; + } + if (typeof errors === "string") { + message = errors; + } + return { error: true, message, status: false }; +} + +module.exports = { sendError }; diff --git a/src/models/user.js b/src/models/user.js index f501210..9c3c00a 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -160,7 +160,7 @@ const userSchema = new mongoose.Schema( }, race: { type: String, - default: "not-to-disclose", + default: "", enum: { values: [ "black/african american", @@ -179,7 +179,7 @@ const userSchema = new mongoose.Schema( }, disability: { type: String, - default: "not-to-say", + default: "", enum: { values: ["yes", "No", "not-to-say"], general: "Invalid type of Disability", diff --git a/src/routes/events/create-event.js b/src/routes/events/create-event.js index 7787d3f..068fd02 100644 --- a/src/routes/events/create-event.js +++ b/src/routes/events/create-event.js @@ -1,13 +1,14 @@ -const axios = require('axios'); -const FormData = require('form-data'); -const moment = require('moment'); +const axios = require("axios"); +const FormData = require("form-data"); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { cleanSpaces } = require('../../helpers'); -const { Photo } = require('../../models/photo'); -const { Team } = require('../../models/team'); +const { Event } = require("../../models/event"); +const { cleanSpaces } = require("../../helpers"); +const { Photo } = require("../../models/photo"); +const { Team } = require("../../models/team"); -const { validateCreateEvent } = require('./validations'); +const { validateCreateEvent } = require("./validations"); +const { sendError } = require("../../helpers/Error"); module.exports = async (req, res, next) => { const data = { @@ -24,18 +25,18 @@ module.exports = async (req, res, next) => { poster: req.body.poster, reviewsGoal: req.body.reviewsGoal, startDate: req.body.startDate, - teamManager: req.body.teamManager + teamManager: req.body.teamManager, }; const { errors, isValid } = validateCreateEvent(data); - if (!isValid) return res.status(400).json(errors); + if (!isValid) return res.status(400).json(sendError(errors)); data.address = cleanSpaces(data.address); - data.endDate = moment(data.endDate).endOf('day').utc().toDate(); + data.endDate = moment(data.endDate).endOf("day").utc().toDate(); data.location = { - coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]] + coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]], }; delete data.locationCoordinates; @@ -49,9 +50,9 @@ module.exports = async (req, res, next) => { console.log(`Event ${data.name} failed to be found at create-event`); return next(err); } - + console.log("repeatedEvent", repeatedEvent); if (repeatedEvent) { - return res.status(400).json({ name: 'Is already taken' }); + return res.status(400).json(sendError({ name: "Is already taken" })); } if (data.poster) { @@ -64,11 +65,11 @@ module.exports = async (req, res, next) => { } if (!poster) { - return res.status(404).json({ poster: 'Not found' }); + return res.status(404).json(sendError({ poster: "Not found" })); } } - data.startDate = moment(data.startDate).startOf('day').utc().toDate(); + data.startDate = moment(data.startDate).startOf("day").utc().toDate(); if (data.teamManager) { let team; @@ -82,12 +83,12 @@ module.exports = async (req, res, next) => { } if (!team) { - return res.status(404).json({ teamManager: 'Not found' }); + return res.status(404).json(sendError({ teamManager: "Not found" })); } const teamManagers = team.managers.map((m) => m.toString()); if (!teamManagers.includes(req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json(sendError({ general: "Forbidden action" })); } } else { data.teamManager = undefined; @@ -95,31 +96,31 @@ module.exports = async (req, res, next) => { if (data.donationEnabled) { const campaignData = new FormData(); - campaignData.append('title', data.name); - campaignData.append('goal_in_cents', data.donationGoal * 100); + campaignData.append("title", data.name); + campaignData.append("goal_in_cents", data.donationGoal * 100); let options = { - method: 'POST', + method: "POST", url: `https://${ process.env.DONATELY_SUBDOMAIN }.dntly.com/api/v1/admin/campaigns`, headers: { - 'Content-Type': `multipart/form-data; boundary=${ + "Content-Type": `multipart/form-data; boundary=${ campaignData._boundary - }` + }`, }, auth: { username: process.env.DONATELY_TOKEN, - password: '' + password: "", }, - data: campaignData + data: campaignData, }; let response; try { response = await axios(options); } catch (err) { - console.log('Donation campaign failed to be created at create-event.'); + console.log("Donation campaign failed to be created at create-event."); return next(err); } @@ -130,7 +131,7 @@ module.exports = async (req, res, next) => { try { event = await Event.create(data); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -162,7 +163,7 @@ module.exports = async (req, res, next) => { if (event.location.coordinates) { eventLocation = { lat: event.location.coordinates[1], - lng: event.location.coordinates[0] + lng: event.location.coordinates[0], }; } const dataResponse = { @@ -177,7 +178,7 @@ module.exports = async (req, res, next) => { participantsGoal: event.participantsGoal, poster: event.poster, reviewsGoal: event.reviewsGoal, - teamManager: event.teamManager + teamManager: event.teamManager, }; return res.status(201).json(dataResponse); diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 029bb73..9284de3 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -20,28 +20,13 @@ module.exports = async (req, res, next) => { eventsQuery.isArchived = false; - let afterDate; - let beforeDate; - if (queryParams.afterDate && queryParams.beforeDate) { - afterDate = moment(queryParams.afterDate).utc().toDate(); - beforeDate = moment(queryParams.beforeDate).utc().toDate(); - - eventsQuery.startDate = { $gte: afterDate, $lte: beforeDate }; - } else if (queryParams.afterDate) { - afterDate = moment(queryParams.afterDate).utc().toDate(); - eventsQuery.startDate = { $gte: afterDate }; - } else if (queryParams.beforeDate) { - beforeDate = moment(queryParams.beforeDate).utc().toDate(); - eventsQuery.startDate = { $lte: beforeDate }; - } - let sortBy = "-startDate"; let page = queryParams.page ? queryParams.page - 1 : 0; const pageLimit = queryParams.pageLimit || 12; - const currentDate = moment().utc().toDate(); + const currentDate = moment().startOf("day").utc().toDate(); - eventsQuery.startDate = { $gte: currentDate }; - eventsQuery.endDate = { $lte: currentDate }; + eventsQuery.startDate = { $lte: currentDate }; + eventsQuery.endDate = { $gte: currentDate }; let events; let total; diff --git a/src/routes/events/list-old-events.js b/src/routes/events/list-old-events.js index 37cfef8..ec024ff 100644 --- a/src/routes/events/list-old-events.js +++ b/src/routes/events/list-old-events.js @@ -21,7 +21,7 @@ module.exports = async (req, res, next) => { const pageLimit = queryParams.pageLimit || 12; const currentDate = moment().utc().toDate(); - eventsQuery.endDate = { $gt: currentDate }; + eventsQuery.endDate = { $lt: currentDate }; eventsQuery.$or = [ { managers: req?.user?.id }, { participants: req?.user?.id }, diff --git a/src/routes/events/validations.js b/src/routes/events/validations.js index 15b98be..8d47bf4 100644 --- a/src/routes/events/validations.js +++ b/src/routes/events/validations.js @@ -1,50 +1,50 @@ -const { isEmpty } = require('lodash'); -const { isInt, isMongoId } = require('validator'); -const moment = require('moment'); +const { isEmpty } = require("lodash"); +const { isInt, isMongoId } = require("validator"); +const moment = require("moment"); -const { isNumber } = require('../../helpers'); +const { isNumber } = require("../../helpers"); module.exports = { validateCreateEvent(data) { const errors = {}; - if (typeof data.address === 'undefined' || data.address === '') { - errors.address = 'Is required'; - } else if (typeof data.address !== 'string') { - errors.address = 'Should be a string'; + if (typeof data.address === "undefined" || data.address === "") { + errors.address = "Is required"; + } else if (typeof data.address !== "string") { + errors.address = "Should be a string"; } if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' + typeof data.description !== "undefined" && + typeof data.description !== "string" ) { - errors.description = 'Should be a string'; + errors.description = "Should be a string"; } if (data.donationEnabled === true) { - if (typeof data.donationAmounts === 'undefined') { - errors.donationAmounts = 'Is required'; + if (typeof data.donationAmounts === "undefined") { + errors.donationAmounts = "Is required"; } - if (typeof data.donationGoal === 'undefined') { - errors.donationGoal = 'Is required'; + if (typeof data.donationGoal === "undefined") { + errors.donationGoal = "Is required"; } } - if (typeof data.donationAmounts !== 'undefined') { + if (typeof data.donationAmounts !== "undefined") { if (!Array.isArray(data.donationAmounts)) { - errors.donationAmounts = 'Should be an array'; + errors.donationAmounts = "Should be an array"; } else { data.donationAmounts.some((d) => { - if (typeof d.value === 'undefined') { + if (typeof d.value === "undefined") { errors.donationAmounts = - 'All elements should have a value property'; + "All elements should have a value property"; return true; - } else if (typeof d.value !== 'number') { - errors.donationAmounts = 'All value properties should be numbers'; + } else if (typeof d.value !== "number") { + errors.donationAmounts = "All value properties should be numbers"; return true; } else if (d < 5 || d > 10000) { errors.donationAmounts = - 'All value properties should be between 5 and 10000'; + "All value properties should be between 5 and 10000"; return true; } }); @@ -52,133 +52,132 @@ module.exports = { } if ( - typeof data.donationEnabled !== 'undefined' && - typeof data.donationEnabled !== 'boolean' + typeof data.donationEnabled !== "undefined" && + typeof data.donationEnabled !== "boolean" ) { - errors.donationEnabled = 'Should be a boolean'; + errors.donationEnabled = "Should be a boolean"; } - if (typeof data.donationGoal !== 'undefined') { - if (typeof data.donationGoal !== 'number') { - errors.donationGoal = 'Should be a number'; + if (typeof data.donationGoal !== "undefined") { + if (typeof data.donationGoal !== "number") { + errors.donationGoal = "Should be a number"; } else if (!isInt(data.donationGoal.toString())) { - errors.donationGoal = 'Should be a integer'; + errors.donationGoal = "Should be a integer"; } } let endDateIsValid = false; - if (typeof data.endDate === 'undefined' || data.endDate === '') { - errors.endDate = 'Is required'; - } else if (typeof data.endDate !== 'string') { - errors.endDate = 'Should be a string'; + if (typeof data.endDate === "undefined" || data.endDate === "") { + errors.endDate = "Is required"; + } else if (typeof data.endDate !== "string") { + errors.endDate = "Should be a string"; } else if (!moment(data.endDate).isValid()) { - errors.endDate = 'Should have a ISO-8601 format'; + errors.endDate = "Should have a ISO-8601 format"; } else { - const endDate = moment(data.endDate).endOf('day').utc(); - const today = moment().startOf('day').utc(); + const endDate = moment(data.endDate).endOf("day").utc(); + const today = moment().startOf("day").utc(); if (endDate.isBefore(today)) { - errors.endDate = 'Should be greater than or equal to today'; + errors.endDate = "Should be greater than or equal to today"; } else { endDateIsValid = true; } } if ( - typeof data.isOpen !== 'undefined' && - typeof data.isOpen !== 'boolean' + typeof data.isOpen !== "undefined" && + typeof data.isOpen !== "boolean" ) { - errors.isOpen = 'Should be a boolean'; + errors.isOpen = "Should be a boolean"; } - if (typeof data.locationCoordinates === 'undefined') { - errors.locationCoordinates = 'Is required'; + if (typeof data.locationCoordinates === "undefined") { + errors.locationCoordinates = "Is required"; } else if (!Array.isArray(data.locationCoordinates)) { - errors.locationCoordinates = 'Should be an array'; - } else if (typeof data.locationCoordinates[0] === 'undefined') { - errors.locationCoordinates = 'Latitude is required'; + errors.locationCoordinates = "Should be an array"; + } else if (typeof data.locationCoordinates[0] === "undefined") { + errors.locationCoordinates = "Latitude is required"; } else if (!isNumber(data.locationCoordinates[0])) { - errors.locationCoordinates = 'Latitude should be a number'; + errors.locationCoordinates = "Latitude should be a number"; } else if ( parseFloat(data.locationCoordinates[0]) < -90 || parseFloat(data.locationCoordinates[0]) > 90 ) { - errors.locationCoordinates = 'Latitude value is not valid'; - } else if (typeof data.locationCoordinates[1] === 'undefined') { - errors.locationCoordinates = 'Longitude is required'; + errors.locationCoordinates = "Latitude value is not valid"; + } else if (typeof data.locationCoordinates[1] === "undefined") { + errors.locationCoordinates = "Longitude is required"; } else if (!isNumber(data.locationCoordinates[1])) { - errors.locationCoordinates = 'Longitude should be a number'; + errors.locationCoordinates = "Longitude should be a number"; } else if ( parseFloat(data.locationCoordinates[1]) < -180 || parseFloat(data.locationCoordinates[1]) > 180 ) { - errors.locationCoordinates = 'Longitude value is not valid'; + errors.locationCoordinates = "Longitude value is not valid"; } else if (data.locationCoordinates.length > 2) { - errors.locationCoordinates = 'Should only have latitude and longitude'; + errors.locationCoordinates = "Should only have latitude and longitude"; } - - if (typeof data.name === 'undefined' || data.name === '') { - errors.name = 'Is required'; - } else if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; + if (typeof data.name === "undefined" || data.name === "") { + errors.name = "Is required"; + } else if (typeof data.name !== "string") { + errors.name = "Should be a string"; } - if (typeof data.participantsGoal === 'undefined') { - errors.participantsGoal = 'Is required'; - } else if (typeof data.participantsGoal !== 'number') { - errors.participantsGoal = 'Should be a number'; + if (typeof data.participantsGoal === "undefined") { + errors.participantsGoal = "Is required"; + } else if (typeof data.participantsGoal !== "number") { + errors.participantsGoal = "Should be a number"; } else if (!isInt(data.participantsGoal.toString())) { - errors.participantsGoal = 'Should be a integer'; + errors.participantsGoal = "Should be a integer"; } - if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { - errors.poster = 'Should be a string'; + if (typeof data.poster !== "undefined" && typeof data.poster !== "string") { + errors.poster = "Should be a string"; } - if (typeof data.reviewsGoal === 'undefined') { - errors.reviewsGoal = 'Is required'; - } else if (typeof data.reviewsGoal !== 'number') { - errors.reviewsGoal = 'Should be a number'; + if (typeof data.reviewsGoal === "undefined") { + errors.reviewsGoal = "Is required"; + } else if (typeof data.reviewsGoal !== "number") { + errors.reviewsGoal = "Should be a number"; } else if (!isInt(data.reviewsGoal.toString())) { - errors.reviewsGoal = 'Should be a integer'; + errors.reviewsGoal = "Should be a integer"; } let startDateIsValid = false; - if (typeof data.startDate === 'undefined' || data.startDate === '') { - errors.startDate = 'Is required'; - } else if (typeof data.startDate !== 'string') { - errors.startDate = 'Should be a string'; + if (typeof data.startDate === "undefined" || data.startDate === "") { + errors.startDate = "Is required"; + } else if (typeof data.startDate !== "string") { + errors.startDate = "Should be a string"; } else if (!moment(data.startDate).isValid()) { - errors.startDate = 'Should have a ISO-8601 format'; + errors.startDate = "Should have a ISO-8601 format"; } else { - const startDate = moment(data.startDate).startOf('day').utc(); - const today = moment().startOf('day').utc(); + const startDate = moment(data.startDate).startOf("day").utc(); + const today = moment().startOf("day").utc(); if (startDate.isBefore(today)) { - errors.startDate = 'Should be greater than or equal to today'; + errors.startDate = "Should be greater than or equal to today"; } else { startDateIsValid = true; } } if ( - typeof data.teamManager !== 'undefined' && - typeof data.teamManager !== 'string' + typeof data.teamManager !== "undefined" && + typeof data.teamManager !== "string" ) { - errors.teamManager = 'Should be a string'; + errors.teamManager = "Should be a string"; } else if (data.teamManager && !isMongoId(data.teamManager)) { - errors.teamManager = 'Should be a valid id'; + errors.teamManager = "Should be a valid id"; } if (endDateIsValid && startDateIsValid) { - const endDate = moment(data.endDate).endOf('day').utc(); - const startDate = moment(data.startDate).startOf('day').utc(); + const endDate = moment(data.endDate).endOf("day").utc(); + const startDate = moment(data.startDate).startOf("day").utc(); if (startDate.isAfter(endDate)) { - errors.endDate = 'Should be greater than or equal to startDate'; - errors.startDate = 'Should be less than or equal to endDate'; - } else if (endDate.diff(startDate, 'days') > 365) { - errors.endDate = 'Should last less than 365 days'; + errors.endDate = "Should be greater than or equal to startDate"; + errors.startDate = "Should be less than or equal to endDate"; + } else if (endDate.diff(startDate, "days") > 365) { + errors.endDate = "Should last less than 365 days"; } } @@ -187,35 +186,35 @@ module.exports = { validateEditEvent(data) { const errors = {}; - if (typeof data.address !== 'undefined') { - if (typeof data.address !== 'string') { - errors.address = 'Should be a string'; - } else if (data.address === '') { - errors.address = 'Is required'; + if (typeof data.address !== "undefined") { + if (typeof data.address !== "string") { + errors.address = "Should be a string"; + } else if (data.address === "") { + errors.address = "Is required"; } } if ( - typeof data.description !== 'undefined' && - typeof data.description !== 'string' + typeof data.description !== "undefined" && + typeof data.description !== "string" ) { - errors.description = 'Should be a string'; + errors.description = "Should be a string"; } let endDateIsValid = false; - if (typeof data.endDate !== 'undefined') { - if (typeof data.endDate !== 'string') { - errors.endDate = 'Should be a string'; - } else if (data.endDate === '') { - errors.endDate = 'Is required'; + if (typeof data.endDate !== "undefined") { + if (typeof data.endDate !== "string") { + errors.endDate = "Should be a string"; + } else if (data.endDate === "") { + errors.endDate = "Is required"; } else if (!moment(data.endDate).isValid()) { - errors.endDate = 'Should have a ISO-8601 format'; + errors.endDate = "Should have a ISO-8601 format"; } else { - const endDate = moment(data.endDate).endOf('day').utc(); - const today = moment().startOf('day').utc(); + const endDate = moment(data.endDate).endOf("day").utc(); + const today = moment().startOf("day").utc(); if (endDate.isBefore(today)) { - errors.endDate = 'Should be greater than or equal to today'; + errors.endDate = "Should be greater than or equal to today"; } else { endDateIsValid = true; } @@ -223,51 +222,51 @@ module.exports = { } if ( - typeof data.isOpen !== 'undefined' && - typeof data.isOpen !== 'boolean' + typeof data.isOpen !== "undefined" && + typeof data.isOpen !== "boolean" ) { - errors.isOpen = 'Should be a boolean'; + errors.isOpen = "Should be a boolean"; } - if (typeof data.locationCoordinates !== 'undefined') { + if (typeof data.locationCoordinates !== "undefined") { if (!Array.isArray(data.locationCoordinates)) { - errors.locationCoordinates = 'Should be an array'; - } else if (typeof data.locationCoordinates[0] === 'undefined') { - errors.locationCoordinates = 'Latitude is required'; + errors.locationCoordinates = "Should be an array"; + } else if (typeof data.locationCoordinates[0] === "undefined") { + errors.locationCoordinates = "Latitude is required"; } else if (!isNumber(data.locationCoordinates[0])) { - errors.locationCoordinates = 'Latitude should be a number'; + errors.locationCoordinates = "Latitude should be a number"; } else if ( parseFloat(data.locationCoordinates[0]) < -90 || parseFloat(data.locationCoordinates[0]) > 90 ) { - errors.locationCoordinates = 'Latitude value is not valid'; - } else if (typeof data.locationCoordinates[1] === 'undefined') { - errors.locationCoordinates = 'Longitude is required'; + errors.locationCoordinates = "Latitude value is not valid"; + } else if (typeof data.locationCoordinates[1] === "undefined") { + errors.locationCoordinates = "Longitude is required"; } else if (!isNumber(data.locationCoordinates[1])) { - errors.locationCoordinates = 'Longitude should be a number'; + errors.locationCoordinates = "Longitude should be a number"; } else if ( parseFloat(data.locationCoordinates[1]) < -180 || parseFloat(data.locationCoordinates[1]) > 180 ) { - errors.locationCoordinates = 'Longitude value is not valid'; + errors.locationCoordinates = "Longitude value is not valid"; } else if (data.locationCoordinates.length > 2) { - errors.locationCoordinates = 'Should only have latitude and longitude'; + errors.locationCoordinates = "Should only have latitude and longitude"; } } - if (typeof data.managers !== 'undefined') { + if (typeof data.managers !== "undefined") { if (!Array.isArray(data.managers)) { - errors.managers = 'Should be an array'; + errors.managers = "Should be an array"; } else { data.managers.some((m) => { - if (typeof m !== 'string') { - errors.managers = 'Should only have string values'; + if (typeof m !== "string") { + errors.managers = "Should only have string values"; return true; } else if (!m) { - errors.managers = 'Should not have empty values'; + errors.managers = "Should not have empty values"; return true; } else { - if (m.startsWith('-')) { + if (m.startsWith("-")) { m = m.substring(1); } @@ -280,26 +279,26 @@ module.exports = { } } - if (typeof data.name !== 'undefined') { - if (typeof data.name !== 'string') { - errors.name = 'Should be a string'; - } else if (data.name === '') { - errors.name = 'Is required'; + if (typeof data.name !== "undefined") { + if (typeof data.name !== "string") { + errors.name = "Should be a string"; + } else if (data.name === "") { + errors.name = "Is required"; } } - if (typeof data.participants !== 'undefined') { + if (typeof data.participants !== "undefined") { if (!Array.isArray(data.participants)) { - errors.participants = 'Should be an array'; + errors.participants = "Should be an array"; } else { data.participants.some((p) => { - if (typeof p !== 'string') { - errors.participants = 'Should only have string values'; + if (typeof p !== "string") { + errors.participants = "Should only have string values"; return true; } else if (!p) { - errors.participants = 'Should not have empty values'; + errors.participants = "Should not have empty values"; return true; - } else if (!p.startsWith('-')) { + } else if (!p.startsWith("-")) { errors.participants = `${p} should start with -`; return true; } else if (!isMongoId(p.substring(1))) { @@ -310,44 +309,44 @@ module.exports = { } } - if (typeof data.participantsGoal !== 'undefined') { + if (typeof data.participantsGoal !== "undefined") { if (data.participantsGoal === null) { - errors.participantsGoal = 'Is required'; - } else if (typeof data.participantsGoal !== 'number') { - errors.participantsGoal = 'Should be a number'; + errors.participantsGoal = "Is required"; + } else if (typeof data.participantsGoal !== "number") { + errors.participantsGoal = "Should be a number"; } else if (!isInt(data.participantsGoal.toString())) { - errors.participantsGoal = 'Should be a integer'; + errors.participantsGoal = "Should be a integer"; } } - if (typeof data.poster !== 'undefined' && typeof data.poster !== 'string') { - errors.poster = 'Should be a string'; + if (typeof data.poster !== "undefined" && typeof data.poster !== "string") { + errors.poster = "Should be a string"; } - if (typeof data.reviewsGoal !== 'undefined') { + if (typeof data.reviewsGoal !== "undefined") { if (data.reviewsGoal === null) { - errors.reviewsGoal = 'Is required'; - } else if (typeof data.reviewsGoal !== 'number') { - errors.reviewsGoal = 'Should be a number'; + errors.reviewsGoal = "Is required"; + } else if (typeof data.reviewsGoal !== "number") { + errors.reviewsGoal = "Should be a number"; } else if (!isInt(data.reviewsGoal.toString())) { - errors.reviewsGoal = 'Should be a integer'; + errors.reviewsGoal = "Should be a integer"; } } let startDateIsValid = false; - if (typeof data.startDate !== 'undefined') { - if (typeof data.startDate !== 'string') { - errors.startDate = 'Should be a string'; - } else if (data.startDate === '') { - errors.startDate = 'Is required'; + if (typeof data.startDate !== "undefined") { + if (typeof data.startDate !== "string") { + errors.startDate = "Should be a string"; + } else if (data.startDate === "") { + errors.startDate = "Is required"; } else if (!moment(data.startDate).isValid()) { - errors.startDate = 'Should have a ISO-8601 format'; + errors.startDate = "Should have a ISO-8601 format"; } else { - const startDate = moment(data.startDate).startOf('day').utc(); - const today = moment().startOf('day').utc(); + const startDate = moment(data.startDate).startOf("day").utc(); + const today = moment().startOf("day").utc(); if (startDate.isBefore(today)) { - errors.startDate = 'Should be greater than or equal to today'; + errors.startDate = "Should be greater than or equal to today"; } else { startDateIsValid = true; } @@ -355,26 +354,26 @@ module.exports = { } if ( - typeof data.teamManager !== 'undefined' && - typeof data.teamManager !== 'string' + typeof data.teamManager !== "undefined" && + typeof data.teamManager !== "string" ) { - errors.teamManager = 'Should be a string'; + errors.teamManager = "Should be a string"; } else if (data.teamManager && !isMongoId(data.teamManager)) { - errors.teamManager = 'Should be a valid id'; + errors.teamManager = "Should be a valid id"; } - if (typeof data.teams !== 'undefined') { + if (typeof data.teams !== "undefined") { if (!Array.isArray(data.teams)) { - errors.teams = 'Should be an array'; + errors.teams = "Should be an array"; } else { data.teams.some((t) => { - if (typeof t !== 'string') { - errors.teams = 'Should only have string values'; + if (typeof t !== "string") { + errors.teams = "Should only have string values"; return true; } else if (!t) { - errors.teams = 'Should not have empty values'; + errors.teams = "Should not have empty values"; return true; - } else if (!t.startsWith('-')) { + } else if (!t.startsWith("-")) { errors.teams = `${t} should start with -`; return true; } else if (!isMongoId(t.substring(1))) { @@ -386,14 +385,14 @@ module.exports = { } if (endDateIsValid && startDateIsValid) { - const endDate = moment(data.endDate).endOf('day').utc(); - const startDate = moment(data.startDate).startOf('day').utc(); + const endDate = moment(data.endDate).endOf("day").utc(); + const startDate = moment(data.startDate).startOf("day").utc(); if (startDate.isAfter(endDate)) { - errors.endDate = 'Should be greater than or equal to startDate'; - errors.startDate = 'Should be less than or equal to endDate'; - } else if (endDate.diff(startDate, 'days') > 365) { - errors.endDate = 'Should last less than 365 days'; + errors.endDate = "Should be greater than or equal to startDate"; + errors.startDate = "Should be less than or equal to endDate"; + } else if (endDate.diff(startDate, "days") > 365) { + errors.endDate = "Should last less than 365 days"; } } @@ -405,9 +404,9 @@ module.exports = { let isAfterDateValid = false; if ( queryParams.afterDate && - !moment(queryParams.afterDate, 'YYYY-MM-DD', true).isValid() + !moment(queryParams.afterDate, "YYYY-MM-DD", true).isValid() ) { - errors.afterDate = 'Should have YYYY-MM-DD format'; + errors.afterDate = "Should have YYYY-MM-DD format"; } else { isAfterDateValid = true; } @@ -415,52 +414,52 @@ module.exports = { let isBeforeDateValid = false; if ( queryParams.beforeDate && - !moment(queryParams.beforeDate, 'YYYY-MM-DD', true).isValid() + !moment(queryParams.beforeDate, "YYYY-MM-DD", true).isValid() ) { - errors.beforeDate = 'Should have YYYY-MM-DD format'; + errors.beforeDate = "Should have YYYY-MM-DD format"; } else { isBeforeDateValid = true; } if (isAfterDateValid && isBeforeDateValid) { - const afterDate = moment(queryParams.afterDate, 'YYYY-MM-DD').utc(); - const beforeDate = moment(queryParams.beforeDate, 'YYYY-MM-DD').utc(); + const afterDate = moment(queryParams.afterDate, "YYYY-MM-DD").utc(); + const beforeDate = moment(queryParams.beforeDate, "YYYY-MM-DD").utc(); if (afterDate.isAfter(beforeDate)) { - errors.afterDate = 'Should be less than beforeDate'; - errors.beforeDate = 'Should be greater than afterDate'; + errors.afterDate = "Should be less than beforeDate"; + errors.beforeDate = "Should be greater than afterDate"; } } const sortOptions = [ - 'name', - '-name', - 'reviewsAmount', - '-reviewsAmount', - 'startDate', - '-startDate' + "name", + "-name", + "reviewsAmount", + "-reviewsAmount", + "startDate", + "-startDate", ]; if (queryParams.sortBy && !sortOptions.includes(queryParams.sortBy)) { - errors.sortBy = 'Should be a valid sort'; + errors.sortBy = "Should be a valid sort"; } if (queryParams.page) { if (!isInt(queryParams.page)) { - errors.page = 'Should be a integer'; + errors.page = "Should be a integer"; } else if (parseInt(queryParams.page, 10) < 1) { - errors.page = 'Should be a positive integer'; + errors.page = "Should be a positive integer"; } } if (queryParams.pageLimit) { if (!isInt(queryParams.pageLimit)) { - errors.pageLimit = 'Should be a integer'; + errors.pageLimit = "Should be a integer"; } else if (parseInt(queryParams.pageLimit, 10) < 1) { - errors.pageLimit = 'Should be a positive integer'; + errors.pageLimit = "Should be a positive integer"; } else if (parseInt(queryParams.pageLimit, 10) > 12) { - errors.pageLimit = 'Should be less than 13'; + errors.pageLimit = "Should be less than 13"; } } return { errors, isValid: isEmpty(errors) }; - } + }, }; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index 457693e..6f6b77d 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -53,8 +53,6 @@ function covertDistanceToFeet(distanceInMeter, language = "en") { module.exports = async (req, res, next) => { const queryParams = req.query; - console.log(queryParams); - const { errors, isValid } = validateListVenues(queryParams); if (!isValid) return res.status(400).json(errors); @@ -271,11 +269,9 @@ module.exports = async (req, res, next) => { ) .skip(page * pageLimit) .limit(pageLimit), - (await Venue.find(dbVenuesFilters)).length, - /*TODO: count is deprecated in favor of countDocuments, but that does not support $near - would need to move to GeoWithin but that does not return sorted results - */ + (await Venue.find(dbVenuesFilters))?.length, ]); + console.log({ total }); } catch (err) { console.log( `Venues failed to be found or count at list-venues.\nvenuesQuery: ${JSON.stringify( @@ -446,7 +442,7 @@ module.exports = async (req, res, next) => { } //do we need to check for 0? - if (placesResponse.data.results.length == 1) { + if (placesResponse.data.results?.length == 1) { if (placesResponse.data.results[0].types[0] == "locality") { console.log( "Found a city only: ", @@ -491,6 +487,7 @@ module.exports = async (req, res, next) => { placesIds.push(place.place_id); }); + console.log("calling venues"); //Use array of Google Place IDs to find AXS Venues let venues; try { @@ -501,7 +498,7 @@ module.exports = async (req, res, next) => { ); return next(err); } - + console.log("venues length", venues.length); //Perform ratings logic on all returned venues venues.forEach((venue) => { //console.log('In scoring assignment'); @@ -593,6 +590,7 @@ module.exports = async (req, res, next) => { // places = places.map((place) => { const venue = find(venues, (venue) => venue.placeId === place.placeId); + console.log(venue); if (venue) { return Object.assign({}, place, { //new expanded fields From 03244298df7b4b84d9bc816886fce7ae7d02558b Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 3 Mar 2025 18:46:56 +0500 Subject: [PATCH 07/67] mapathin date validation fixed --- src/routes/events/validations.js | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/routes/events/validations.js b/src/routes/events/validations.js index 8d47bf4..4dc0762 100644 --- a/src/routes/events/validations.js +++ b/src/routes/events/validations.js @@ -74,14 +74,7 @@ module.exports = { } else if (!moment(data.endDate).isValid()) { errors.endDate = "Should have a ISO-8601 format"; } else { - const endDate = moment(data.endDate).endOf("day").utc(); - const today = moment().startOf("day").utc(); - - if (endDate.isBefore(today)) { - errors.endDate = "Should be greater than or equal to today"; - } else { - endDateIsValid = true; - } + endDateIsValid = true; } if ( @@ -150,14 +143,7 @@ module.exports = { } else if (!moment(data.startDate).isValid()) { errors.startDate = "Should have a ISO-8601 format"; } else { - const startDate = moment(data.startDate).startOf("day").utc(); - const today = moment().startOf("day").utc(); - - if (startDate.isBefore(today)) { - errors.startDate = "Should be greater than or equal to today"; - } else { - startDateIsValid = true; - } + startDateIsValid = true; } if ( From b7be5eae00ec139b95fe9283b7388932f1c07eb0 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 3 Mar 2025 18:58:49 +0500 Subject: [PATCH 08/67] user schema updated --- src/models/user.js | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/models/user.js b/src/models/user.js index 9c3c00a..72de29f 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -161,29 +161,24 @@ const userSchema = new mongoose.Schema( race: { type: String, default: "", - enum: { - values: [ - "black/african american", - "caucasian", - "indigenous/first nation/native american", - "latino/hispanic", - "middle eastern/north african", - "native hawaiian/pacific islander", - "biracial/multiracial", - "non-naucasian", - "not-to-disclose", - ], - general: "Invalid type of Race", - }, + enum: [ + "black/african american", + "caucasian", + "indigenous/first nation/native american", + "latino/hispanic", + "middle eastern/north african", + "native hawaiian/pacific islander", + "biracial/multiracial", + "non-naucasian", + "not-to-disclose", + "", + ], required: false, }, disability: { type: String, default: "", - enum: { - values: ["yes", "No", "not-to-say"], - general: "Invalid type of Disability", - }, + enum: ["yes", "No", "not-to-say", ""], required: false, }, }, From 3bbaf85a0d4612e6ce3027e6cf02eb3948a22b6e Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 3 Mar 2025 19:12:03 +0500 Subject: [PATCH 09/67] update user profile resolvedd --- src/routes/users/edit-user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/users/edit-user.js b/src/routes/users/edit-user.js index bfc0ca3..56e3036 100644 --- a/src/routes/users/edit-user.js +++ b/src/routes/users/edit-user.js @@ -61,9 +61,9 @@ module.exports = async (req, res, next) => { user.description = data.description || user.description; user.disabilities = data.disabilities || user.disabilities; - user.disability = data.disability || user.disabilities; + user.disability = data.disability || ""; user.birthday = data.birthday || user.birthday; - user.race = data.race || user.race; + user.race = data.race || ""; user.firstName = data.firstName ? cleanSpaces(data.firstName) From 7328f7e17719d7e41d1b7b30a52152a835e8a2f3 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 20 Mar 2025 16:46:11 +0500 Subject: [PATCH 10/67] asian race added --- src/models/user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/models/user.js b/src/models/user.js index 72de29f..84971d1 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -169,6 +169,7 @@ const userSchema = new mongoose.Schema( "middle eastern/north african", "native hawaiian/pacific islander", "biracial/multiracial", + "asian", "non-naucasian", "not-to-disclose", "", From 0d503a3d926b7750c381a517744e70e9688e550d Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 26 Mar 2025 21:04:56 +0500 Subject: [PATCH 11/67] forgot password link updated --- src/routes/auth/forgotten-password.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/auth/forgotten-password.js b/src/routes/auth/forgotten-password.js index ec73405..c2cd4fd 100644 --- a/src/routes/auth/forgotten-password.js +++ b/src/routes/auth/forgotten-password.js @@ -62,8 +62,8 @@ module.exports = async (req, res, next) => {

To reset your password use the link below:


- ${process.env.APP_URL}/reset-password?key=${passwordTicket.key} + https://axsmap.com/reset-password?key=${passwordTicket.key}"> + https://axsmap.com/reset-password?key=${passwordTicket.key}

Stay awesome.

From c65fbd5cac4b9448baa1cd7ce3b48dc56748eb19 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 2 Apr 2025 16:39:05 +0500 Subject: [PATCH 12/67] resolve forgot password issues and activate user flow --- src/routes/auth/activate-account.js | 7 ++++--- src/routes/auth/forgotten-password.js | 1 + src/routes/auth/reset-password.js | 30 +++++++++++++-------------- src/routes/auth/sign-up.js | 5 +++-- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/routes/auth/activate-account.js b/src/routes/auth/activate-account.js index d6885b3..798c29d 100644 --- a/src/routes/auth/activate-account.js +++ b/src/routes/auth/activate-account.js @@ -33,7 +33,7 @@ module.exports = async (req, res, next) => { const now = moment.utc(); if (expiresAt.isBefore(now)) { try { - await activationTicket.remove(); + await ActivationTicket.deleteOne({ key }); } catch (err) { console.log( `Activation ticket with key ${ @@ -125,7 +125,7 @@ module.exports = async (req, res, next) => { } try { - await activationTicket.remove(); + await ActivationTicket.deleteOne({ key }); } catch (err) { console.log( `Activation ticket with key ${ @@ -134,6 +134,7 @@ module.exports = async (req, res, next) => { ); return next(err); } + // TODO change base URL - return res.redirect(`${process.env.APP_URL}/sign-in`); + return res.redirect(`https://axsmap.com/sign-in`); }; diff --git a/src/routes/auth/forgotten-password.js b/src/routes/auth/forgotten-password.js index c2cd4fd..c782c05 100644 --- a/src/routes/auth/forgotten-password.js +++ b/src/routes/auth/forgotten-password.js @@ -56,6 +56,7 @@ module.exports = async (req, res, next) => { ); return next(err); } + console.log(passwordTicket); const htmlContent = `

Hi from AXS Map!

diff --git a/src/routes/auth/reset-password.js b/src/routes/auth/reset-password.js index 51f6a90..5eb1f6f 100644 --- a/src/routes/auth/reset-password.js +++ b/src/routes/auth/reset-password.js @@ -1,10 +1,10 @@ -const moment = require('moment'); +const moment = require("moment"); -const { PasswordTicket } = require('../../models/password-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { PasswordTicket } = require("../../models/password-ticket"); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); -const { validateResetPassword } = require('./validations'); +const { validateResetPassword } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateResetPassword(req.body); @@ -26,14 +26,14 @@ module.exports = async (req, res, next) => { } if (!passwordTicket) { - return res.status(404).json({ general: 'Password Ticket not found' }); + return res.status(404).json({ general: "Password Ticket not found" }); } const expiresAt = moment(passwordTicket.expiresAt).utc(); const today = moment.utc(); if (expiresAt.isBefore(today)) { try { - await passwordTicket.remove(); + await PasswordTicket.deleteOne({ key }); } catch (err) { console.log( `Password Ticket with key ${ @@ -43,14 +43,14 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(400).json({ general: 'Password Ticket expired' }); + return res.status(400).json({ general: "Password Ticket expired" }); } let user; try { user = await User.findOne({ email: passwordTicket.email, - isArchived: false + isArchived: false, }); } catch (err) { console.log( @@ -63,7 +63,7 @@ module.exports = async (req, res, next) => { if (!user) { try { - await passwordTicket.remove(); + await PasswordTicket.deleteOne({ key }); } catch (err) { console.log( `Password Ticket with key ${ @@ -73,12 +73,12 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(400).json({ general: 'User not found' }); + return res.status(400).json({ general: "User not found" }); } const passwordMatches = user.comparePassword(password); if (passwordMatches) { - return res.status(400).json({ password: 'Is already used' }); + return res.status(400).json({ password: "Is already used" }); } user.password = password; @@ -107,7 +107,7 @@ module.exports = async (req, res, next) => { if (refreshToken) { try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ userId: user.id }); } catch (err) { console.log( `Refresh Token with userId ${ @@ -119,7 +119,7 @@ module.exports = async (req, res, next) => { } try { - await passwordTicket.remove(); + await PasswordTicket.deleteOne({ key }); } catch (err) { console.log( `Password Ticket with key ${ @@ -129,5 +129,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 6367411..b31b6b6 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -128,13 +128,14 @@ module.exports = async (req, res, next) => { } const subject = "Activate Account"; + // TODO change base URL for ACTIVATION const htmlContent = `

Welcome to AXS Map!

To activate your account use the link below:


- ${process.env.API_URL}/auth/activate-account/${activationTicket.key} + https://axsmap.com//auth/activate-account/${activationTicket.key}"> + https://axsmap.com//auth/activate-account/${activationTicket.key}

Stay awesome.

From abc8213345c53ed8b44a0288a181d77ba46df465 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 2 Apr 2025 19:02:17 +0500 Subject: [PATCH 13/67] replace remove function with delete one --- src/routes/auth/generate-token.js | 16 +-- src/routes/auth/sign-out.js | 10 +- src/routes/events/delete-event.js | 34 ++--- src/routes/events/join-event.js | 40 +++--- src/routes/petitions/create-petition.js | 164 +++++++++++++--------- src/routes/petitions/edit-petition.js | 152 ++++++++++---------- src/routes/teams/delete-team.js | 28 ++-- src/routes/teams/join-team.js | 34 +++-- src/routes/users/archive-user.js | 28 ++-- src/routes/users/change-password.js | 14 +- src/routes/users/deactivate-user.js | 26 ++-- src/routes/users/delete-user.js | 14 +- src/scripts/db/update-events-locations.js | 44 +++--- 13 files changed, 318 insertions(+), 286 deletions(-) diff --git a/src/routes/auth/generate-token.js b/src/routes/auth/generate-token.js index 689e2d2..ff40108 100644 --- a/src/routes/auth/generate-token.js +++ b/src/routes/auth/generate-token.js @@ -1,9 +1,9 @@ -const jwt = require('jsonwebtoken'); -const moment = require('moment'); +const jwt = require("jsonwebtoken"); +const moment = require("moment"); -const { RefreshToken } = require('../../models/refresh-token'); +const { RefreshToken } = require("../../models/refresh-token"); -const { validateGenerateToken } = require('./validations'); +const { validateGenerateToken } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateGenerateToken(req.body); @@ -24,14 +24,14 @@ module.exports = async (req, res, next) => { } if (!refreshToken) { - return res.status(404).json({ general: 'Refresh Token not found' }); + return res.status(404).json({ general: "Refresh Token not found" }); } const expiresAt = moment(refreshToken.expiresAt).utc(); const today = moment.utc(); if (expiresAt.isBefore(today)) { try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ key }); } catch (err) { console.log( `Refresh Token with key ${ @@ -41,14 +41,14 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(401).json({ general: 'Refresh Token expired' }); + return res.status(401).json({ general: "Refresh Token expired" }); } const token = jwt.sign( { userId: refreshToken.userId }, process.env.JWT_SECRET, { - expiresIn: 3600 + expiresIn: 3600, } ); return res.status(200).json({ token }); diff --git a/src/routes/auth/sign-out.js b/src/routes/auth/sign-out.js index 6810f6b..57ada88 100644 --- a/src/routes/auth/sign-out.js +++ b/src/routes/auth/sign-out.js @@ -1,8 +1,8 @@ -const { RefreshToken } = require('../../models/refresh-token'); +const { RefreshToken } = require("../../models/refresh-token"); module.exports = async (req, res, next) => { if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); + return res.status(423).json({ general: "You are blocked" }); } let refreshToken; @@ -16,11 +16,11 @@ module.exports = async (req, res, next) => { } if (!refreshToken) { - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); } try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ userId: req.user.id }); } catch (err) { console.log( `Refresh token with userId ${ @@ -30,5 +30,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); }; diff --git a/src/routes/events/delete-event.js b/src/routes/events/delete-event.js index ca305ae..ec69388 100644 --- a/src/routes/events/delete-event.js +++ b/src/routes/events/delete-event.js @@ -1,16 +1,16 @@ -const aws = require('aws-sdk'); -const { last } = require('lodash'); -const moment = require('moment'); +const aws = require("aws-sdk"); +const { last } = require("lodash"); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); +const { Event } = require("../../models/event"); +const { Team } = require("../../models/team"); +const { User } = require("../../models/user"); const s3 = new aws.S3(); module.exports = async (req, res, next) => { if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); + return res.status(423).json({ general: "You are blocked" }); } const eventId = req.params.eventId; @@ -19,22 +19,22 @@ module.exports = async (req, res, next) => { try { event = await Event.findOne({ _id: eventId }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Event not found" }); } console.log(`Event ${eventId} failed to be found at delete-event`); return next(err); } if (!event) { - return res.status(404).json({ general: 'Event not found' }); + return res.status(404).json({ general: "Event not found" }); } if ( !event.managers.find((m) => m.toString() === req.user.id) && !req.user.isAdmin ) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } const endDate = moment(event.endDate).utc(); @@ -43,7 +43,7 @@ module.exports = async (req, res, next) => { if (endDate.isBefore(today) && event.reviews > 0) { return res.status(423).json({ general: - 'It cannot be removed because it already ended and has one or more reviews' + "It cannot be removed because it already ended and has one or more reviews", }); } @@ -55,7 +55,7 @@ module.exports = async (req, res, next) => { try { participants = await Promise.all(participantsPromises); } catch (err) { - console.log('A participant failed to be found at delete-event'); + console.log("A participant failed to be found at delete-event"); return next(err); } @@ -79,7 +79,7 @@ module.exports = async (req, res, next) => { for (const photo of event.photos) { const photoParams = { Bucket: process.env.AWS_S3_BUCKET, - Key: `events/photos/${last(photo.url.split('/'))}` + Key: `events/photos/${last(photo.url.split("/"))}`, }; try { @@ -102,7 +102,7 @@ module.exports = async (req, res, next) => { try { teams = await Promise.all(teamsPromises); } catch (err) { - console.log('A team failed to be found at delete-event'); + console.log("A team failed to be found at delete-event"); return next(err); } @@ -120,11 +120,11 @@ module.exports = async (req, res, next) => { } try { - await event.remove(); + await Event.deleteOne({ _id: eventId }); } catch (err) { console.log(`Event ${event.id} failed to be removed at delete-event`); return next(err); } - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); }; diff --git a/src/routes/events/join-event.js b/src/routes/events/join-event.js index f3b6378..3248f3a 100644 --- a/src/routes/events/join-event.js +++ b/src/routes/events/join-event.js @@ -1,7 +1,7 @@ -const moment = require('moment'); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); +const { Event } = require("../../models/event"); +const { Petition } = require("../../models/petition"); module.exports = async (req, res, next) => { const eventId = req.params.eventId; @@ -10,8 +10,8 @@ module.exports = async (req, res, next) => { try { event = await Event.findOne({ _id: eventId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Event not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Event not found" }); } console.log(`Event ${eventId} failed to be found at join-event`); @@ -19,21 +19,21 @@ module.exports = async (req, res, next) => { } if (!event) { - return res.status(404).json({ general: 'Event not found' }); + return res.status(404).json({ general: "Event not found" }); } const eventParticipants = event.participants.map((p) => p.toString()); if (eventParticipants.includes(req.user.id)) { return res .status(400) - .json({ general: 'You already are a participant in this event' }); + .json({ general: "You already are a participant in this event" }); } const eventManagers = event.managers.map((m) => m.toString()); if (eventManagers.includes(req.user.id)) { return res .status(400) - .json({ general: 'You already are a participant in this event' }); + .json({ general: "You already are a participant in this event" }); } if (event.isOpen) { @@ -57,14 +57,14 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Joined' }); + return res.status(200).json({ general: "Joined" }); } else { let petition; try { petition = await Petition.findOne({ event: event.id, sender: req.user.id, - type: 'request-user-event' + type: "request-user-event", }); } catch (err) { console.log( @@ -75,18 +75,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'You already have a pending petition with this event' + general: "You already have a pending petition with this event", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + event: event.id, + sender: req.user.id, + type: "request-user-event", + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at join-event` @@ -100,18 +104,18 @@ module.exports = async (req, res, next) => { if (endDate.isBefore(today)) { return res .status(423) - .json({ general: 'This event has already finished' }); + .json({ general: "This event has already finished" }); } const petitionData = { event: event.id, sender: req.user.id, - type: 'request-user-event' + type: "request-user-event", }; try { await Petition.create(petitionData); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -129,6 +133,6 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Requested' }); + return res.status(200).json({ general: "Requested" }); } }; diff --git a/src/routes/petitions/create-petition.js b/src/routes/petitions/create-petition.js index 3e1b5d8..dc270d9 100644 --- a/src/routes/petitions/create-petition.js +++ b/src/routes/petitions/create-petition.js @@ -1,11 +1,11 @@ -const moment = require('moment'); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); +const { Event } = require("../../models/event"); +const { Petition } = require("../../models/petition"); +const { Team } = require("../../models/team"); +const { User } = require("../../models/user"); -const { validateCreatePetition } = require('./validations'); +const { validateCreatePetition } = require("./validations"); module.exports = async (req, res, next) => { const { errors, isValid } = validateCreatePetition(req.body); @@ -18,13 +18,13 @@ module.exports = async (req, res, next) => { message: req.body.message, team: req.body.team, type: req.body.type, - user: req.body.user + user: req.body.user, } ); data.sender = req.user.id.toString(); const today = moment.utc(); - if (data.type === 'invite-team-event') { + if (data.type === "invite-team-event") { delete data.user; let petition; @@ -32,7 +32,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ event: data.event, team: data.team, - type: data.type + type: data.type, }); } catch (err) { console.log( @@ -43,18 +43,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'Team already has a pending invitation to event' + general: "Team already has a pending invitation to event", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + event: data.event, + team: data.team, + type: data.type, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -71,21 +75,21 @@ module.exports = async (req, res, next) => { return next(err); } - if (!event) return res.status(404).json({ event: 'Not found' }); + if (!event) return res.status(404).json({ event: "Not found" }); if (!event.managers.find((m) => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } if (event.teams.find((t) => t.toString() === data.team)) { return res.status(400).json({ - general: 'Team is already participant of event' + general: "Team is already participant of event", }); } const endDate = moment(event.endDate).utc(); if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); + return res.status(400).json({ general: "Event has already finished" }); } let team; @@ -96,8 +100,8 @@ module.exports = async (req, res, next) => { return next(err); } - if (!team) return res.status(404).json({ general: 'Team not found' }); - } else if (data.type === 'invite-user-event') { + if (!team) return res.status(404).json({ general: "Team not found" }); + } else if (data.type === "invite-user-event") { delete data.team; let petition; @@ -105,7 +109,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ event: data.event, type: data.type, - user: data.user + user: data.user, }); } catch (err) { console.log( @@ -116,18 +120,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'User already has a pending invitation to event' + general: "User already has a pending invitation to event", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.findOne({ + event: data.event, + type: data.type, + user: data.user, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -137,7 +145,7 @@ module.exports = async (req, res, next) => { } if (data.sender === data.user) { - return res.status(400).json({ general: 'User should not be you' }); + return res.status(400).json({ general: "User should not be you" }); } let event; @@ -148,21 +156,21 @@ module.exports = async (req, res, next) => { return next(err); } - if (!event) return res.status(404).json({ general: 'Event not found' }); + if (!event) return res.status(404).json({ general: "Event not found" }); if (!event.managers.find((m) => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } if (event.participants.find((p) => p.toString() === data.user)) { return res.status(400).json({ - general: 'User is already participant of event' + general: "User is already participant of event", }); } const endDate = moment(event.endDate).utc(); if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); + return res.status(400).json({ general: "Event has already finished" }); } let user; @@ -173,8 +181,8 @@ module.exports = async (req, res, next) => { return next(err); } - if (!user) return res.status(404).json({ general: 'User not found' }); - } else if (data.type === 'invite-user-team') { + if (!user) return res.status(404).json({ general: "User not found" }); + } else if (data.type === "invite-user-team") { delete data.event; let petition; @@ -182,7 +190,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ team: data.team, type: data.type, - user: data.user + user: data.user, }); } catch (err) { console.log( @@ -193,18 +201,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'User already has a pending invitation to team' + general: "User already has a pending invitation to team", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + team: data.team, + type: data.type, + user: data.user, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -214,7 +226,7 @@ module.exports = async (req, res, next) => { } if (req.sender === data.user) { - return res.status(400).json({ general: 'User should not be you' }); + return res.status(400).json({ general: "User should not be you" }); } let team; @@ -225,15 +237,15 @@ module.exports = async (req, res, next) => { return next(err); } - if (!team) return res.status(404).json({ general: 'Team not found' }); + if (!team) return res.status(404).json({ general: "Team not found" }); if (!team.managers.find((m) => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } if (team.members.find((m) => m.toString() === data.user)) { return res.status(400).json({ - general: 'User is already member of team' + general: "User is already member of team", }); } @@ -245,8 +257,8 @@ module.exports = async (req, res, next) => { return next(err); } - if (!user) return res.status(404).json({ general: 'User not found' }); - } else if (data.type === 'request-team-event') { + if (!user) return res.status(404).json({ general: "User not found" }); + } else if (data.type === "request-team-event") { delete data.user; let petition; @@ -254,7 +266,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ event: data.event, team: data.team, - type: data.type + type: data.type, }); } catch (err) { console.log( @@ -265,18 +277,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'Team already has a pending request with event' + general: "Team already has a pending request with event", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + event: data.event, + team: data.team, + type: data.type, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -293,17 +309,17 @@ module.exports = async (req, res, next) => { return next(err); } - if (!event) return res.status(404).json({ general: 'Event not found' }); + if (!event) return res.status(404).json({ general: "Event not found" }); if (event.teams.find((t) => t.toString() === data.sender)) { return res.status(400).json({ - general: 'Team is already participant of event ' + general: "Team is already participant of event ", }); } const endDate = moment(event.endDate).utc(); if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); + return res.status(400).json({ general: "Event has already finished" }); } let team; @@ -314,12 +330,12 @@ module.exports = async (req, res, next) => { return next(err); } - if (!team) return res.status(404).json({ general: 'Team not found' }); + if (!team) return res.status(404).json({ general: "Team not found" }); if (!team.managers.find((m) => m.toString() === data.sender)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - } else if (data.type === 'request-user-event') { + } else if (data.type === "request-user-event") { delete data.team; let petition; @@ -327,7 +343,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ event: data.event, sender: data.sender, - type: data.type + type: data.type, }); } catch (err) { console.log( @@ -338,18 +354,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'User already have a pending request with event' + general: "User already have a pending request with event", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + event: data.event, + sender: data.sender, + type: data.type, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -366,17 +386,17 @@ module.exports = async (req, res, next) => { return next(err); } - if (!event) return res.status(404).json({ general: 'Event not found' }); + if (!event) return res.status(404).json({ general: "Event not found" }); if (event.participants.find((p) => p.toString() === data.sender)) { return res.status(400).json({ - general: 'User already is participant of event' + general: "User already is participant of event", }); } const endDate = moment(event.endDate).utc(); if (endDate.isBefore(today)) { - return res.status(400).json({ general: 'Event has already finished' }); + return res.status(400).json({ general: "Event has already finished" }); } } else { // data.type === request-user-team @@ -387,7 +407,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ team: data.team, sender: data.sender, - type: data.type + type: data.type, }); } catch (err) { console.log( @@ -398,18 +418,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'User already have a pending request with team' + general: "User already have a pending request with team", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + team: data.team, + sender: data.sender, + type: data.type, + }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at create-petition` @@ -426,11 +450,11 @@ module.exports = async (req, res, next) => { return next(err); } - if (!team) return res.status(404).json({ general: 'Team not found' }); + if (!team) return res.status(404).json({ general: "Team not found" }); if (team.members.find((m) => m.toString() === data.sender)) { return res.status(400).json({ - general: 'User already is member of team' + general: "User already is member of team", }); } } @@ -439,7 +463,7 @@ module.exports = async (req, res, next) => { try { petition = await Petition.create(data); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -467,7 +491,7 @@ module.exports = async (req, res, next) => { state: petition.state, team: petition.team, type: petition.type, - user: petition.user + user: petition.user, } ); return res.status(201).json(dataResponse); diff --git a/src/routes/petitions/edit-petition.js b/src/routes/petitions/edit-petition.js index b3adcfa..f837db2 100644 --- a/src/routes/petitions/edit-petition.js +++ b/src/routes/petitions/edit-petition.js @@ -1,11 +1,11 @@ -const moment = require('moment'); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); +const { Event } = require("../../models/event"); +const { Petition } = require("../../models/petition"); +const { Team } = require("../../models/team"); +const { User } = require("../../models/user"); -const { validateEditPetition } = require('./validations'); +const { validateEditPetition } = require("./validations"); module.exports = async (req, res, next) => { const petitionId = req.params.petitionId; @@ -14,8 +14,8 @@ module.exports = async (req, res, next) => { try { petition = await Petition.findOne({ _id: petitionId }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Petition not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Petition not found" }); } console.log(`Petition ${petitionId} failed to be found at edit-petition`); @@ -23,19 +23,19 @@ module.exports = async (req, res, next) => { } if (!petition) { - return res.status(404).json({ general: 'Petition not found' }); + return res.status(404).json({ general: "Petition not found" }); } - if (petition.state === 'accepted') { - return res.status(400).json({ general: 'Is already accepted' }); + if (petition.state === "accepted") { + return res.status(400).json({ general: "Is already accepted" }); } - if (petition.state === 'canceled') { - return res.status(400).json({ general: 'Is already canceled' }); + if (petition.state === "canceled") { + return res.status(400).json({ general: "Is already canceled" }); } - if (petition.state === 'rejected') { - return res.status(400).json({ general: 'Is already rejected' }); + if (petition.state === "rejected") { + return res.status(400).json({ general: "Is already rejected" }); } const { errors, isValid } = validateEditPetition(req.body); @@ -45,14 +45,14 @@ module.exports = async (req, res, next) => { if (petition.sender.toString() === req.user.id) { isSender = true; - if (req.body.state === 'canceled') { - petition.state = 'canceled'; + if (req.body.state === "canceled") { + petition.state = "canceled"; } else { - return res.status(400).json({ state: 'Should only be canceled' }); + return res.status(400).json({ state: "Should only be canceled" }); } } - if (petition.type.endsWith('event')) { + if (petition.type.endsWith("event")) { let event; try { event = await Event.findOne({ _id: petition.event }); @@ -65,7 +65,7 @@ module.exports = async (req, res, next) => { if (!event) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -74,11 +74,11 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'Event is already removed. Petition was removed' + general: "Event is already removed. Petition was removed", }); } - if (petition.type === 'invite-team-event') { + if (petition.type === "invite-team-event") { let team; try { team = await Team.findOne({ _id: petition.team }); @@ -91,7 +91,7 @@ module.exports = async (req, res, next) => { if (!team) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -100,13 +100,13 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'Team is already removed. Petition was removed' + general: "Team is already removed. Petition was removed", }); } if (event.teams.find((t) => t.toString() === team.id)) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -116,20 +116,20 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: - 'Team is already a participant of event. Petition was removed' + "Team is already a participant of event. Petition was removed", }); } if (isSender) { if (!event.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } } else { if (!team.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { event.teams = [...event.teams, team.id]; event.updatedAt = moment.utc().toDate(); @@ -154,19 +154,19 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } - } else if (petition.type === 'invite-user-event') { + } else if (petition.type === "invite-user-event") { if ( event.participants.find( (p) => p.toString() === petition.user.toString() ) ) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -176,20 +176,20 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: - 'User is already a participant of event. Petition was removed' + "User is already a participant of event. Petition was removed", }); } if (isSender) { if (!event.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } } else { if (petition.user.toString() !== req.user.id) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { event.participants = [...event.participants, req.user.id]; event.updatedAt = moment.utc().toDate(); @@ -214,12 +214,12 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } - } else if (petition.type === 'request-team-event') { + } else if (petition.type === "request-team-event") { let team; try { team = await Team.findOne({ _id: petition.team }); @@ -232,7 +232,7 @@ module.exports = async (req, res, next) => { if (!team) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -241,13 +241,13 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'Team is already removed. Petition was removed' + general: "Team is already removed. Petition was removed", }); } if (event.teams.find((t) => t.toString() === team.id)) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -257,20 +257,20 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: - 'Team is already a participant of event. Petition was removed' + "Team is already a participant of event. Petition was removed", }); } if (isSender) { if (!team.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } } else { if (!event.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { event.teams = [...event.teams, team.id]; event.updatedAt = moment.utc().toDate(); @@ -295,9 +295,9 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } } else { @@ -314,7 +314,7 @@ module.exports = async (req, res, next) => { if (!user) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -323,13 +323,13 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'User is already removed. Petition was removed' + general: "User is already removed. Petition was removed", }); } if (event.participants.find((p) => p.toString() === user.id)) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -339,16 +339,16 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: - 'User is already a participant of event. Petition was removed' + "User is already a participant of event. Petition was removed", }); } if (!isSender) { if (!event.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { event.participants = [...event.participants, user.id]; event.updatedAt = moment.utc().toDate(); @@ -373,9 +373,9 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } } @@ -393,7 +393,7 @@ module.exports = async (req, res, next) => { if (!team) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -402,14 +402,14 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'Team is already removed. Petition was removed' + general: "Team is already removed. Petition was removed", }); } - if (petition.type === 'invite-user-team') { + if (petition.type === "invite-user-team") { if (team.members.find((m) => m.toString() === petition.user.toString())) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -418,20 +418,20 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'User is already a member of team. Petition was removed' + general: "User is already a member of team. Petition was removed", }); } if (isSender) { if (!team.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } } else { if (petition.user.toString() !== req.user.id) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { team.members = [...team.members, req.user.id]; team.updatedAt = moment.utc().toDate(); @@ -456,9 +456,9 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } } else { @@ -476,7 +476,7 @@ module.exports = async (req, res, next) => { if (!user) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -485,13 +485,13 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'User is already removed. Petition was removed' + general: "User is already removed. Petition was removed", }); } if (team.members.find((m) => m.toString() === user.id)) { try { - await petition.remove(); + await Petition.deleteOne({ _id: petitionId }); } catch (err) { console.log( `Petition ${petition.id} failed to be removed at edit-petition` @@ -500,16 +500,16 @@ module.exports = async (req, res, next) => { } return res.status(400).json({ - general: 'User is already a member of team. Petition was removed' + general: "User is already a member of team. Petition was removed", }); } if (!isSender) { if (!team.managers.find((m) => m.toString() === req.user.id)) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } - if (req.body.state === 'accepted') { + if (req.body.state === "accepted") { team.members = [...team.members, user.id]; team.updatedAt = moment.utc().toDate(); @@ -534,9 +534,9 @@ module.exports = async (req, res, next) => { return next(err); } - petition.state = 'accepted'; + petition.state = "accepted"; } else { - petition.state = 'rejected'; + petition.state = "rejected"; } } } @@ -553,5 +553,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/teams/delete-team.js b/src/routes/teams/delete-team.js index 912b7a1..14e4f76 100644 --- a/src/routes/teams/delete-team.js +++ b/src/routes/teams/delete-team.js @@ -1,12 +1,12 @@ -const moment = require('moment'); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Team } = require('../../models/team'); -const { User } = require('../../models/user'); +const { Event } = require("../../models/event"); +const { Team } = require("../../models/team"); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); + return res.status(423).json({ general: "You are blocked" }); } const teamId = req.params.teamId; @@ -15,8 +15,8 @@ module.exports = async (req, res, next) => { try { team = await Team.findOne({ _id: teamId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Team not found" }); } console.log(`Team ${teamId} failed to be found at delete-team`); @@ -24,14 +24,14 @@ module.exports = async (req, res, next) => { } if (!team) { - return res.status(404).json({ general: 'Team not found' }); + return res.status(404).json({ general: "Team not found" }); } if ( !team.managers.find((m) => m.toString() === req.user.id) && !req.user.isAdmin ) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } let archiveTeam = false; @@ -45,13 +45,13 @@ module.exports = async (req, res, next) => { try { teamEvents = await Promise.all(teamEventsPromises); } catch (err) { - console.log('A team event failed to be found at delete-team'); + console.log("A team event failed to be found at delete-team"); return next(err); } for (const event of teamEvents) { const endDate = moment(event.endDate).utc(); - const endOfToday = moment.utc().endOf('day'); + const endOfToday = moment.utc().endOf("day"); if (endDate.isBefore(endOfToday)) { event.teams = event.teams.filter((t) => t.toString() !== team.id); event.updatedAt = moment.utc().toDate(); @@ -76,7 +76,7 @@ module.exports = async (req, res, next) => { try { teamMembers = await Promise.all(teamMembersPromises); } catch (err) { - console.log('A team member failed to be found at delete-team'); + console.log("A team member failed to be found at delete-team"); return next(err); } @@ -104,12 +104,12 @@ module.exports = async (req, res, next) => { } } else { try { - await team.remove(); + await Team.deleteOne({ _id: teamId, isArchived: false }); } catch (err) { console.log(`Team ${team.id} failed to be removed at delete-team`); return next(err); } } - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); }; diff --git a/src/routes/teams/join-team.js b/src/routes/teams/join-team.js index c2de2e4..e847fa4 100644 --- a/src/routes/teams/join-team.js +++ b/src/routes/teams/join-team.js @@ -1,5 +1,5 @@ -const { Petition } = require('../../models/petition'); -const { Team } = require('../../models/team'); +const { Petition } = require("../../models/petition"); +const { Team } = require("../../models/team"); module.exports = async (req, res, next) => { const teamId = req.params.teamId; @@ -8,8 +8,8 @@ module.exports = async (req, res, next) => { try { team = await Team.findOne({ _id: teamId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Team not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Team not found" }); } console.log(`Team ${teamId} failed to be found at join-team`); @@ -17,21 +17,21 @@ module.exports = async (req, res, next) => { } if (!team) { - return res.status(404).json({ general: 'Team not found' }); + return res.status(404).json({ general: "Team not found" }); } const eventMembers = team.members.map((m) => m.toString()); if (eventMembers.includes(req.user.id)) { return res .status(400) - .json({ general: 'You already are a member in this team' }); + .json({ general: "You already are a member in this team" }); } const eventManagers = team.managers.map((m) => m.toString()); if (eventManagers.includes(req.user.id)) { return res .status(400) - .json({ general: 'You already are a member in this team' }); + .json({ general: "You already are a member in this team" }); } let petition; @@ -39,7 +39,7 @@ module.exports = async (req, res, next) => { petition = await Petition.findOne({ team: team.id, sender: req.user.id, - type: 'request-user-team' + type: "request-user-team", }); } catch (err) { console.log( @@ -50,18 +50,22 @@ module.exports = async (req, res, next) => { return next(err); } - if (petition && petition.state === 'pending') { + if (petition && petition.state === "pending") { return res.status(400).json({ - general: 'You already have a pending petition with this team' + general: "You already have a pending petition with this team", }); } if ( petition && - (petition.state === 'rejected' || petition.state === 'canceled') + (petition.state === "rejected" || petition.state === "canceled") ) { try { - await petition.remove(); + await Petition.deleteOne({ + team: team.id, + sender: req.user.id, + type: "request-user-team", + }); } catch (err) { console.log(`Petition ${petition.id} failed to be removed at join-team`); return next(err); @@ -71,12 +75,12 @@ module.exports = async (req, res, next) => { const petitionData = { team: team.id, sender: req.user.id, - type: 'request-user-team' + type: "request-user-team", }; try { await Petition.create(petitionData); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -94,5 +98,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Requested' }); + return res.status(200).json({ general: "Requested" }); }; diff --git a/src/routes/users/archive-user.js b/src/routes/users/archive-user.js index 4d19eba..9bf62e2 100644 --- a/src/routes/users/archive-user.js +++ b/src/routes/users/archive-user.js @@ -1,9 +1,9 @@ -const moment = require('moment'); +const moment = require("moment"); -const { ActivationTicket } = require('../../models/activation-ticket'); -const { PasswordTicket } = require('../../models/password-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { ActivationTicket } = require("../../models/activation-ticket"); +const { PasswordTicket } = require("../../models/password-ticket"); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { const userId = req.params.userId; @@ -12,8 +12,8 @@ module.exports = async (req, res, next) => { try { user = await User.findOne({ _id: userId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "User not found" }); } console.log(`User with Id ${userId} failed to be found at archive-user.`); @@ -21,11 +21,11 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(404).json({ general: 'User not found' }); + return res.status(404).json({ general: "User not found" }); } if (user.id !== req.user.id && !req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } let activateAccountTicket; @@ -35,7 +35,7 @@ module.exports = async (req, res, next) => { [activateAccountTicket, passwordTicket, refreshToken] = await Promise.all([ ActivationTicket.findOne({ email: user.email }), PasswordTicket.findOne({ email: user.email }), - RefreshToken.findOne({ userId: user.id }) + RefreshToken.findOne({ userId: user.id }), ]); } catch (err) { console.log( @@ -48,7 +48,7 @@ module.exports = async (req, res, next) => { if (activateAccountTicket) { try { - await activateAccountTicket.remove(); + await ActivationTicket.deleteOne({ email: user.email }); } catch (err) { console.log( `Activate user ticket with key ${ @@ -61,7 +61,7 @@ module.exports = async (req, res, next) => { if (passwordTicket) { try { - await passwordTicket.remove(); + await PasswordTicket.deleteOne({ email: user.email }); } catch (err) { console.log( `Password ticket with key ${ @@ -74,7 +74,7 @@ module.exports = async (req, res, next) => { if (refreshToken) { try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ userId: user.id }); } catch (err) { console.log( `Refresh token with key ${ @@ -97,5 +97,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/users/change-password.js b/src/routes/users/change-password.js index 2c88231..db7dbed 100644 --- a/src/routes/users/change-password.js +++ b/src/routes/users/change-password.js @@ -1,12 +1,12 @@ -const moment = require('moment'); +const moment = require("moment"); -const { RefreshToken } = require('../../models/refresh-token'); +const { RefreshToken } = require("../../models/refresh-token"); -const { validateChangePassword } = require('./validations'); +const { validateChangePassword } = require("./validations"); module.exports = async (req, res, next) => { if (req.user.isBlocked) { - return res.status(423).json({ general: 'You are blocked' }); + return res.status(423).json({ general: "You are blocked" }); } const { errors, isValid } = validateChangePassword(req.body); @@ -20,7 +20,7 @@ module.exports = async (req, res, next) => { const passwordMatches = req.user.comparePassword(oldPassword); if (!passwordMatches) { - return res.status(400).json({ oldPassword: 'Wrong password' }); + return res.status(400).json({ oldPassword: "Wrong password" }); } let refreshToken; @@ -37,7 +37,7 @@ module.exports = async (req, res, next) => { if (refreshToken) { try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ userId: req.user.id }); } catch (err) { console.log( `Refresh Token with key ${ @@ -60,5 +60,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/users/deactivate-user.js b/src/routes/users/deactivate-user.js index 880289f..642930a 100644 --- a/src/routes/users/deactivate-user.js +++ b/src/routes/users/deactivate-user.js @@ -1,9 +1,9 @@ -const moment = require('moment'); +const moment = require("moment"); -const { ActivationTicket } = require('../../models/activation-ticket'); -const { PasswordTicket } = require('../../models/password-ticket'); -const { RefreshToken } = require('../../models/refresh-token'); -const { User } = require('../../models/user'); +const { ActivationTicket } = require("../../models/activation-ticket"); +const { PasswordTicket } = require("../../models/password-ticket"); +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { const userId = req.user._id; @@ -12,8 +12,8 @@ module.exports = async (req, res, next) => { try { user = await User.findOne({ _id: userId, isArchived: false }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'User not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "User not found" }); } console.log(`User with Id ${userId} failed to be found at archive-user.`); @@ -21,7 +21,7 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(404).json({ general: 'User not found' }); + return res.status(404).json({ general: "User not found" }); } let activateAccountTicket; @@ -31,7 +31,7 @@ module.exports = async (req, res, next) => { [activateAccountTicket, passwordTicket, refreshToken] = await Promise.all([ ActivationTicket.findOne({ email: user.email }), PasswordTicket.findOne({ email: user.email }), - RefreshToken.findOne({ userId: user.id }) + RefreshToken.findOne({ userId: user.id }), ]); } catch (err) { console.log( @@ -44,7 +44,7 @@ module.exports = async (req, res, next) => { if (activateAccountTicket) { try { - await activateAccountTicket.remove(); + await ActivationTicket.deleteOne({ email: user.email }); } catch (err) { console.log( `Activate user ticket with key ${ @@ -57,7 +57,7 @@ module.exports = async (req, res, next) => { if (passwordTicket) { try { - await passwordTicket.remove(); + await PasswordTicket.deleteOne({ email: user.email }); } catch (err) { console.log( `Password ticket with key ${ @@ -70,7 +70,7 @@ module.exports = async (req, res, next) => { if (refreshToken) { try { - await refreshToken.remove(); + await RefreshToken.deleteOne({ userId: user.id }); } catch (err) { console.log( `Refresh token with key ${ @@ -93,5 +93,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(200).json({ general: 'Success' }); + return res.status(200).json({ general: "Success" }); }; diff --git a/src/routes/users/delete-user.js b/src/routes/users/delete-user.js index 401e7e4..6b32ce3 100644 --- a/src/routes/users/delete-user.js +++ b/src/routes/users/delete-user.js @@ -1,8 +1,8 @@ -const { User } = require('../../models/user'); +const { User } = require("../../models/user"); module.exports = async (req, res, next) => { if (!req.user.isAdmin) { - return res.status(403).json({ general: 'Forbidden action' }); + return res.status(403).json({ general: "Forbidden action" }); } const userId = req.params.userId; @@ -11,8 +11,8 @@ module.exports = async (req, res, next) => { try { user = await User.findOne({ _id: userId, isArchived: true }); } catch (err) { - if (err.name === 'CastError') { - return res.status(404).json({ general: 'Archived user not found' }); + if (err.name === "CastError") { + return res.status(404).json({ general: "Archived user not found" }); } console.log(`User with Id ${userId} failed to be found at delete-user.`); @@ -20,11 +20,11 @@ module.exports = async (req, res, next) => { } if (!user) { - return res.status(404).json({ general: 'Archived user not found' }); + return res.status(404).json({ general: "Archived user not found" }); } try { - await user.remove(); + await User.deleteOne({ _id: userId, isArchived: true }); } catch (err) { console.log( `User with email ${user.email} failed to be deleted at delete-user.` @@ -32,5 +32,5 @@ module.exports = async (req, res, next) => { return next(err); } - return res.status(204).json({ general: 'Success' }); + return res.status(204).json({ general: "Success" }); }; diff --git a/src/scripts/db/update-events-locations.js b/src/scripts/db/update-events-locations.js index ead1a7f..f5e2455 100644 --- a/src/scripts/db/update-events-locations.js +++ b/src/scripts/db/update-events-locations.js @@ -1,10 +1,10 @@ -const axios = require('axios'); -const mongoose = require('mongoose'); +const axios = require("axios"); +const mongoose = require("mongoose"); -require('dotenv').config(); +require("dotenv").config(); -const { eventSchema } = require('../../models/event'); -const { venueSchema } = require('../../models/venue'); +const { eventSchema } = require("../../models/event"); +const { venueSchema } = require("../../models/venue"); mongoose.Promise = global.Promise; @@ -23,21 +23,21 @@ const uri = process.env.MONGODB_URI; const options = { useMongoClient: true, socketTimeoutMS: 0, - keepAlive: 2000 + keepAlive: 2000, }; const db = mongoose.createConnection(uri, options); -db.on('connected', async () => { - console.log('Connection to DB established successfully'); +db.on("connected", async () => { + console.log("Connection to DB established successfully"); - const Event = db.model('Event', eventSchema); - const Venue = db.model('Venue', venueSchema); + const Event = db.model("Event", eventSchema); + const Venue = db.model("Venue", venueSchema); let totalEvents; try { totalEvents = await Event.count(); } catch (error) { - console.log('Events failed to be count'); + console.log("Events failed to be count"); console.log(error); await closeConnections(db); } @@ -54,7 +54,7 @@ db.on('connected', async () => { .skip(page * pageLimit) .limit(pageLimit); } catch (error) { - console.log('Events failed to be found'); + console.log("Events failed to be found"); console.log(error); await closeConnections(db); } @@ -66,7 +66,7 @@ db.on('connected', async () => { try { venues = await Promise.all(getVenues); } catch (err) { - console.log('Venues failed to be found'); + console.log("Venues failed to be found"); console.log(err); await closeConnections(db); } @@ -86,7 +86,7 @@ db.on('connected', async () => { try { places = await Promise.all(getPlaces); } catch (err) { - console.log('Places failed to be found'); + console.log("Places failed to be found"); console.log(err); await closeConnections(db); } @@ -106,7 +106,7 @@ db.on('connected', async () => { updateEvents.push(event.save()); } else { const event = events[i]; - removeEvents.push(event.remove()); + removeEvents.push(Event.deleteOne({ _id: event?._id })); } }); try { @@ -115,14 +115,14 @@ db.on('connected', async () => { console.log( `Events failed to be updated.\nData: ${JSON.stringify({ page, - i + i, })}` ); console.log(err); await closeConnections(db); } - console.log('Events updated'); + console.log("Events updated"); page = page + 1; i = i + events.length; @@ -131,7 +131,7 @@ db.on('connected', async () => { try { totalEvents = await Event.count(); } catch (error) { - console.log('Events failed to be count'); + console.log("Events failed to be count"); console.log(error); await closeConnections(db); } @@ -140,11 +140,11 @@ db.on('connected', async () => { await closeConnections(db); }); -db.on('error', (err) => { - console.log('Connection to DB failed ' + err); +db.on("error", (err) => { + console.log("Connection to DB failed " + err); process.exit(0); }); -db.on('disconnected', () => { - console.log('Connection from DB closed'); +db.on("disconnected", () => { + console.log("Connection from DB closed"); }); From 05cb0dab85a57970acb710ab0125257e6243351b Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 2 Apr 2025 19:06:50 +0500 Subject: [PATCH 14/67] replace remove function with delete one --- src/routes/petitions/create-petition.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/petitions/create-petition.js b/src/routes/petitions/create-petition.js index dc270d9..69a8474 100644 --- a/src/routes/petitions/create-petition.js +++ b/src/routes/petitions/create-petition.js @@ -131,7 +131,7 @@ module.exports = async (req, res, next) => { (petition.state === "rejected" || petition.state === "canceled") ) { try { - await Petition.findOne({ + await Petition.deleteOne({ event: data.event, type: data.type, user: data.user, From 26a4ae165189a7abfaad1c0ce3ec6dbc745fb9f9 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 7 Apr 2025 19:24:27 +0500 Subject: [PATCH 15/67] resolve activation account issue --- src/routes/auth/sign-up.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index b31b6b6..15acf14 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -134,8 +134,8 @@ module.exports = async (req, res, next) => {

To activate your account use the link below:


- https://axsmap.com//auth/activate-account/${activationTicket.key} + https://axsmap.com/auth/activate-account/${activationTicket.key}"> + https://axsmap.com/auth/activate-account/${activationTicket.key}

Stay awesome.

From 249e8e4441fb7e2fa493af99c1199a331b214e81 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 9 Apr 2025 23:49:18 +0500 Subject: [PATCH 16/67] new fields added in user model lastLocation lastActivityTime and device --- src/helpers/index.js | 62 ++++++++++++++++++++++++-------------- src/models/user.js | 22 ++++++++++++++ src/routes/venues/index.js | 16 +++++----- 3 files changed, 70 insertions(+), 30 deletions(-) diff --git a/src/helpers/index.js b/src/helpers/index.js index 94f26fc..a401165 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -1,15 +1,15 @@ -const aws = require('aws-sdk'); -const { camelCase } = require('lodash'); -const jwt = require('jsonwebtoken'); -const { mapKeys, pickBy } = require('lodash'); -const nodemailer = require('nodemailer'); -const { snakeCase } = require('lodash'); +const aws = require("aws-sdk"); +const { camelCase } = require("lodash"); +const jwt = require("jsonwebtoken"); +const { mapKeys, pickBy } = require("lodash"); +const nodemailer = require("nodemailer"); +const { snakeCase } = require("lodash"); -const { User } = require('../models/user'); +const { User } = require("../models/user"); module.exports = { cleanSpaces(string) { - return string.replace(/\s+/g, ' ').trim(); + return string.replace(/\s+/g, " ").trim(); }, deleteUnusedProperties(obj) { return pickBy(obj, (prop) => prop); @@ -18,10 +18,13 @@ module.exports = { ({ isOptional }) => async (req, res, next) => { const authorizationHeader = req.headers.authorization; + const deviceType = req.headers["x-device-type"]; + const userAgent = req.headers["user-agent"]; + let token; if (authorizationHeader) { - token = authorizationHeader.split(' ')[1]; + token = authorizationHeader.split(" ")[1]; } if (token) { @@ -30,17 +33,32 @@ module.exports = { decoded = await jwt.verify(token, process.env.JWT_SECRET); } catch (err) { console.log(err); - return res.status(401).json({ general: 'Failed to authenticate' }); + return res.status(401).json({ general: "Failed to authenticate" }); } let user; try { user = await User.findOne({ _id: decoded.userId, - isArchived: false + isArchived: false, }).select( - '-__v -createdAt -isAdmin -isArchived -isBlocked -hashedPassword -updatedAt' + "-__v -createdAt -isAdmin -isArchived -isBlocked -hashedPassword -updatedAt" ); + if (req.originalUrl.startsWith("/venues?") && req.method === "GET") { + const location = req.query.location; + if (location) { + const [lat, lng] = location + .split(",") + .map((coord) => coord.trim()); + user.lastLocation = { + lat, + lng, + }; + } + } + user.lastActivityTime = new Date().toISOString(); + user.device = deviceType || userAgent || ""; + user.save(); } catch (err) { console.log( `User ${decoded.userId} failed to be found at authenticate` @@ -55,20 +73,20 @@ module.exports = { (isOptional && req.user && req.user.isBlocked) || (!isOptional && req.user.isBlocked) ) { - return res.status(423).json({ general: 'You are blocked' }); + return res.status(423).json({ general: "You are blocked" }); } return next(); } - return res.status(404).json({ general: 'User not found' }); + return res.status(404).json({ general: "User not found" }); } if (isOptional) { return next(); } - return res.status(401).json({ general: 'No token provided' }); + return res.status(401).json({ general: "No token provided" }); }, isNumber(number) { return !isNaN(parseFloat(number)) && isFinite(number); @@ -80,30 +98,30 @@ module.exports = { return mapKeys(obj, (value, key) => snakeCase(key)); }, removeSpaces(string) { - return string.replace(/\s/g, ''); + return string.replace(/\s/g, ""); }, sendEmail({ senderEmail = process.env.SENDER_EMAIL, receiversEmails, subject, htmlContent, - textContent + textContent, }) { const transporter = nodemailer.createTransport({ SES: new aws.SES({ - apiVersion: '2010-12-01' - }) + apiVersion: "2010-12-01", + }), }); return transporter.sendMail({ from: `"AXS Map" <${senderEmail}>`, - to: receiversEmails.join(', '), + to: receiversEmails.join(", "), subject, text: textContent, - html: htmlContent + html: htmlContent, }); }, toJSON(obj) { return JSON.parse(JSON.stringify(obj)); - } + }, }; diff --git a/src/models/user.js b/src/models/user.js index 84971d1..d9cfe87 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -129,6 +129,28 @@ const userSchema = new mongoose.Schema( default: false, required: [true, "Is required"], }, + lastActivityTime: { + type: Date, + default: null, + }, + lastLocation: { + type: { + lat: { + type: Number, + }, + lng: { + type: Number, + }, + }, + default: { + lat: null, + lng: null, + }, + }, + device: { + type: String, + default: "", + }, showEmail: { type: Boolean, default: false, diff --git a/src/routes/venues/index.js b/src/routes/venues/index.js index 94fec3d..a66f887 100644 --- a/src/routes/venues/index.js +++ b/src/routes/venues/index.js @@ -1,17 +1,17 @@ -const express = require('express'); +const express = require("express"); -const { isAuthenticated } = require('../../helpers'); +const { isAuthenticated } = require("../../helpers"); -const archiveVenue = require('./archive-venue'); -const getVenue = require('./get-venue'); -const listVenues = require('./list-venues'); +const archiveVenue = require("./archive-venue"); +const getVenue = require("./get-venue"); +const listVenues = require("./list-venues"); const router = new express.Router(); -router.get('', listVenues); -router.get('/:placeId', getVenue); +router.get("", isAuthenticated({ isOptional: true }), listVenues); +router.get("/:placeId", getVenue); router.put( - '/:venueId/archive', + "/:venueId/archive", isAuthenticated({ isOptional: false }), archiveVenue ); From e5ed491acd99c0568decafcb5fe914286db51893 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Apr 2025 18:23:08 +0500 Subject: [PATCH 17/67] upComing mapathons added --- src/routes/events/index.js | 2 + src/routes/events/list-upcoimg-events.js | 77 ++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/routes/events/list-upcoimg-events.js diff --git a/src/routes/events/index.js b/src/routes/events/index.js index 33728d3..c64a0b3 100644 --- a/src/routes/events/index.js +++ b/src/routes/events/index.js @@ -10,11 +10,13 @@ const leaveEvent = require("./leave-event"); const listEvents = require("./list-events"); const listOldEvents = require("./list-old-events"); const joinEvent = require("./join-event"); +const listUpcoimgEvents = require("./list-upcoimg-events"); const router = new express.Router(); router.get("", listEvents); router.get("/old", isAuthenticated({ isOptional: false }), listOldEvents); +router.get("/upComing", listUpcoimgEvents); router.post("", isAuthenticated({ isOptional: false }), createEvent); router.get("/:eventId", getEvent); router.put("/:eventId", isAuthenticated({ isOptional: false }), editEvent); diff --git a/src/routes/events/list-upcoimg-events.js b/src/routes/events/list-upcoimg-events.js new file mode 100644 index 0000000..e2ef12d --- /dev/null +++ b/src/routes/events/list-upcoimg-events.js @@ -0,0 +1,77 @@ +const moment = require("moment"); + +const { Event } = require("../../models/event"); + +const { validateListEvents } = require("./validations"); + +module.exports = async (req, res, next) => { + const queryParams = req.query; + + const { errors, isValid } = validateListEvents(queryParams); + if (!isValid) return res.status(400).json(errors); + + const eventsQuery = {}; + + if (queryParams.keywords && queryParams.keywords !== "") { + eventsQuery.$text = { $search: queryParams.keywords }; + } + + eventsQuery.isArchived = false; + + let sortBy = "-startDate"; + let page = queryParams.page ? queryParams.page - 1 : 0; + const pageLimit = queryParams.pageLimit || 12; + const currentDate = moment().startOf("day").utc().toDate(); + + eventsQuery.startDate = { $gte: currentDate }; + + let events; + let total; + try { + [events, total] = await Promise.all([ + Event.aggregate() + .match(eventsQuery) + .project({ + _id: 0, + id: "$_id", + address: 1, + endDate: 1, + name: 1, + poster: 1, + reviewsAmount: 1, + reviewsGoal: 1, + startDate: 1, + location: 1, + description: 1, + }) + .sort(sortBy) + .skip(page * pageLimit) + .limit(pageLimit), + Event.countDocuments(eventsQuery), + ]); + } catch (err) { + console.log("Events failed to be found or count at list-events"); + return next(err); + } + + let lastPage = Math.ceil(total / pageLimit); + if (lastPage > 0) { + if (page > lastPage) { + return res + .status(400) + .json({ page: `Should be equal to or less than ${lastPage}` }); + } + } else { + page = null; + lastPage = null; + } + console.log(events); + return res.status(200).json({ + page: page + 1, + lastPage, + pageLimit, + total, + sortBy, + results: events, + }); +}; From e8474111be7fa6d8a3264032b5677ebd0df5cb49 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 22 Apr 2025 21:34:34 +0500 Subject: [PATCH 18/67] change review logic --- src/helpers/mail-template.js | 52 +++ src/helpers/venue-review-summary.js | 131 +++++-- src/models/activation-ticket.js | 27 +- src/models/review.js | 73 ++-- src/models/user.js | 3 + src/models/venue.js | 30 ++ src/routes/auth/sign-in.js | 4 +- src/routes/auth/sign-up.js | 16 +- src/routes/auth/validations.js | 1 + src/routes/reviews/create-review.js | 523 +++++++++++++++------------- src/routes/reviews/validations.js | 7 - src/routes/users/edit-user.js | 2 + src/routes/users/get-profile.js | 2 +- src/routes/venues/list-venues.js | 73 ++-- 14 files changed, 587 insertions(+), 357 deletions(-) create mode 100644 src/helpers/mail-template.js diff --git a/src/helpers/mail-template.js b/src/helpers/mail-template.js new file mode 100644 index 0000000..402e636 --- /dev/null +++ b/src/helpers/mail-template.js @@ -0,0 +1,52 @@ +export const activationEmailTemplate = (link,name) => { + return ` + + + + + + + +
+ + + + + + + + + + + +
+

Welcome to AXS MAP 🎉

+

You're just one step away from getting started!

+
+

+ Hi ${name}, +

+

+ Thanks for signing up! Please confirm your email address by clicking the button below. +

+ + + +

+ If you didn’t sign up for [Your App Name], no worries — you can safely ignore this email. +

+
+

+ Need help? Contact Support +

+

© 2025 AXS MAP. All rights reserved.

+
+
+ + +`; +}; diff --git a/src/helpers/venue-review-summary.js b/src/helpers/venue-review-summary.js index 6fc30b5..3e98162 100644 --- a/src/helpers/venue-review-summary.js +++ b/src/helpers/venue-review-summary.js @@ -1,5 +1,5 @@ //const { ReviewLogic } = require('review-icon-logic-2.json'); -const reviewLogic = require('./review-icon-logic-2.json'); +const reviewLogic = require("./review-icon-logic-2.json"); function assignFromYesNo(venueField) { //field may not exist for old data @@ -8,8 +8,8 @@ function assignFromYesNo(venueField) { // Mongoose hasOwnProperty test issues if ( venueField && - 'yes' in venueField && - 'no' in venueField && + "yes" in venueField && + "no" in venueField && !(venueField.yes === 0 && venueField.no === 0) ) { if (venueField.yes >= venueField.no) { @@ -23,10 +23,10 @@ function assignFromYesNo(venueField) { } function assignFromSteps(stepField) { - let moreThanTwo = 'moreThanTwo' in stepField ? stepField.moreThanTwo : 0; - let two = 'two' in stepField ? stepField.two : 0; - let one = 'one' in stepField ? stepField.one : 0; - let zero = 'zero' in stepField ? stepField.zero : 0; + let moreThanTwo = "moreThanTwo" in stepField ? stepField.moreThanTwo : 0; + let two = "two" in stepField ? stepField.two : 0; + let one = "one" in stepField ? stepField.one : 0; + let zero = "zero" in stepField ? stepField.zero : 0; if (moreThanTwo === 0 && two === 0 && one === 0 && zero === 0) { return null; @@ -97,14 +97,14 @@ module.exports = { //valid values: entrance, restroom, interior sectionLogic = reviewSummaryLogic[sectionName]; } else { - console.log('Error: Logic not found for sectionLogic: ' + sectionName); + console.log("Error: Logic not found for sectionLogic: " + sectionName); return { - errors: 'Logic not found for sectionLogic: ' + sectionName + errors: "Logic not found for sectionLogic: " + sectionName, }; } let ratingLevel, ratingGlyphs; - const ratingLevels = ['alert', 'caution', 'accessible']; + const ratingLevels = ["alert", "caution", "accessible"]; for (let rl = 0; rl < ratingLevels.length; rl++) { if ( @@ -117,26 +117,26 @@ module.exports = { let ratingDefinitionMatch = false; if ( - 'field' in ratingDefinition && + "field" in ratingDefinition && ratingDefinition.field in venueData ) { if ( - ('matchValue' in ratingDefinition && + ("matchValue" in ratingDefinition && venueData[ratingDefinition.field] === ratingDefinition.matchValue) || - ('notMatchValue' in ratingDefinition && + ("notMatchValue" in ratingDefinition && venueData[ratingDefinition.field] !== ratingDefinition.notMatchValue) ) { ratingDefinitionMatch = true; } - } else if ('fields' in ratingDefinition) { + } else if ("fields" in ratingDefinition) { let fieldMatchCount = 0; for (let field of ratingDefinition.fields) { if ( - ('matchValue' in ratingDefinition && + ("matchValue" in ratingDefinition && venueData[field] === ratingDefinition.matchValue) || - ('notMatchValue' in ratingDefinition && + ("notMatchValue" in ratingDefinition && venueData[field] !== ratingDefinition.notMatchValue) ) { fieldMatchCount++; @@ -148,18 +148,18 @@ module.exports = { } } - if (ratingDefinitionMatch === true && 'and' in ratingDefinition) { + if (ratingDefinitionMatch === true && "and" in ratingDefinition) { //console.log('Evaluate AND condition in ' + sectionName); if ( - 'field' in ratingDefinition.and && + "field" in ratingDefinition.and && ratingDefinition.and.field in venueData ) { //evaluate 'and' condition depending on match or noMatch value - if ('matchValue' in ratingDefinition.and) { + if ("matchValue" in ratingDefinition.and) { ratingDefinitionMatch = venueData[ratingDefinition.and.field] == ratingDefinition.and.matchValue; - } else if ('notMatchValue' in ratingDefinition.and) { + } else if ("notMatchValue" in ratingDefinition.and) { ratingDefinitionMatch = venueData[ratingDefinition.and.field] !== ratingDefinition.and.notMatchValue; @@ -173,11 +173,11 @@ module.exports = { if (ratingDefinitionMatch === true) { //console.log('Found rule match for ' + sectionName); - if (ratingLevels[rl] == 'alert') { + if (ratingLevels[rl] == "alert") { ratingLevel = 1; - } else if (ratingLevels[rl] == 'caution') { + } else if (ratingLevels[rl] == "caution") { ratingLevel = 3; - } else if (ratingLevels[rl] == 'accessible') { + } else if (ratingLevels[rl] == "accessible") { ratingLevel = 5; } @@ -197,16 +197,91 @@ module.exports = { //console.log('ratingLevel not set: ', sectionLogic); ratingLevel = 0; ratingGlyphs = - 'default' in sectionLogic && + "default" in sectionLogic && sectionLogic.default.length > 0 && - 'showGlyph' in sectionLogic.default[0] + "showGlyph" in sectionLogic.default[0] ? sectionLogic.default[0].showGlyph - : ''; + : ""; } return { ratingLevel: ratingLevel, - ratingGlyphs: ratingGlyphs + ratingGlyphs: ratingGlyphs, }; - } + }, + calculateInteriorScore(venue) { + const multipleFloors = venue.multipleFloors?.yes === 1; + const hasAccessibleElevator = venue.hasAccessibleElevator?.yes === 1; + const hasInteriorRamp = venue.hasInteriorRamp?.yes === 1; + const hasFlashingLights = venue.brightLightTitle?.yes === 1; + + const hasAnyGreen = + venue.multipleFloors?.no === 1 || + hasAccessibleElevator || + hasInteriorRamp; + + const isYellow = venue.hasWellLit?.no === 1 && hasFlashingLights; + + const isRed = + multipleFloors && + venue.hasAccessibleElevator?.no === 1 && + venue.hasInteriorRamp?.no === 1; + + if (isRed) return 1; + if (isYellow) return 3; + if (hasAnyGreen) return 5; + + return 3; + }, + calculateEntranceScore(venue) { + const hasStep = venue.steps?.zero === 1; + const hasPermanentRamp = venue.hasPermanentRamp?.yes === 1; + const hasSecondEntry = venue.hasSecondEntry?.yes === 1; + const hasWideEntrance = venue.hasWideEntrance?.yes === 1; + + const hasAnyGreenCondition = + hasStep || hasWideEntrance || hasPermanentRamp || hasSecondEntry; + + const isYellowCondition = + hasStep && venue.hasPermanentRamp.no === 1 && hasSecondEntry; + + const isRedCondition = + hasStep && + venue.hasPermanentRamp.no === 1 && + venue.hasSecondEntry?.no === 1; + + if (isRedCondition) return 1; + if (isYellowCondition) return 3; + if (hasAnyGreenCondition) return 5; + + return 3; + }, + calculateBathroomScore(venue) { + const hasWashroom = venue.hasWashroom?.yes === 1; + const hasSupportAroundToilet = venue.hasSupportAroundToilet?.yes === 1; + + if (venue.hasWashroom?.no === 1) { + return 1; + } + if ( + venue.hasSupportAroundToilet?.no === 1 && + venue.hasLoweredSinks?.no === 1 + ) { + return 3; + } + + if (hasWashroom || hasSupportAroundToilet) return 5; + + return 3; + }, + calculateMapIconScore() { + const total = entranceScore + interiorScore + restroomScore; + const avg = total / 3; + + // Maximum possible total is 15 (5 points each for entrance, interior, restroom) + // Scale the average to account for max possible score + if (avg > 3) return 5; + if (avg > 1) return 3; + return 1; + }, }; diff --git a/src/models/activation-ticket.js b/src/models/activation-ticket.js index 1fa8760..9e6112c 100644 --- a/src/models/activation-ticket.js +++ b/src/models/activation-ticket.js @@ -36,7 +36,32 @@ const activationTicketSchema = new mongoose.Schema( username: { type: String, maxlength: [67, 'Should have less than 68 characters'] - } + }, + aboutMe: { + type: String, + default:null, + maxlength: [67, 'Should have less than 68 characters'] + }, + dateOfBirth: { + type: String, + default:null, + maxlength: [67, 'Should have less than 68 characters'] + }, + disability: { + type: String, + default:null, + maxlength: [67, 'Should have less than 68 characters'] + }, + gender: { + type: String, + default:null, + maxlength: [67, 'Should have less than 68 characters'] + }, + race: { + type: String, + default:null, + maxlength: [67, 'Should have less than 68 characters'] + }, } }, { timestamps: true } diff --git a/src/models/review.js b/src/models/review.js index f719643..af9b67f 100644 --- a/src/models/review.js +++ b/src/models/review.js @@ -1,4 +1,4 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); const reviewSchema = new mongoose.Schema( { @@ -13,69 +13,74 @@ const reviewSchema = new mongoose.Schema( hasLargeStall: Boolean, hasSupportAroundToilet: Boolean, hasLoweredSinks: Boolean, + has1Step: Boolean, + has2Step: Boolean, + multipleFloors: Boolean, + hasWashroom: Boolean, + brightLightTitle: Boolean, //original fields allowsGuideDog: Boolean, comments: { type: String, - maxlength: [300, 'Should be less than 301 characters'] + maxlength: [300, "Should be less than 301 characters"], }, complaints: [ { comments: { type: String, - maxlength: [300, 'Should be less than 30 characters'] + maxlength: [300, "Should be less than 30 characters"], }, createdAt: { type: Date, default: Date.now, - required: [true, 'Is required'] + required: [true, "Is required"], }, type: { type: String, enum: { values: [ - 'biased', - 'copyright', - 'inconsistent', - 'offensive', - 'offtopic', - 'other', - 'spam' + "biased", + "copyright", + "inconsistent", + "offensive", + "offtopic", + "other", + "spam", ], - general: 'Invalid type of complaint' + general: "Invalid type of complaint", }, - required: [true, 'Is required'] + required: [true, "Is required"], }, user: { type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] - } - } + ref: "User", + required: [true, "Is required"], + }, + }, ], /* * deprecated 5-star scoring */ _entryScore: { - type: Number + type: Number, //max: [9, 'Should be less than 10'], //min: [1, 'Should be more than 0'] }, _bathroomScore: { - type: Number + type: Number, //max: [4, 'Should be less than 5'], //min: [1, 'Should be more than 0'] }, _isScoreConverted: { type: Boolean, - default: false + default: false, }, event: { type: mongoose.Schema.Types.ObjectId, - ref: 'Event' + ref: "Event", }, hasParking: Boolean, hasSecondEntry: Boolean, @@ -83,40 +88,40 @@ const reviewSchema = new mongoose.Schema( isBanned: { type: Boolean, default: false, - required: [true, 'Is required'] + required: [true, "Is required"], }, isQuiet: Boolean, isSpacious: Boolean, steps: { type: Number, - max: [3, 'Should be less than 4'], - min: [0, 'Should be more than -1'] + max: [3, "Should be less than 4"], + min: [0, "Should be more than -1"], }, team: { type: mongoose.Schema.Types.ObjectId, - ref: 'Team' + ref: "Team", }, user: { type: mongoose.Schema.Types.ObjectId, - ref: 'User', - required: [true, 'Is required'] + ref: "User", + required: [true, "Is required"], }, venue: { type: mongoose.Schema.Types.ObjectId, - ref: 'Venue', - required: [true, 'Is required'] + ref: "Venue", + required: [true, "Is required"], }, voters: [ { type: mongoose.Schema.Types.ObjectId, - ref: 'User' - } - ] + ref: "User", + }, + ], }, { timestamps: true } ); module.exports = { - Review: mongoose.model('Review', reviewSchema), - reviewSchema + Review: mongoose.model("Review", reviewSchema), + reviewSchema, }; diff --git a/src/models/user.js b/src/models/user.js index d9cfe87..3d5471b 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -175,6 +175,9 @@ const userSchema = new mongoose.Schema( type: String, maxlength: [32, "Should be less than 33 characters"], }, + aboutMe: { + type: String, + }, birthday: { type: Date, default: null, diff --git a/src/models/venue.js b/src/models/venue.js index e0c475d..aebf58b 100644 --- a/src/models/venue.js +++ b/src/models/venue.js @@ -13,6 +13,36 @@ const venueSchema = new mongoose.Schema( default: 0 } }, + brightLightTitle: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + hasWashroom: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, + multipleFloors: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, hasPortableRamp: { yes: { type: Number, diff --git a/src/routes/auth/sign-in.js b/src/routes/auth/sign-in.js index 15c4330..4a96d3e 100644 --- a/src/routes/auth/sign-in.js +++ b/src/routes/auth/sign-in.js @@ -62,9 +62,9 @@ module.exports = async (req, res, next) => { ); return next(err); } - +console.log(process.env.JWT_SECRET) const token = jwt.sign({ userId }, process.env.JWT_SECRET, { - expiresIn: 36000, + expiresIn: '30d', }); return res.status(200).json({ refreshToken: refreshToken.key, token }); }; diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 15acf14..071b7e8 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -10,6 +10,7 @@ const { cleanSpaces, sendEmail } = require("../../helpers"); const { User } = require("../../models/user"); const { validateSignUp } = require("./validations"); +const { activationEmailTemplate } = require("../../helpers/mail-template"); module.exports = async (req, res, next) => { const { errors, isValid } = validateSignUp(req.body); @@ -23,7 +24,13 @@ module.exports = async (req, res, next) => { "isSubscribed", "lastName", "password", + "aboutMe", + "dateOfBirth", + "disability", + "gender", + "race", ]); + data.aboutMe = cleanSpaces(data.aboutMe); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; @@ -114,6 +121,11 @@ module.exports = async (req, res, next) => { lastName: data.lastName, password: data.password, username: data.username, + aboutMe: data.aboutMe || null, + dateOfBirth: data.dateOfBirth || null, + disability: data.disability || null, + gender: data.gender || null, + race: data.race || null, }, }; try { @@ -147,10 +159,12 @@ module.exports = async (req, res, next) => { Stay awesome. `; const receiversEmails = [activationTicket.email]; + const activationLink = `https://axsmap.com/auth/activate-account/${activationTicket.key}`; + const name = `${(activationTicket?.userData?.firstName ?? '')} ${(activationTicket?.userData?.lastName?? '')}`; sendEmail({ subject, - htmlContent, + htmlContent:activationEmailTemplate(activationLink,name), textContent, receiversEmails, }); diff --git a/src/routes/auth/validations.js b/src/routes/auth/validations.js index 7c11055..451b3b7 100644 --- a/src/routes/auth/validations.js +++ b/src/routes/auth/validations.js @@ -149,6 +149,7 @@ module.exports = { } else if (data.password.length > 30) { errors.password = 'Should have less than 31 characters'; } + return { errors, isValid: isEmpty(errors) }; } diff --git a/src/routes/reviews/create-review.js b/src/routes/reviews/create-review.js index 7b78f17..2399513 100644 --- a/src/routes/reviews/create-review.js +++ b/src/routes/reviews/create-review.js @@ -1,51 +1,56 @@ -const axios = require('axios'); -const moment = require('moment'); +const axios = require("axios"); +const moment = require("moment"); -const { Event } = require('../../models/event'); -const { Photo } = require('../../models/photo'); -const { Review } = require('../../models/review'); -const { Team } = require('../../models/team'); -const { Venue } = require('../../models/venue'); +const { Event } = require("../../models/event"); +const { Photo } = require("../../models/photo"); +const { Review } = require("../../models/review"); +const { Team } = require("../../models/team"); +const { Venue } = require("../../models/venue"); -const { validateCreateEditReview } = require('./validations'); -const venueReviewSummary = require('../../helpers/venue-review-summary.js'); +const { validateCreateEditReview } = require("./validations"); +const venueReviewSummary = require("../../helpers/venue-review-summary.js"); module.exports = async (req, res, next) => { - console.log('body: ', req.body); - const { errors, isValid } = validateCreateEditReview(req.body); - if (!isValid) return res.status(400).json(errors); + // const { errors, isValid } = validateCreateEditReview(req.body); + // if (!isValid) return res.status(400).json(errors); const data = { - //new expanded fields - hasPermanentRamp: req.body.hasPermanentRamp, - hasPortableRamp: req.body.hasPortableRamp, + // existing fields + hasParking: req.body.hasParking, + hasWellLit: req.body.hasWellLit, + steps: req.body.steps, hasWideEntrance: req.body.hasWideEntrance, - hasAccessibleTableHeight: req.body.hasAccessibleTableHeight, hasAccessibleElevator: req.body.hasAccessibleElevator, - hasInteriorRamp: req.body.hasInteriorRamp, - hasSwingOutDoor: req.body.hasSwingOutDoor, - hasLargeStall: req.body.hasLargeStall, hasSupportAroundToilet: req.body.hasSupportAroundToilet, + // new added fields + has2Step: req.body.has2Step, + has1Step: req.body.has1Step, + multipleFloors: req.body.multipleFloors, + hasWashroom: req.body.hasWashroom, + brightLightTitle: req.body.brightLightTitle, + hasSecondEntry: req.body.hasSecondEntry, + hasPermanentRamp: req.body.hasPermanentRamp, hasLoweredSinks: req.body.hasLoweredSinks, - interiorScore: req.body.interiorScore, - _isScoreConverted: true, - //original fields - allowsGuideDog: req.body.allowsGuideDog, - //bathroomScore: req.body.bathroomScore, - comments: req.body.comments, - //entryScore: req.body.entryScore, + // hasPortableRamp: req.body.hasPortableRamp, + // hasAccessibleTableHeight: req.body.hasAccessibleTableHeight, + // hasInteriorRamp: req.body.hasInteriorRamp, + // hasSwingOutDoor: req.body.hasSwingOutDoor, + // hasLargeStall: req.body.hasLargeStall, + // interiorScore: req.body.interiorScore, + // _isScoreConverted: true, + // allowsGuideDog: req.body.allowsGuideDog, + // isQuiet: req.body.isQuiet, + // isSpacious: req.body.isSpacious, + // extra fields event: req.body.event, - hasParking: req.body.hasParking, - hasSecondEntry: req.body.hasSecondEntry, - hasWellLit: req.body.hasWellLit, - isQuiet: req.body.isQuiet, - isSpacious: req.body.isSpacious, - steps: req.body.steps, team: req.body.team, - user: req.user.id + user: req.user.id, + comments: req.body.comments, }; + console.log(data); + let event; if (data.event) { try { @@ -56,7 +61,7 @@ module.exports = async (req, res, next) => { } if (!event) { - return res.status(404).json({ event: 'Event not found' }); + return res.status(404).json({ event: "Event not found" }); } if ( @@ -65,16 +70,16 @@ module.exports = async (req, res, next) => { ) { return res .status(400) - .json({ event: 'You are not a participant of this event' }); + .json({ event: "You are not a participant of this event" }); } const startDate = moment(event.startDate).utc(); const endDate = moment(event.endDate).utc(); - const today = moment().startOf('day').utc(); + const today = moment().startOf("day").utc(); if (startDate.isAfter(today)) { - return res.status(400).json({ event: 'Event has not started yet' }); + return res.status(400).json({ event: "Event has not started yet" }); } else if (endDate.isBefore(today)) { - return res.status(400).json({ event: 'Event has already finished' }); + return res.status(400).json({ event: "Event has already finished" }); } } @@ -88,7 +93,7 @@ module.exports = async (req, res, next) => { } if (!team) { - return res.status(404).json({ team: 'Team not found' }); + return res.status(404).json({ team: "Team not found" }); } if ( @@ -97,7 +102,7 @@ module.exports = async (req, res, next) => { ) { return res .status(400) - .json({ team: 'You are not a member of this team' }); + .json({ team: "You are not a member of this team" }); } } @@ -128,8 +133,8 @@ module.exports = async (req, res, next) => { } const statusResponse = response.data.status; - if (statusResponse !== 'OK') { - return res.status(404).json({ general: 'Place not found' }); + if (statusResponse !== "OK") { + return res.status(404).json({ general: "Place not found" }); } const placeData = response.data.result; @@ -138,12 +143,12 @@ module.exports = async (req, res, next) => { location: { coordinates: [ placeData.geometry.location.lng, - placeData.geometry.location.lat - ] + placeData.geometry.location.lat, + ], }, name: placeData.name, placeId, - types: placeData.types + types: placeData.types, }; try { @@ -163,7 +168,7 @@ module.exports = async (req, res, next) => { try { review = await Review.create(data); } catch (err) { - if (typeof err.errors === 'object') { + if (typeof err.errors === "object") { const validationErrors = {}; Object.keys(err.errors).forEach((key) => { @@ -242,7 +247,7 @@ module.exports = async (req, res, next) => { } if (!photo) { - return res.status(404).json({ photo: 'Not found' }); + return res.status(404).json({ photo: "Not found" }); } venue.photos = [...venue.photos, photo.id]; @@ -273,129 +278,176 @@ module.exports = async (req, res, next) => { // //new expanded fields // - if (typeof review.hasPermanentRamp !== 'undefined') { - venue.hasPermanentRamp = { - yes: review.hasPermanentRamp - ? venue.hasPermanentRamp.yes + 1 - : venue.hasPermanentRamp.yes, - no: review.hasPermanentRamp - ? venue.hasPermanentRamp.no - : venue.hasPermanentRamp.no + 1 - }; - } - - if (typeof review.hasPortableRamp !== 'undefined') { - venue.hasPortableRamp = { - yes: review.hasPortableRamp - ? venue.hasPortableRamp.yes + 1 - : venue.hasPortableRamp.yes, - no: review.hasPortableRamp - ? venue.hasPortableRamp.no - : venue.hasPortableRamp.no + 1 - }; - } - - if (typeof review.hasWideEntrance !== 'undefined') { - venue.hasWideEntrance = { - yes: review.hasWideEntrance - ? venue.hasWideEntrance.yes + 1 - : venue.hasWideEntrance.yes, - no: review.hasWideEntrance - ? venue.hasWideEntrance.no - : venue.hasWideEntrance.no + 1 - }; - } - - if (typeof review.hasAccessibleTableHeight !== 'undefined') { - venue.hasAccessibleTableHeight = { - yes: review.hasAccessibleTableHeight - ? venue.hasAccessibleTableHeight.yes + 1 - : venue.hasAccessibleTableHeight.yes, - no: review.hasAccessibleTableHeight - ? venue.hasAccessibleTableHeight.no - : venue.hasAccessibleTableHeight.no + 1 - }; - } - - if (typeof review.hasAccessibleElevator !== 'undefined') { - venue.hasAccessibleElevator = { - yes: review.hasAccessibleElevator - ? venue.hasAccessibleElevator.yes + 1 - : venue.hasAccessibleElevator.yes, - no: review.hasAccessibleElevator - ? venue.hasAccessibleElevator.no - : venue.hasAccessibleElevator.no + 1 - }; - } - - if (typeof review.hasInteriorRamp !== 'undefined') { - venue.hasInteriorRamp = { - yes: review.hasInteriorRamp - ? venue.hasInteriorRamp.yes + 1 - : venue.hasInteriorRamp.yes, - no: review.hasInteriorRamp - ? venue.hasInteriorRamp.no - : venue.hasInteriorRamp.no + 1 - }; - } - - if (typeof review.hasSwingOutDoor !== 'undefined') { - venue.hasSwingOutDoor = { - yes: review.hasSwingOutDoor - ? venue.hasSwingOutDoor.yes + 1 - : venue.hasSwingOutDoor.yes, - no: review.hasSwingOutDoor - ? venue.hasSwingOutDoor.no - : venue.hasSwingOutDoor.no + 1 - }; - } - - if (typeof review.hasLargeStall !== 'undefined') { - venue.hasLargeStall = { - yes: review.hasLargeStall - ? venue.hasLargeStall.yes + 1 - : venue.hasLargeStall.yes, - no: review.hasLargeStall - ? venue.hasLargeStall.no - : venue.hasLargeStall.no + 1 - }; - } - - if (typeof review.hasSupportAroundToilet !== 'undefined') { - venue.hasSupportAroundToilet = { - yes: review.hasSupportAroundToilet - ? venue.hasSupportAroundToilet.yes + 1 - : venue.hasSupportAroundToilet.yes, - no: review.hasSupportAroundToilet - ? venue.hasSupportAroundToilet.no - : venue.hasSupportAroundToilet.no + 1 - }; - } - - if (typeof review.hasLoweredSinks !== 'undefined') { - venue.hasLoweredSinks = { - yes: review.hasLoweredSinks - ? venue.hasLoweredSinks.yes + 1 - : venue.hasLoweredSinks.yes, - no: review.hasLoweredSinks - ? venue.hasLoweredSinks.no - : venue.hasLoweredSinks.no + 1 - }; - } + // hasParking: req.body.hasParking, + // hasWellLit: req.body.hasWellLit, + // steps: req.body.steps, + // hasWideEntrance: req.body.hasWideEntrance, + // hasAccessibleElevator: req.body.hasAccessibleElevator, + // hasSupportAroundToilet: req.body.hasSupportAroundToilet, + // // new added fields + // has2Step:req.body.has2Step , + // multipleFloors: req.body.multipleFloors, + // hasWashroom: req.body.hasWashroom, + // brightLightTitle: req.body.brightLightTitle, + // has1Step: req.body.has1Step, + + const keys = [ + "hasParking", + "hasWellLit", + "hasWideEntrance", + "hasAccessibleElevator", + "hasSupportAroundToilet", + "multipleFloors", + "hasWashroom", + "brightLightTitle", + "hasSecondEntry", + "hasPermanentRamp", + "hasLoweredSinks", + ]; + + keys.forEach((key) => { + if (typeof review[key] !== "undefined") { + venue[key] = { + yes: venue[key].yes + (review[key] ? 1 : 0), + no: venue[key].no + (review[key] ? 0 : 1), + }; + } + }); + + // if (typeof review.hasPermanentRamp !== "undefined") { + // venue.hasPermanentRamp = { + // yes: review.hasPermanentRamp + // ? venue.hasPermanentRamp.yes + 1 + // : venue.hasPermanentRamp.yes, + // no: review.hasPermanentRamp + // ? venue.hasPermanentRamp.no + // : venue.hasPermanentRamp.no + 1, + // }; + // } + + // if (typeof review.hasPermanentRamp !== "undefined") { + // venue.hasPermanentRamp = { + // yes: review.hasPermanentRamp + // ? venue.hasPermanentRamp.yes + 1 + // : venue.hasPermanentRamp.yes, + // no: review.hasPermanentRamp + // ? venue.hasPermanentRamp.no + // : venue.hasPermanentRamp.no + 1, + // }; + // } + + // if (typeof review.hasPortableRamp !== "undefined") { + // venue.hasPortableRamp = { + // yes: review.hasPortableRamp + // ? venue.hasPortableRamp.yes + 1 + // : venue.hasPortableRamp.yes, + // no: review.hasPortableRamp + // ? venue.hasPortableRamp.no + // : venue.hasPortableRamp.no + 1, + // }; + // } + + // if (typeof review.hasWideEntrance !== "undefined") { + // venue.hasWideEntrance = { + // yes: review.hasWideEntrance + // ? venue.hasWideEntrance.yes + 1 + // : venue.hasWideEntrance.yes, + // no: review.hasWideEntrance + // ? venue.hasWideEntrance.no + // : venue.hasWideEntrance.no + 1, + // }; + // } + + // if (typeof review.hasAccessibleTableHeight !== "undefined") { + // venue.hasAccessibleTableHeight = { + // yes: review.hasAccessibleTableHeight + // ? venue.hasAccessibleTableHeight.yes + 1 + // : venue.hasAccessibleTableHeight.yes, + // no: review.hasAccessibleTableHeight + // ? venue.hasAccessibleTableHeight.no + // : venue.hasAccessibleTableHeight.no + 1, + // }; + // } + + // if (typeof review.hasAccessibleElevator !== "undefined") { + // venue.hasAccessibleElevator = { + // yes: review.hasAccessibleElevator + // ? venue.hasAccessibleElevator.yes + 1 + // : venue.hasAccessibleElevator.yes, + // no: review.hasAccessibleElevator + // ? venue.hasAccessibleElevator.no + // : venue.hasAccessibleElevator.no + 1, + // }; + // } + + // if (typeof review.hasInteriorRamp !== "undefined") { + // venue.hasInteriorRamp = { + // yes: review.hasInteriorRamp + // ? venue.hasInteriorRamp.yes + 1 + // : venue.hasInteriorRamp.yes, + // no: review.hasInteriorRamp + // ? venue.hasInteriorRamp.no + // : venue.hasInteriorRamp.no + 1, + // }; + // } + + // if (typeof review.hasSwingOutDoor !== "undefined") { + // venue.hasSwingOutDoor = { + // yes: review.hasSwingOutDoor + // ? venue.hasSwingOutDoor.yes + 1 + // : venue.hasSwingOutDoor.yes, + // no: review.hasSwingOutDoor + // ? venue.hasSwingOutDoor.no + // : venue.hasSwingOutDoor.no + 1, + // }; + // } + + // if (typeof review.hasLargeStall !== "undefined") { + // venue.hasLargeStall = { + // yes: review.hasLargeStall + // ? venue.hasLargeStall.yes + 1 + // : venue.hasLargeStall.yes, + // no: review.hasLargeStall + // ? venue.hasLargeStall.no + // : venue.hasLargeStall.no + 1, + // }; + // } + + // if (typeof review.hasSupportAroundToilet !== "undefined") { + // venue.hasSupportAroundToilet = { + // yes: review.hasSupportAroundToilet + // ? venue.hasSupportAroundToilet.yes + 1 + // : venue.hasSupportAroundToilet.yes, + // no: review.hasSupportAroundToilet + // ? venue.hasSupportAroundToilet.no + // : venue.hasSupportAroundToilet.no + 1, + // }; + // } + + // if (typeof review.hasLoweredSinks !== "undefined") { + // venue.hasLoweredSinks = { + // yes: review.hasLoweredSinks + // ? venue.hasLoweredSinks.yes + 1 + // : venue.hasLoweredSinks.yes, + // no: review.hasLoweredSinks + // ? venue.hasLoweredSinks.no + // : venue.hasLoweredSinks.no + 1, + // }; + // } // //original fields // - if (typeof review.allowsGuideDog !== 'undefined') { - venue.allowsGuideDog = { - yes: review.allowsGuideDog - ? venue.allowsGuideDog.yes + 1 - : venue.allowsGuideDog.yes, - no: review.allowsGuideDog - ? venue.allowsGuideDog.no - : venue.allowsGuideDog.no + 1 - }; - } + // if (typeof review.allowsGuideDog !== "undefined") { + // venue.allowsGuideDog = { + // yes: review.allowsGuideDog + // ? venue.allowsGuideDog.yes + 1 + // : venue.allowsGuideDog.yes, + // no: review.allowsGuideDog + // ? venue.allowsGuideDog.no + // : venue.allowsGuideDog.no + 1, + // }; + // } /* if (typeof review.bathroomScore !== 'undefined') { @@ -421,83 +473,80 @@ module.exports = async (req, res, next) => { } */ - if (typeof review.hasParking !== 'undefined') { - venue.hasParking = { - yes: review.hasParking ? venue.hasParking.yes + 1 : venue.hasParking.yes, - no: review.hasParking ? venue.hasParking.no : venue.hasParking.no + 1 - }; - } - - if (typeof review.hasSecondEntry !== 'undefined') { - venue.hasSecondEntry = { - yes: review.hasSecondEntry - ? venue.hasSecondEntry.yes + 1 - : venue.hasSecondEntry.yes, - no: review.hasSecondEntry - ? venue.hasSecondEntry.no - : venue.hasSecondEntry.no + 1 - }; - } - - if (typeof review.hasWellLit !== 'undefined') { - venue.hasWellLit = { - yes: review.hasWellLit ? venue.hasWellLit.yes + 1 : venue.hasWellLit.yes, - no: review.hasWellLit ? venue.hasWellLit.no : venue.hasWellLit.no + 1 - }; - } - - if (typeof review.isQuiet !== 'undefined') { - venue.isQuiet = { - yes: review.isQuiet ? venue.isQuiet.yes + 1 : venue.isQuiet.yes, - no: review.isQuiet ? venue.isQuiet.no : venue.isQuiet.no + 1 - }; - } - - if (typeof review.isSpacious !== 'undefined') { - venue.isSpacious = { - yes: review.isSpacious ? venue.isSpacious.yes + 1 : venue.isSpacious.yes, - no: review.isSpacious ? venue.isSpacious.no : venue.isSpacious.no + 1 - }; - } + // if (typeof review.hasParking !== "undefined") { + // venue.hasParking = { + // yes: review.hasParking ? venue.hasParking.yes + 1 : venue.hasParking.yes, + // no: review.hasParking ? venue.hasParking.no : venue.hasParking.no + 1, + // }; + // } + + // if (typeof review.hasSecondEntry !== "undefined") { + // venue.hasSecondEntry = { + // yes: review.hasSecondEntry + // ? venue.hasSecondEntry.yes + 1 + // : venue.hasSecondEntry.yes, + // no: review.hasSecondEntry + // ? venue.hasSecondEntry.no + // : venue.hasSecondEntry.no + 1, + // }; + // } + + // if (typeof review.hasWellLit !== "undefined") { + // venue.hasWellLit = { + // yes: review.hasWellLit ? venue.hasWellLit.yes + 1 : venue.hasWellLit.yes, + // no: review.hasWellLit ? venue.hasWellLit.no : venue.hasWellLit.no + 1, + // }; + // } + + // if (typeof review.isQuiet !== "undefined") { + // venue.isQuiet = { + // yes: review.isQuiet ? venue.isQuiet.yes + 1 : venue.isQuiet.yes, + // no: review.isQuiet ? venue.isQuiet.no : venue.isQuiet.no + 1, + // }; + // } + + // if (typeof review.isSpacious !== "undefined") { + // venue.isSpacious = { + // yes: review.isSpacious ? venue.isSpacious.yes + 1 : venue.isSpacious.yes, + // no: review.isSpacious ? venue.isSpacious.no : venue.isSpacious.no + 1, + // }; + // } venue.reviews = [...venue.reviews, review.id]; - if (typeof review.steps !== 'undefined') { + if (typeof review.steps !== "undefined") { venue.steps = { - zero: review.steps === 0 ? venue.steps.zero + 1 : venue.steps.zero, - one: review.steps === 1 ? venue.steps.one + 1 : venue.steps.one, - two: review.steps === 2 ? venue.steps.two + 1 : venue.steps.two, - moreThanTwo: - review.steps === 3 - ? venue.steps.moreThanTwo + 1 - : venue.steps.moreThanTwo + zero: review.steps ? 1 : 0, + one: review.has1Step ? 1 : 0, + two: review.has2Step ? 1 : 0, + moreThanTwo: review.has2Step ? 1 : 0, }; } - let scoring; - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('entrance', venue); - //console.log('entrance score: ', scoring); - venue.entranceScore = scoring.ratingLevel; - venue.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('interior', venue); - //console.log('interior score: ', scoring); - venue.interiorScore = scoring.ratingLevel; - venue.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel('restroom', venue); - //console.log('restroom score: ', scoring); - venue.restroomScore = scoring.ratingLevel; - venue.restroomGlyphs = scoring.ratingGlyphs; - - venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - venue.entranceScore, - venue.interiorScore, - venue.restroomScore - ); + // let scoring; + // //calculate entranceScore, glyphs + // scoring = venueReviewSummary.calculateRatingLevel("entrance", venue); + // //console.log('entrance score: ', scoring); + // venue.entranceScore = scoring.ratingLevel; + // venue.entranceGlyphs = scoring.ratingGlyphs; + + // //calculate interiorScore, glyphs + // scoring = venueReviewSummary.calculateRatingLevel("interior", venue); + // //console.log('interior score: ', scoring); + // venue.interiorScore = scoring.ratingLevel; + // venue.interiorGlyphs = scoring.ratingGlyphs; + + // //calculate restroomScore, glyphs + // scoring = venueReviewSummary.calculateRatingLevel("restroom", venue); + // //console.log('restroom score: ', scoring); + // venue.restroomScore = scoring.ratingLevel; + // venue.restroomGlyphs = scoring.ratingGlyphs; + + // venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( + // venue.entranceScore, + // venue.interiorScore, + // venue.restroomScore + // ); //console.log('venue: ', venue); @@ -549,7 +598,7 @@ module.exports = async (req, res, next) => { user: review.user, userReviewFieldsAmount: req.user.reviewFieldsAmount, userReviewsAmount: req.user.reviewsAmount, - venue: review.venue + venue: review.venue, }; return res.status(201).json(dataResponse); }; diff --git a/src/routes/reviews/validations.js b/src/routes/reviews/validations.js index 5a811de..7993a41 100644 --- a/src/routes/reviews/validations.js +++ b/src/routes/reviews/validations.js @@ -182,13 +182,6 @@ module.exports = { errors.place = 'Should be a string'; } - if (typeof data.steps !== 'undefined') { - if (typeof data.steps !== 'number') { - errors.steps = 'Should be a number'; - } else if (data.steps < 0 || data.steps > 3) { - errors.steps = 'Should be between 0 and 3'; - } - } if (data.team) { if (typeof data.team !== 'string') { diff --git a/src/routes/users/edit-user.js b/src/routes/users/edit-user.js index 56e3036..1f43af0 100644 --- a/src/routes/users/edit-user.js +++ b/src/routes/users/edit-user.js @@ -64,6 +64,7 @@ module.exports = async (req, res, next) => { user.disability = data.disability || ""; user.birthday = data.birthday || user.birthday; user.race = data.race || ""; + user.aboutMe = data.aboutMe || ""; user.firstName = data.firstName ? cleanSpaces(data.firstName) @@ -162,6 +163,7 @@ module.exports = async (req, res, next) => { showPhone: user.showPhone, username: user.username, zip: user.zip, + aboutMe:user.aboutMe }; return res.status(200).json(dataResponse); }; diff --git a/src/routes/users/get-profile.js b/src/routes/users/get-profile.js index 6e40fd4..6afc6a3 100644 --- a/src/routes/users/get-profile.js +++ b/src/routes/users/get-profile.js @@ -3,7 +3,6 @@ const { Team } = require("../../models/team"); const { User } = require("../../models/user"); module.exports = async (req, res, next) => { - console.log(req.user.teams); const getUserTeams = req.user.teams.map((t) => Team.findOne({ _id: t })); let userTeams; try { @@ -101,6 +100,7 @@ module.exports = async (req, res, next) => { birthday: req.user?.birthday, disability: req.user.disability, ranking, + aboutMe:req.user.aboutMe, }; return res.status(200).json(userData); }; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index 6f6b77d..b49cf50 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -414,10 +414,10 @@ module.exports = async (req, res, next) => { let placesResponse; try { - console.log( - "performing google search: " + - `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` - ); + // console.log( + // "performing google search: " + + // `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` + // ); placesResponse = await axios.get( `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` ); @@ -487,7 +487,7 @@ module.exports = async (req, res, next) => { placesIds.push(place.place_id); }); - console.log("calling venues"); + // console.log("calling venues"); //Use array of Google Place IDs to find AXS Venues let venues; try { @@ -498,31 +498,20 @@ module.exports = async (req, res, next) => { ); return next(err); } - console.log("venues length", venues.length); //Perform ratings logic on all returned venues venues.forEach((venue) => { - //console.log('In scoring assignment'); - let scoring; - //calculate entranceScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel("entrance", venue); - venue.entranceScore = scoring.ratingLevel; - venue.entranceGlyphs = scoring.ratingGlyphs; - - //calculate interiorScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel("interior", venue); - venue.interiorScore = scoring.ratingLevel; - venue.interiorGlyphs = scoring.ratingGlyphs; - - //calculate restroomScore, glyphs - scoring = venueReviewSummary.calculateRatingLevel("restroom", venue); - venue.restroomScore = scoring.ratingLevel; - venue.restroomGlyphs = scoring.ratingGlyphs; - - venue.mapMarkerScore = venueReviewSummary.calculateMapMarkerScore( - venue.entranceScore, - venue.interiorScore, - venue.restroomScore + const entrance = venueReviewSummary.calculateEntranceScore(venue); + venue.entranceScore = entrance; + const interior = venueReviewSummary.calculateInteriorScore(venue); + venue.interiorScore = interior; + const bathroomScore = venueReviewSummary.calculateBathroomScore(venue); + venue.restroomScore = bathroomScore; + const mapScore = venueReviewSummary.calculateMapMarkerScore( + entrance, + interior, + bathroomScore ); + venue.mapMarkerScore = mapScore; }); //Filter out, remove, Google Places that are not AXS Venues @@ -590,7 +579,6 @@ module.exports = async (req, res, next) => { // places = places.map((place) => { const venue = find(venues, (venue) => venue.placeId === place.placeId); - console.log(venue); if (venue) { return Object.assign({}, place, { //new expanded fields @@ -605,25 +593,21 @@ module.exports = async (req, res, next) => { hasLargeStall: venue.hasLargeStall, hasSupportAroundToilet: venue.hasSupportAroundToilet, hasLoweredSinks: venue.hasLoweredSinks, - - entranceScore: venue.entranceScore, entranceGlyphs: venue.entranceGlyphs, - interiorScore: venue.interiorScore, interiorGlyphs: venue.interiorGlyphs, - restroomScore: venue.restroomScore, restroomGlyphs: venue.restroomGlyphs, - mapMarkerScore: venue.mapMarkerScore, - - //original fields allowsGuideDog: venue.allowsGuideDog, - //_bathroomScore: venue.bathroomScore, - //_entryScore: venue.entryScore, hasParking: venue.hasParking, hasSecondEntry: venue.hasSecondEntry, hasWellLit: venue.hasWellLit, isQuiet: venue.isQuiet, isSpacious: venue.isSpacious, steps: venue.steps, + restroomScore: venue.restroomScore, + entranceScore: venue.entranceScore, + interiorScore: venue.interiorScore, + mapMarkerScore: venue.mapMarkerScore, + isReviewed:true }); } @@ -641,20 +625,12 @@ module.exports = async (req, res, next) => { hasLargeStall: { yes: 0, no: 0 }, hasSupportAroundToilet: { yes: 0, no: 0 }, hasLoweredSinks: { yes: 0, no: 0 }, - interiorScore: 0, interiorGlyphs: "interior", - restroomScore: 0, restroomGlyphs: "restroom", - entranceScore: 0, entranceGlyphs: "entrylg", - mapMarkerScore: 0, - //original fields + // original fields allowsGuideDog: { yes: 0, no: 0 }, - //_bathroomReviews: 0, - //_bathroomScore: null, - //_entryReviews: 0, - //_entryScore: null, hasParking: { yes: 0, no: 0 }, hasSecondEntry: { yes: 0, no: 0 }, hasWellLit: { yes: 0, no: 0 }, @@ -666,6 +642,11 @@ module.exports = async (req, res, next) => { two: 0, moreThanTwo: 0, }, + entranceScore: 0, + interiorScore: 0, + restroomScore: 0, + mapMarkerScore: 0, + isReviewed:false }); }); From 2ce71deb345ece5681c7b4974272c45d51430864 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 22 Apr 2025 21:47:20 +0500 Subject: [PATCH 19/67] template issue resolve --- src/helpers/mail-template.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/helpers/mail-template.js b/src/helpers/mail-template.js index 402e636..c14d1b2 100644 --- a/src/helpers/mail-template.js +++ b/src/helpers/mail-template.js @@ -1,4 +1,4 @@ -export const activationEmailTemplate = (link,name) => { +const activationEmailTemplate = (link,name) => { return ` @@ -50,3 +50,8 @@ export const activationEmailTemplate = (link,name) => { `; }; + + +module.exports={ + activationEmailTemplate +} \ No newline at end of file From 95c75d94f95df40254ca94e27285177d0780afb1 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 24 Apr 2025 18:10:19 +0500 Subject: [PATCH 20/67] fix signup issue --- src/routes/auth/sign-up.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 071b7e8..99ff354 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -30,11 +30,13 @@ module.exports = async (req, res, next) => { "gender", "race", ]); - data.aboutMe = cleanSpaces(data.aboutMe); + data.aboutMe = cleanSpaces(data.aboutMe ?? ''); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; + console.log('replacing error') + let activationTicket; try { activationTicket = await ActivationTicket.findOne({ email: data.email }); From e43434c2e8747d518004a0801780eae5a9c0f938 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 25 Apr 2025 16:15:52 +0500 Subject: [PATCH 21/67] add validation for sign up --- src/helpers/constants.js | 275 +++++++++++++++------------- src/routes/auth/activate-account.js | 27 +-- src/routes/auth/sign-up.js | 10 +- src/routes/auth/validations.js | 133 ++++++++------ 4 files changed, 243 insertions(+), 202 deletions(-) diff --git a/src/helpers/constants.js b/src/helpers/constants.js index 72f82c7..e250834 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -1,129 +1,156 @@ module.exports = { - languages: ['en', 'es'], + languages: ["en", "es"], placesTypes: [ - 'accounting', - 'airport', - 'amusement_park', - 'aquarium', - 'art_gallery', - 'atm', - 'bakery', - 'bank', - 'bar', - 'beauty_salon', - 'bicycle_store', - 'book_store', - 'bowling_alley', - 'bus_station', - 'cafe', - 'campground', - 'car_dealer', - 'car_rental', - 'car_repair', - 'car_wash', - 'casino', - 'cemetery', - 'church', - 'city_hall', - 'clothing_store', - 'convenience_store', - 'courthouse', - 'dentist', - 'department_store', - 'doctor', - 'electrician', - 'electronics_store', - 'embassy', - 'establishment', - 'fire_station', - 'florist', - 'funeral_home', - 'furniture_store', - 'gas_station', - 'gym', - 'hair_care', - 'hardware_store', - 'hindu_temple', - 'home_goods_store', - 'hospital', - 'insurance_agency', - 'jewelry_store', - 'laundry', - 'lawyer', - 'library', - 'liquor_store', - 'local_government_office', - 'locksmith', - 'lodging', - 'meal_delivery', - 'meal_takeaway', - 'mosque', - 'movie_rental', - 'movie_theater', - 'moving_company', - 'museum', - 'night_club', - 'painter', - 'park', - 'parking', - 'pet_store', - 'pharmacy', - 'physiotherapist', - 'plumber', - 'police', - 'post_office', - 'real_estate_agency', - 'restaurant', - 'roofing_contractor', - 'rv_park', - 'school', - 'shoe_store', - 'shopping_mall', - 'spa', - 'stadium', - 'storage', - 'store', - 'subway_station', - 'synagogue', - 'taxi_stand', - 'train_station', - 'transit_station', - 'travel_agency', - 'university', - 'veterinary_care', - 'zoo' + "accounting", + "airport", + "amusement_park", + "aquarium", + "art_gallery", + "atm", + "bakery", + "bank", + "bar", + "beauty_salon", + "bicycle_store", + "book_store", + "bowling_alley", + "bus_station", + "cafe", + "campground", + "car_dealer", + "car_rental", + "car_repair", + "car_wash", + "casino", + "cemetery", + "church", + "city_hall", + "clothing_store", + "convenience_store", + "courthouse", + "dentist", + "department_store", + "doctor", + "electrician", + "electronics_store", + "embassy", + "establishment", + "fire_station", + "florist", + "funeral_home", + "furniture_store", + "gas_station", + "gym", + "hair_care", + "hardware_store", + "hindu_temple", + "home_goods_store", + "hospital", + "insurance_agency", + "jewelry_store", + "laundry", + "lawyer", + "library", + "liquor_store", + "local_government_office", + "locksmith", + "lodging", + "meal_delivery", + "meal_takeaway", + "mosque", + "movie_rental", + "movie_theater", + "moving_company", + "museum", + "night_club", + "painter", + "park", + "parking", + "pet_store", + "pharmacy", + "physiotherapist", + "plumber", + "police", + "post_office", + "real_estate_agency", + "restaurant", + "roofing_contractor", + "rv_park", + "school", + "shoe_store", + "shopping_mall", + "spa", + "stadium", + "storage", + "store", + "subway_station", + "synagogue", + "taxi_stand", + "train_station", + "transit_station", + "travel_agency", + "university", + "veterinary_care", + "zoo", ], directionsTypes: [ - 'administrative_area_level_1', - 'administrative_area_level_2', - 'administrative_area_level_3', - 'administrative_area_level_4', - 'administrative_area_level_5', - 'colloquial_area', - 'country', - 'finance', - 'floor', - 'geocode', - 'intersection', - 'locality', - 'natural_feature', - 'neighborhood', - 'place_of_worship', - 'political', - 'postal_code', - 'postal_code_prefix', - 'postal_code_suffix', - 'postal_town', - 'premise', - 'route', - 'street_address', - 'street_number', - 'sublocality', - 'sublocality_level_5', - 'sublocality_level_4', - 'sublocality_level_3', - 'sublocality_level_2', - 'sublocality_level_1', - 'subpremise' - ] + "administrative_area_level_1", + "administrative_area_level_2", + "administrative_area_level_3", + "administrative_area_level_4", + "administrative_area_level_5", + "colloquial_area", + "country", + "finance", + "floor", + "geocode", + "intersection", + "locality", + "natural_feature", + "neighborhood", + "place_of_worship", + "political", + "postal_code", + "postal_code_prefix", + "postal_code_suffix", + "postal_town", + "premise", + "route", + "street_address", + "street_number", + "sublocality", + "sublocality_level_5", + "sublocality_level_4", + "sublocality_level_3", + "sublocality_level_2", + "sublocality_level_1", + "subpremise", + ], + disability: [ + "yes", "No", "not-to-say", "" + ], + genders: [ + "female", + "male", + "other", + "private", + "transgender", + "non-binary", + "gender-fluid", + "agender", + "not-to-say", + ], + race: [ + "black/african american", + "caucasian", + "indigenous/first nation/native american", + "latino/hispanic", + "middle eastern/north african", + "native hawaiian/pacific islander", + "biracial/multiracial", + "asian", + "non-naucasian", + "not-to-disclose", + "", + ], }; diff --git a/src/routes/auth/activate-account.js b/src/routes/auth/activate-account.js index 798c29d..6a18acd 100644 --- a/src/routes/auth/activate-account.js +++ b/src/routes/auth/activate-account.js @@ -18,10 +18,6 @@ module.exports = async (req, res, next) => { if (err.name === "CastError") { return res.status(404).json({ general: "Activation ticket not found" }); } - - console.log( - `Activation ticket with key ${key} failed to be found at activate-account.` - ); return next(err); } @@ -35,20 +31,27 @@ module.exports = async (req, res, next) => { try { await ActivationTicket.deleteOne({ key }); } catch (err) { - console.log( - `Activation ticket with key ${ - activationTicket.key - } failed to be deleted at activate-account.` - ); return next(err); } return res.status(400).json({ general: "Activation ticket expired" }); } - const userData = Object.assign({}, activationTicket.userData, { - email: activationTicket.email, - }); + const userData = { + firstName: activationTicket?.userData?.firstName, + isSubscribed: activationTicket?.userData?.isSubscribed, + lastName: activationTicket?.userData?.lastName, + password: activationTicket?.userData?.password, + username: activationTicket?.userData?.username, + aboutMe: activationTicket?.userData?.aboutMe || '', + dateOfBirth: activationTicket?.userData?.dateOfBirth || null, + disability: activationTicket?.userData?.disability || '', + gender: activationTicket?.userData?.gender || 'not-to-say', + race: activationTicket?.userData?.race || '', + email: activationTicket?.email, + }; + + console.log(userData); let repeatedUsers; try { diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 99ff354..72b997a 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -30,12 +30,12 @@ module.exports = async (req, res, next) => { "gender", "race", ]); - data.aboutMe = cleanSpaces(data.aboutMe ?? ''); + data.aboutMe = cleanSpaces(data.aboutMe ?? ""); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; - console.log('replacing error') + console.log(data) let activationTicket; try { @@ -127,7 +127,7 @@ module.exports = async (req, res, next) => { dateOfBirth: data.dateOfBirth || null, disability: data.disability || null, gender: data.gender || null, - race: data.race || null, + race: data?.race || '', }, }; try { @@ -162,11 +162,11 @@ module.exports = async (req, res, next) => { `; const receiversEmails = [activationTicket.email]; const activationLink = `https://axsmap.com/auth/activate-account/${activationTicket.key}`; - const name = `${(activationTicket?.userData?.firstName ?? '')} ${(activationTicket?.userData?.lastName?? '')}`; + const name = `${activationTicket?.userData?.firstName ?? ""} ${activationTicket?.userData?.lastName ?? ""}`; sendEmail({ subject, - htmlContent:activationEmailTemplate(activationLink,name), + htmlContent: activationEmailTemplate(activationLink, name), textContent, receiversEmails, }); diff --git a/src/routes/auth/validations.js b/src/routes/auth/validations.js index 451b3b7..872db78 100644 --- a/src/routes/auth/validations.js +++ b/src/routes/auth/validations.js @@ -1,17 +1,19 @@ -const freemail = require('freemail'); -const { isEmail } = require('validator'); -const { isEmpty } = require('lodash'); +const freemail = require("freemail"); +const { isEmail } = require("validator"); +const { isEmpty } = require("lodash"); -const { cleanSpaces } = require('../../helpers'); +const { cleanSpaces } = require("../../helpers"); + +const { disability, race, genders } = require("../../helpers/constants"); module.exports = { validateFacebookSignIn(data) { const errors = {}; if (!data.code) { - errors.code = 'Is required'; - } else if (typeof data.code !== 'string') { - errors.code = 'Should be a string'; + errors.code = "Is required"; + } else if (typeof data.code !== "string") { + errors.code = "Should be a string"; } return { errors, isValid: isEmpty(errors) }; @@ -20,11 +22,11 @@ module.exports = { const errors = {}; if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; + errors.email = "Is required"; + } else if (typeof data.email !== "string") { + errors.email = "Should be a string"; } else if (!isEmail(data.email)) { - errors.email = 'Should be a valid email'; + errors.email = "Should be a valid email"; } return { errors, isValid: isEmpty(errors) }; @@ -33,9 +35,9 @@ module.exports = { const errors = {}; if (!data.key) { - errors.key = 'Is required'; - } else if (typeof data.key !== 'string') { - errors.key = 'Should be a string'; + errors.key = "Is required"; + } else if (typeof data.key !== "string") { + errors.key = "Should be a string"; } return { errors, isValid: isEmpty(errors) }; @@ -44,9 +46,9 @@ module.exports = { const errors = {}; if (!data.code) { - errors.code = 'Is required'; - } else if (typeof data.code !== 'string') { - errors.code = 'Should be a string'; + errors.code = "Is required"; + } else if (typeof data.code !== "string") { + errors.code = "Should be a string"; } return { errors, isValid: isEmpty(errors) }; @@ -55,19 +57,19 @@ module.exports = { const errors = {}; if (!data.key) { - errors.key = 'Is required'; - } else if (typeof data.key !== 'string') { - errors.key = 'Should be a string'; + errors.key = "Is required"; + } else if (typeof data.key !== "string") { + errors.key = "Should be a string"; } if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; + errors.password = "Is required"; + } else if (typeof data.password !== "string") { + errors.password = "Should be a string"; } else if (data.password.length < 8) { - errors.password = 'Should have more than 7 characters'; + errors.password = "Should have more than 7 characters"; } else if (data.password.length > 30) { - errors.password = 'Should have less than 31 characters'; + errors.password = "Should have less than 31 characters"; } return { errors, isValid: isEmpty(errors) }; @@ -76,15 +78,15 @@ module.exports = { const errors = {}; if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; + errors.email = "Is required"; + } else if (typeof data.email !== "string") { + errors.email = "Should be a string"; } if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; + errors.password = "Is required"; + } else if (typeof data.password !== "string") { + errors.password = "Should be a string"; } return { errors, isValid: isEmpty(errors) }; @@ -93,64 +95,73 @@ module.exports = { const errors = {}; if (!data.email) { - errors.email = 'Is required'; - } else if (typeof data.email !== 'string') { - errors.email = 'Should be a string'; + errors.email = "Is required"; + } else if (typeof data.email !== "string") { + errors.email = "Should be a string"; } else if (cleanSpaces(data.email).length > 254) { - errors.email = 'Should have less than 255 characters'; + errors.email = "Should have less than 255 characters"; } else if (!isEmail(data.email) || freemail.isDisposable(data.email)) { - errors.email = 'Should be a valid email'; + errors.email = "Should be a valid email"; } if (!data.firstName) { - errors.firstName = 'Is required'; - } else if (typeof data.firstName !== 'string') { - errors.firstName = 'Should be a string'; + errors.firstName = "Is required"; + } else if (typeof data.firstName !== "string") { + errors.firstName = "Should be a string"; } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.firstName)) { - errors.firstName = 'Should only have letters'; + errors.firstName = "Should only have letters"; } else if (cleanSpaces(data.firstName).length > 24) { - errors.firstName = 'Should have less than 25 characters'; + errors.firstName = "Should have less than 25 characters"; } else { const firstName = cleanSpaces(data.firstName); - if (firstName.split(' ').length > 1) { - errors.firstName = 'Should only be one name'; + if (firstName.split(" ").length > 1) { + errors.firstName = "Should only be one name"; } } - if (typeof data.isSubscribed === 'undefined') { - errors.isSubscribed = 'Is required'; - } else if (typeof data.isSubscribed !== 'boolean') { - errors.isSubscribed = 'Should be a boolean'; + if (typeof data.isSubscribed === "undefined") { + errors.isSubscribed = "Is required"; + } else if (typeof data.isSubscribed !== "boolean") { + errors.isSubscribed = "Should be a boolean"; } if (!data.lastName) { - errors.lastName = 'Is required'; - } else if (typeof data.lastName !== 'string') { - errors.lastName = 'Should be a string'; + errors.lastName = "Is required"; + } else if (typeof data.lastName !== "string") { + errors.lastName = "Should be a string"; } else if (/[~`!#$%^&*+=\-[\]\\';,./{}|\\":<>?\d]/g.test(data.lastName)) { - errors.lastName = 'Should only have letters'; + errors.lastName = "Should only have letters"; } else if (cleanSpaces(data.lastName).length > 36) { - errors.lastName = 'Should have less than 37 characters'; + errors.lastName = "Should have less than 37 characters"; } else { const lastName = cleanSpaces(data.lastName); - if (lastName.split(' ').length > 1) { - errors.lastName = 'Should only be one surname'; + if (lastName.split(" ").length > 1) { + errors.lastName = "Should only be one surname"; } } if (!data.password) { - errors.password = 'Is required'; - } else if (typeof data.password !== 'string') { - errors.password = 'Should be a string'; + errors.password = "Is required"; + } else if (typeof data.password !== "string") { + errors.password = "Should be a string"; } else if (data.password.length < 8) { - errors.password = 'Should have more than 7 characters'; + errors.password = "Should have more than 7 characters"; } else if (data.password.length > 30) { - errors.password = 'Should have less than 31 characters'; + errors.password = "Should have less than 31 characters"; + } + + if (data.disability && !disability.includes(data.disability)) { + errors.disability = "Please select a valid disability option"; + } + if (data.gender && !genders.includes(data.gender)) { + errors.gender = "Please select a valid gender option"; + } + if (data.race && !race.includes(data.race)) { + errors.race = "Please select a valid race option"; } - return { errors, isValid: isEmpty(errors) }; - } + }, }; From 140f1ad49765331d523d6edf10860ed5998746f6 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 29 Apr 2025 15:28:27 +0500 Subject: [PATCH 22/67] join mapathon changrd --- src/routes/events/join-event.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/events/join-event.js b/src/routes/events/join-event.js index 3248f3a..9398f53 100644 --- a/src/routes/events/join-event.js +++ b/src/routes/events/join-event.js @@ -36,7 +36,7 @@ module.exports = async (req, res, next) => { .json({ general: "You already are a participant in this event" }); } - if (event.isOpen) { + if (true || event.isOpen) { req.user.events = [...req.user.events, event.id]; req.user.updatedAt = moment.utc().toDate(); From 02898d44f62d34d7be1b3cb7ceadb10d6662e292 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 29 Apr 2025 15:34:08 +0500 Subject: [PATCH 23/67] join mapathon flow change --- src/routes/events/join-event.js | 46 +++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/routes/events/join-event.js b/src/routes/events/join-event.js index 9398f53..39d07ff 100644 --- a/src/routes/events/join-event.js +++ b/src/routes/events/join-event.js @@ -22,6 +22,14 @@ module.exports = async (req, res, next) => { return res.status(404).json({ general: "Event not found" }); } + const endDate = moment(event.endDate).utc(); + const today = moment.utc(); + if (endDate.isBefore(today)) { + return res + .status(423) + .json({ general: "This event has already finished" }); + } + const eventParticipants = event.participants.map((p) => p.toString()); if (eventParticipants.includes(req.user.id)) { return res @@ -35,27 +43,33 @@ module.exports = async (req, res, next) => { .status(400) .json({ general: "You already are a participant in this event" }); } + req.user.events = [...req.user.events, event.id]; + req.user.updatedAt = moment.utc().toDate(); + + try { + await req.user.save(); + } catch (err) { + console.log(`User ${req.user.id} failed to be updated at join-event`); + return next(err); + } + + event.participants = [...event.participants, req.user.id]; + event.updatedAt = moment.utc().toDate(); + + try { + await event.save(); + } catch (err) { + console.log(`Event ${event.id} failed to be updated at join-event`); + return next(err); + } + + return res.status(200).json({ general: "Joined" }); if (true || event.isOpen) { req.user.events = [...req.user.events, event.id]; req.user.updatedAt = moment.utc().toDate(); - try { - await req.user.save(); - } catch (err) { - console.log(`User ${req.user.id} failed to be updated at join-event`); - return next(err); - } - - event.participants = [...event.participants, req.user.id]; - event.updatedAt = moment.utc().toDate(); - - try { - await event.save(); - } catch (err) { - console.log(`Event ${event.id} failed to be updated at join-event`); - return next(err); - } + return res.status(200).json({ general: "Joined" }); } else { From ffa4e717aa5b78111454d4611480cc09b81a73b6 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 29 Apr 2025 15:51:11 +0500 Subject: [PATCH 24/67] change join mapathon flow --- src/routes/events/join-event.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/routes/events/join-event.js b/src/routes/events/join-event.js index 39d07ff..6251641 100644 --- a/src/routes/events/join-event.js +++ b/src/routes/events/join-event.js @@ -13,8 +13,6 @@ module.exports = async (req, res, next) => { if (err.name === "CastError") { return res.status(404).json({ general: "Event not found" }); } - - console.log(`Event ${eventId} failed to be found at join-event`); return next(err); } @@ -24,6 +22,7 @@ module.exports = async (req, res, next) => { const endDate = moment(event.endDate).utc(); const today = moment.utc(); + if (endDate.isBefore(today)) { return res .status(423) @@ -43,26 +42,28 @@ module.exports = async (req, res, next) => { .status(400) .json({ general: "You already are a participant in this event" }); } - req.user.events = [...req.user.events, event.id]; - req.user.updatedAt = moment.utc().toDate(); + + event.participants = [...event.participants, req.user.id]; + event.updatedAt = moment.utc().toDate(); try { - await req.user.save(); + await event.save(); } catch (err) { - console.log(`User ${req.user.id} failed to be updated at join-event`); + console.log(`Event ${event.id} failed to be updated at join-event`); return next(err); } - event.participants = [...event.participants, req.user.id]; - event.updatedAt = moment.utc().toDate(); + req.user.events = [...req.user.events, event.id]; + req.user.updatedAt = moment.utc().toDate(); try { - await event.save(); + await req.user.save(); } catch (err) { - console.log(`Event ${event.id} failed to be updated at join-event`); + console.log(`User ${req.user.id} failed to be updated at join-event`); return next(err); } + return res.status(200).json({ general: "Joined" }); if (true || event.isOpen) { From fb5f6ec4af417e25bb6bb5628af35738120165e1 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 1 May 2025 16:29:04 +0500 Subject: [PATCH 25/67] reset-password issue resolve --- src/models/user.js | 2 +- src/models/venue.js | 10 ++++++++++ src/routes/auth/activate-account.js | 1 - src/routes/auth/reset-password.js | 11 +++++------ src/routes/reviews/create-review.js | 5 ++++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/models/user.js b/src/models/user.js index 3d5471b..a34e386 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -245,7 +245,7 @@ function hashPassword(password) { } function comparePassword(password) { - return bcrypt.compareSync(password, this.hashedPassword); + return bcrypt.compareSync(password, this.hashedPassword ?? ''); } userSchema.virtual("password").set(hashPassword); diff --git a/src/models/venue.js b/src/models/venue.js index aebf58b..c629761 100644 --- a/src/models/venue.js +++ b/src/models/venue.js @@ -13,6 +13,16 @@ const venueSchema = new mongoose.Schema( default: 0 } }, + hasWheelchairParking: { + yes: { + type: Number, + default: 0 + }, + no: { + type: Number, + default: 0 + } + }, brightLightTitle: { yes: { type: Number, diff --git a/src/routes/auth/activate-account.js b/src/routes/auth/activate-account.js index 6a18acd..4ad8407 100644 --- a/src/routes/auth/activate-account.js +++ b/src/routes/auth/activate-account.js @@ -51,7 +51,6 @@ module.exports = async (req, res, next) => { email: activationTicket?.email, }; - console.log(userData); let repeatedUsers; try { diff --git a/src/routes/auth/reset-password.js b/src/routes/auth/reset-password.js index 5eb1f6f..c1250b4 100644 --- a/src/routes/auth/reset-password.js +++ b/src/routes/auth/reset-password.js @@ -28,7 +28,6 @@ module.exports = async (req, res, next) => { if (!passwordTicket) { return res.status(404).json({ general: "Password Ticket not found" }); } - const expiresAt = moment(passwordTicket.expiresAt).utc(); const today = moment.utc(); if (expiresAt.isBefore(today)) { @@ -45,7 +44,6 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: "Password Ticket expired" }); } - let user; try { user = await User.findOne({ @@ -75,10 +73,11 @@ module.exports = async (req, res, next) => { return res.status(400).json({ general: "User not found" }); } - - const passwordMatches = user.comparePassword(password); - if (passwordMatches) { - return res.status(400).json({ password: "Is already used" }); + if (user?.hashedPassword) { + const passwordMatches = user.comparePassword(password); + if (passwordMatches) { + return res.status(400).json({ password: "Is already used" }); + } } user.password = password; diff --git a/src/routes/reviews/create-review.js b/src/routes/reviews/create-review.js index 2399513..211c6ba 100644 --- a/src/routes/reviews/create-review.js +++ b/src/routes/reviews/create-review.js @@ -31,8 +31,9 @@ module.exports = async (req, res, next) => { hasSecondEntry: req.body.hasSecondEntry, hasPermanentRamp: req.body.hasPermanentRamp, hasLoweredSinks: req.body.hasLoweredSinks, + hasPortableRamp: req.body.hasPortableRamp, + hasWheelchairParking:req.body.hasWheelchairParking, - // hasPortableRamp: req.body.hasPortableRamp, // hasAccessibleTableHeight: req.body.hasAccessibleTableHeight, // hasInteriorRamp: req.body.hasInteriorRamp, // hasSwingOutDoor: req.body.hasSwingOutDoor, @@ -303,6 +304,8 @@ module.exports = async (req, res, next) => { "hasSecondEntry", "hasPermanentRamp", "hasLoweredSinks", + "hasWheelchairParking", + "hasPortableRamp", ]; keys.forEach((key) => { From b21d256ccf2cf72766c534b455a91fe4fba38d0d Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 7 May 2025 11:46:03 +0500 Subject: [PATCH 26/67] feat: venue detail api --- src/routes/venues/index.js | 2 + src/routes/venues/venue-details.js | 65 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/routes/venues/venue-details.js diff --git a/src/routes/venues/index.js b/src/routes/venues/index.js index a66f887..0675f4d 100644 --- a/src/routes/venues/index.js +++ b/src/routes/venues/index.js @@ -5,11 +5,13 @@ const { isAuthenticated } = require("../../helpers"); const archiveVenue = require("./archive-venue"); const getVenue = require("./get-venue"); const listVenues = require("./list-venues"); +const venuDetails = require("./venue-details"); const router = new express.Router(); router.get("", isAuthenticated({ isOptional: true }), listVenues); router.get("/:placeId", getVenue); +router.get("/detail/:placeId", venuDetails); router.put( "/:venueId/archive", isAuthenticated({ isOptional: false }), diff --git a/src/routes/venues/venue-details.js b/src/routes/venues/venue-details.js new file mode 100644 index 0000000..cf35bea --- /dev/null +++ b/src/routes/venues/venue-details.js @@ -0,0 +1,65 @@ +const axios = require("axios"); +const { Venue } = require("../../models/venue"); +const { Review } = require("../../models/review"); + +module.exports = async (req, res, next) => { + const placeId = req.params.placeId; + + try { + const venue = await Venue.findOne({ + placeId, + }); + let customReviews; + if (venue) { + customReviews = await Review.aggregate([ + { + $match: { venue: venue._id }, + }, + { + $lookup: { + from: "users", + localField: "user", + foreignField: "_id", + as: "user", + }, + }, + { $unwind: "$user" }, + { + $project: { + _id: 1, + comments: { $ifNull: ["$comments", null] }, + firstName: { $ifNull: ["$user.firstName", null] }, + lastName: { $ifNull: ["$user.lastName", null] }, + avatar: { $ifNull: ["$user.avatar", null] }, + createdAt: 1, + }, + }, + ]); + } + const googleResponse = await axios.get( + "https://maps.googleapis.com/maps/api/place/details/json", + { + params: { + place_id: placeId, + fields: + "name,photos,international_phone_number,rating,reviews,formatted_address,geometry,user_ratings_total,rating,opening_hours,website", + key: process.env.PLACES_API_KEY, + }, + } + ); + + const googleData = googleResponse.data.result; + + if (!googleData) { + return res + .status(404) + .json({ message: "Google venue details not found." }); + } + res.json({ + data: { googleData, axsReviews: customReviews }, + }); + } catch (err) { + console.log(`Place ${placeId} failed to be found at get-venue.`); + return next(err); + } +}; From 91aa160b98fb7a889932bf22cfae22969702db82 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 8 May 2025 11:16:19 +0500 Subject: [PATCH 27/67] feat: google login --- src/routes/auth/google-sign-in.js | 217 +++++++----------------------- 1 file changed, 52 insertions(+), 165 deletions(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 63f7106..5c9e981 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -2,7 +2,7 @@ const crypto = require("crypto"); const querystring = require("querystring"); const axios = require("axios"); -const GoogleAuth = require("google-auth-library"); +const { OAuth2Client } = require("google-auth-library"); const jwt = require("jsonwebtoken"); const moment = require("moment"); const randomstring = require("randomstring"); @@ -13,177 +13,64 @@ const { User } = require("../../models/user"); const { validateGoogleSignIn } = require("./validations"); -module.exports = async (req, res, next) => { +const CLIENT_ID = process.env.GOOGLE_CLIENT_ID; +const CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET; +const REDIRECT_URI = process.env.GOOGLE_REDIRECT_URI; + +module.exports = async (req, res) => { const { errors, isValid } = validateGoogleSignIn(req.body); if (!isValid) { return res.status(400).json(errors); } const code = req.body.code; - - const getTokenUrl = "https://www.googleapis.com/oauth2/v4/token"; - const getTokenParams = { - code, - client_id: process.env.GOOGLE_CLIENT_ID, - client_secret: process.env.GOOGLE_CLIENT_SECRET, - redirect_uri: `${process.env.APP_URL}/auth/google`, - grant_type: "authorization_code", - }; - let getTokenResponse; + const oauth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI); try { - getTokenResponse = await axios.post( - getTokenUrl, - querystring.stringify(getTokenParams) - ); - } catch (err) { - console.error(err); - return res.status(400).json({ general: "Invalid code" }); - } - - const auth = new GoogleAuth(); - const client = new auth.OAuth2(process.env.GOOGLE_CLIENT_ID, "", ""); - const idToken = getTokenResponse.data.id_token; - client.verifyIdToken( - idToken, - process.env.GOOGLE_CLIENT_ID, - async (err, login) => { - if (err) { - return res.status(400).json({ general: "Invalid token id" }); - } - - const payload = login.getPayload(); - - const email = payload.email; - const googleId = payload.sub; - let user; - try { - user = await User.findOne({ - $or: [{ email }, { googleId }], - isArchived: false, - }); - } catch (err) { - console.log( - `User with googleId ${googleId} and email ${email} failed to be found at google-sign-in.` - ); - return next(err); - } - - let refreshToken; - - if (!user) { - const userData = { - email: payload.email, - googleId: payload.sub, - firstName: payload.given_name, - lastName: payload.family_name, - }; - - if (payload.locale === "en") { - userData.language = "en"; - } else if (payload.locale === "es") { - userData.language = "es"; - } - - if (payload.picture) { - userData.avatar = payload.picture; - } - - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}`; - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - username: userData.username, - isArchived: false, - }); - } catch (err) { - console.log("Users failed to be found at google-sign-in."); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: "lowercase", - })}`; - - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false, - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at google-sign-in.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } - - try { - user = await User.create(userData); - } catch (err) { - console.log( - `User failed to be created at google-sign-in.\nData: ${JSON.stringify( - userData - )}` - ); - return next(err); - } - - const today = moment.utc(); - const expiresAt = today.add(30, "days").toDate(); - const refreshTokenData = { - expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString("hex")}`, - userId: user.id, - }; - - try { - refreshToken = await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token failed to be created at google-sign-in.\nData: ${JSON.stringify( - refreshTokenData - )}` - ); - return next(err); - } - } else { - const userId = user.id; - const today = moment.utc(); - const expiresAt = today.add(30, "days").toDate(); - const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; - - try { - refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - } catch (err) { - console.log( - `Refresh Token for userId ${userId} failed to be created or updated at google-sign-in.` - ); - return next(err); - } - } - - const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600, + const { tokens } = await oauth2Client.getToken(code); + oauth2Client.setCredentials(tokens); + const ticket = await oauth2Client.verifyIdToken({ + idToken: tokens.id_token, + audience: CLIENT_ID, + }); + + const payload = ticket.getPayload(); + const { sub: googleId, email, name, picture } = payload; + + const [firstName, lastName] = name.split(" "); + + let user = await User.findOne({ email }); + if (!user) { + user = new User({ + email: email, + firstName: firstName || name, + lastName: lastName || "", + createdAt: new Date(), }); - refreshToken = refreshToken.key; - - return res.status(200).json({ token, refreshToken }); + await user.save(); } - ); + const key = `${user._id}${crypto.randomBytes(28).toString("hex")}`; + + const refreshToken = randomstring.generate(80); + const expiryDate = moment().add(30, "days").toDate(); + + await RefreshToken.create({ + userId: user._id, + key, + token: refreshToken, + expiresAt: expiryDate, + }); + + return res.json({ + success: true, + refreshToken, + user: { + id: user._id, + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + }, + }); + } catch (err) { + return res.status(401).json({ error: "Invalid ID token" }); + } }; From d329521ccf11b22d46d27b0047c4401bff12d408 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 8 May 2025 16:54:11 +0500 Subject: [PATCH 28/67] chore: venue detail photo fix --- src/routes/venues/venue-details.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/routes/venues/venue-details.js b/src/routes/venues/venue-details.js index cf35bea..0178765 100644 --- a/src/routes/venues/venue-details.js +++ b/src/routes/venues/venue-details.js @@ -10,6 +10,8 @@ module.exports = async (req, res, next) => { placeId, }); let customReviews; + // console.log("venue", venue); + if (venue) { customReviews = await Review.aggregate([ { @@ -47,8 +49,16 @@ module.exports = async (req, res, next) => { }, } ); - - const googleData = googleResponse.data.result; + let photo; + if (googleResponse.data.result.photos) { + photo = `https://maps.googleapis.com/maps/api/place/photo?key=${ + process.env.PLACES_API_KEY + }&maxwidth=300&photoreference=${googleResponse.data.result.photos[0].photo_reference}`; + } + const googleData = { + ...googleResponse.data.result, + photo, + }; if (!googleData) { return res From 16c97a3589a49175f03d564091d13fbd1b2cf8a7 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 8 May 2025 16:54:23 +0500 Subject: [PATCH 29/67] chore: token fixed --- src/routes/auth/google-sign-in.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 5c9e981..8ccd0f0 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -51,17 +51,21 @@ module.exports = async (req, res) => { const key = `${user._id}${crypto.randomBytes(28).toString("hex")}`; const refreshToken = randomstring.generate(80); + const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { + expiresIn: "30d", + }); const expiryDate = moment().add(30, "days").toDate(); await RefreshToken.create({ userId: user._id, key, - token: refreshToken, + token: token, expiresAt: expiryDate, }); return res.json({ success: true, + token, refreshToken, user: { id: user._id, From f032b0c5ffed9ab951ac4b0a435a3efb869fb54a Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 8 May 2025 18:16:01 +0500 Subject: [PATCH 30/67] chore: login with facebook --- src/routes/auth/facebook-sign-in.js | 200 +++++----------------------- src/routes/auth/google-sign-in.js | 28 ++-- 2 files changed, 45 insertions(+), 183 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 3a06a1a..e12fe2a 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -18,184 +18,52 @@ module.exports = async (req, res, next) => { } const code = req.body.code; - - const getTokenUrl = "https://graph.facebook.com/v2.10/oauth/access_token"; - const getTokenParams = { - code, - client_id: process.env.FACEBOOK_CLIENT_ID, - client_secret: process.env.FACEBOOK_CLIENT_SECRET, - redirect_uri: `${process.env.APP_URL}/auth/facebook`, - }; - let getTokenResponse; - try { - getTokenResponse = await axios.get(getTokenUrl, { params: getTokenParams }); - } catch (err) { - console.err(err); - return res.status(400).json({ general: "Invalid code" }); - } - - const facebookToken = getTokenResponse.data.access_token; - - const getProfileUrl = - "https://graph.facebook.com/v2.10/me?fields=id,email,first_name,last_name,locale"; - const getProfileOptions = { - params: { - access_token: facebookToken, - }, - }; - let getProfileResponse; - try { - getProfileResponse = await axios.get(getProfileUrl, getProfileOptions); - } catch (err) { - console.log("Profile data failed to be found at facebook-sign-in."); - return next(err); - } - - const email = getProfileResponse.data.email - ? getProfileResponse.data.email - : ""; - const facebookId = getProfileResponse.data.id; - let user; try { - user = await User.findOne({ - $or: [{ email }, { facebookId }], - isArchived: false, + const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { + params: { + access_token: code, + fields: "id,name,email,picture", + }, }); - } catch (err) { - console.log( - `User with facebookId ${facebookId} and email ${email} failed to be found at facebook-sign-in.` - ); - return next(err); - } - - let accessToken; - let refreshToken; - - if (!user) { - console.log(getProfileResponse.data); - const userData = { - email: getProfileResponse.data.email ? getProfileResponse.data.email : "", - facebookId: getProfileResponse.data.id, - firstName: getProfileResponse.data.first_name, - lastName: getProfileResponse.data.last_name, - }; - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}`; - - let repeatedUsers; - try { - repeatedUsers = await User.find({ - username: userData.username, - isArchived: false, - }); - } catch (err) { - console.log("Users failed to be found at facebook-sign-in."); - return next(err); - } - - if (repeatedUsers && repeatedUsers.length > 0) { - let repeatedUser; - do { - userData.username = `${slugify(userData.firstName)}-${slugify( - userData.lastName - )}-${randomstring.generate({ - length: 5, - capitalization: "lowercase", - })}`; - try { - repeatedUser = await User.findOne({ - username: userData.username, - isArchived: false, - }); - } catch (err) { - console.log( - `User with username ${ - userData.username - } failed to be found at facebook-sign-in.` - ); - return next(err); - } - } while (repeatedUser && repeatedUser.username === userData.username); - } + const fbUser = fbUserResponse.data; - const getPictureUrl = `https://graph.facebook.com/v2.10/${ - userData.facebookId - }/picture`; - const getPictureOptions = { - params: { - access_token: accessToken, - redirect: false, - type: "large", - }, - }; - let getPictureResponse; - try { - getPictureResponse = await axios.get(getPictureUrl, getPictureOptions); - } catch (err) { - console.log("User picture failed to be found at facebook-sign-in."); - return next(err); - } + const email = fbUser.email || "No email available"; - const isSilhouette = getPictureResponse.data.data.is_silhouette; - if (!isSilhouette) { - userData.avatar = getPictureResponse.data.data.url; - } + let user = await User.findOne({ facebookId: fbUser.id }); - try { - user = await User.create(userData); - } catch (err) { - console.log( - `User failed to be created at facebook-sign-in.\nData: ${JSON.stringify( - userData - )}` - ); - return next(err); - } + const [firstName, lastName] = fbUser.name.split(" "); - const today = moment.utc(); - const expiresAt = today.add(30, "days").toDate(); - const refreshTokenData = { - expiresAt, - key: `${user.id}${crypto.randomBytes(28).toString("hex")}`, - userId: user.id, - }; + if (!user) { + user = new User({ + fbId: fbUser.id, + email, + firstName: firstName || "", + lastName: lastName || "", + picture: fbUser.picture.data.url, + }); - try { - refreshToken = await RefreshToken.create(refreshTokenData); - } catch (err) { - console.log( - `Refresh token failed to be created at facebook-sign-in.\nData: ${JSON.stringify( - refreshTokenData - )}` - ); - return next(err); + await user.save(); } - } else { - const userId = user.id; + const userId = user._id; const today = moment.utc(); const expiresAt = today.add(30, "days").toDate(); const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; - try { - refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - } catch (err) { - console.log( - `Refresh Token for userId ${userId} failed to be created or updated at facebook-sign-in.` - ); - return next(err); - } - } - - const token = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { - expiresIn: 3600, - }); - refreshToken = refreshToken.key; + let refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { + expiresIn: "30d", + }); - return res.status(200).json({ token, refreshToken }); + res.json({ + refreshToken: refreshToken.key, + token, + }); + } catch (err) { + res.status(401).json({ success: false, error: "Invalid Facebook token" }); + } }; diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 8ccd0f0..17e86ac 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -48,31 +48,25 @@ module.exports = async (req, res) => { }); await user.save(); } - const key = `${user._id}${crypto.randomBytes(28).toString("hex")}`; - const refreshToken = randomstring.generate(80); const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { expiresIn: "30d", }); - const expiryDate = moment().add(30, "days").toDate(); - await RefreshToken.create({ - userId: user._id, - key, - token: token, - expiresAt: expiryDate, - }); + const userId = user._id; + const today = moment.utc(); + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; + + let refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); return res.json({ - success: true, token, - refreshToken, - user: { - id: user._id, - firstName: user.firstName, - lastName: user.lastName, - email: user.email, - }, + refreshToken: refreshToken.key, }); } catch (err) { return res.status(401).json({ error: "Invalid ID token" }); From 7e58e7fc2bc82cb6af1e7d01e215f707ac57b7cc Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 9 May 2025 17:10:18 +0500 Subject: [PATCH 31/67] feat: survey form api --- src/models/survey.js | 48 +++++++++++++++++++++++++++++++++++++ src/routes/others/index.js | 12 ++++++---- src/routes/others/survey.js | 34 ++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 src/models/survey.js create mode 100644 src/routes/others/survey.js diff --git a/src/models/survey.js b/src/models/survey.js new file mode 100644 index 0000000..acc9de0 --- /dev/null +++ b/src/models/survey.js @@ -0,0 +1,48 @@ +const mongoose = require("mongoose"); + +const surveySchema = new mongoose.Schema( + { + features: { + type: String, + required: [true, "Is required"], + }, + navigationEase: { + type: String, + required: [true, "Is required"], + }, + motivation: { + type: String, + required: [true, "Is required"], + }, + accessibility: { + type: String, + required: [true, "Is required"], + }, + additionalFeatures: { + type: String, + required: [true, "Is required"], + }, + satisfaction: { + type: String, + required: [true, "Is required"], + }, + challenges: { + type: String, + required: [true, "Is required"], + }, + recommend: { + type: String, + required: [true, "Is required"], + }, + frequency: { + type: String, + required: [true, "Is required"], + }, + }, + { timestamps: true } +); + +module.exports = { + Survey: mongoose.model("Survey", surveySchema), + surveySchema, +}; diff --git a/src/routes/others/index.js b/src/routes/others/index.js index 7ad24b6..68876b1 100644 --- a/src/routes/others/index.js +++ b/src/routes/others/index.js @@ -1,11 +1,13 @@ -const express = require('express'); +const express = require("express"); -const contact = require('./contact'); -const migrateScores = require('./migrate-scores'); +const contact = require("./contact"); +const migrateScores = require("./migrate-scores"); +const survey = require("./survey"); const router = new express.Router(); -router.post('/contact', contact); -router.get('/migrate-scores', migrateScores); +router.post("/contact", contact); +router.post("/survey", survey); +router.get("/migrate-scores", migrateScores); module.exports = router; diff --git a/src/routes/others/survey.js b/src/routes/others/survey.js new file mode 100644 index 0000000..33bdfa6 --- /dev/null +++ b/src/routes/others/survey.js @@ -0,0 +1,34 @@ +const { Survey } = require("../../models/survey"); + +module.exports = async (req, res) => { + const { + features, + navigationEase, + motivation, + accessibility, + additionalFeatures, + satisfaction, + challenges, + recommend, + frequency, + } = req.body; + try { + const surveyForm = new Survey({ + features, + navigationEase, + motivation, + accessibility, + additionalFeatures, + satisfaction, + challenges, + recommend, + frequency, + }); + + await surveyForm.save(); + + res.status(201).json({ message: "Survey saved successfully." }); + } catch (error) { + res.status(500).json({ error: "Something went wrong." }); + } +}; From 0263adf85bf07ec1529325ba2216ad0f8122e6f2 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 12 May 2025 18:53:56 +0500 Subject: [PATCH 32/67] chore: make some field not required in survey --- src/models/survey.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/models/survey.js b/src/models/survey.js index acc9de0..7bb5445 100644 --- a/src/models/survey.js +++ b/src/models/survey.js @@ -20,23 +20,23 @@ const surveySchema = new mongoose.Schema( }, additionalFeatures: { type: String, - required: [true, "Is required"], + required: true, }, satisfaction: { type: String, - required: [true, "Is required"], + required: false, }, challenges: { type: String, - required: [true, "Is required"], + required: false, }, recommend: { type: String, - required: [true, "Is required"], + required: false, }, frequency: { type: String, - required: [true, "Is required"], + required: false, }, }, { timestamps: true } From 6745fb84f0a394ae14e5ceef8683c997e03b3e87 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 13 May 2025 12:43:35 +0500 Subject: [PATCH 33/67] feat: create api to get user active mapathons list --- src/routes/events/index.js | 2 ++ src/routes/events/joined-events.js | 34 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/routes/events/joined-events.js diff --git a/src/routes/events/index.js b/src/routes/events/index.js index c64a0b3..600d8f6 100644 --- a/src/routes/events/index.js +++ b/src/routes/events/index.js @@ -11,10 +11,12 @@ const listEvents = require("./list-events"); const listOldEvents = require("./list-old-events"); const joinEvent = require("./join-event"); const listUpcoimgEvents = require("./list-upcoimg-events"); +const JoinedEvents = require("./joined-events"); const router = new express.Router(); router.get("", listEvents); +router.get("/joinedEvents", JoinedEvents); router.get("/old", isAuthenticated({ isOptional: false }), listOldEvents); router.get("/upComing", listUpcoimgEvents); router.post("", isAuthenticated({ isOptional: false }), createEvent); diff --git a/src/routes/events/joined-events.js b/src/routes/events/joined-events.js new file mode 100644 index 0000000..0e78432 --- /dev/null +++ b/src/routes/events/joined-events.js @@ -0,0 +1,34 @@ +const moment = require("moment"); + +const { Event } = require("../../models/event"); + +module.exports = async (req, res, next) => { + const userId = req?.body?.userId; + const eventsQuery = {}; + const currentDate = moment().startOf("day").utc().toDate(); + + eventsQuery.startDate = { $lte: currentDate }; + eventsQuery.endDate = { $gte: currentDate }; + eventsQuery.$or = [{ managers: userId }, { participants: userId }]; + + let events; + let total; + try { + [events, total] = await Promise.all([ + Event.aggregate().match(eventsQuery).project({ + _id: 0, + id: "$_id", + name: 1, + description: 1, + }), + Event.countDocuments(eventsQuery), + ]); + + return res.status(200).json({ + total, + results: events, + }); + } catch (err) { + return res.status(400).json({ err }); + } +}; From b7e527b81d0e833f721eca3e9c338b116238bd60 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 13 May 2025 17:10:05 +0500 Subject: [PATCH 34/67] chore: updated api for joined events --- src/routes/events/joined-events.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/routes/events/joined-events.js b/src/routes/events/joined-events.js index 0e78432..079697c 100644 --- a/src/routes/events/joined-events.js +++ b/src/routes/events/joined-events.js @@ -1,9 +1,21 @@ const moment = require("moment"); const { Event } = require("../../models/event"); +const jwt = require("jsonwebtoken"); module.exports = async (req, res, next) => { - const userId = req?.body?.userId; + const authHeader = req.headers.authorization; + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return res + .status(401) + .json({ message: "Authorization token missing or invalid" }); + } + + const token = authHeader.split(" ")[1]; + + const decoded = jwt.verify(token, process.env.JWT_SECRET); + const userId = decoded.userId; + const eventsQuery = {}; const currentDate = moment().startOf("day").utc().toDate(); From cccc3480ed7b3abcd9978b0c85f575efa6d9c351 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 27 May 2025 11:59:11 +0500 Subject: [PATCH 35/67] venue-detail --- src/routes/auth/generate-token.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/auth/generate-token.js b/src/routes/auth/generate-token.js index ff40108..b6ff3e7 100644 --- a/src/routes/auth/generate-token.js +++ b/src/routes/auth/generate-token.js @@ -48,7 +48,7 @@ module.exports = async (req, res, next) => { { userId: refreshToken.userId }, process.env.JWT_SECRET, { - expiresIn: 3600, + expiresIn: '30d', } ); return res.status(200).json({ token }); From ff65bbb48036d4018cc320586f6b34259409d0c4 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 27 May 2025 15:22:40 +0500 Subject: [PATCH 36/67] open ai integrated --- package-lock.json | 144 ++++++++++++++++++++++++- package.json | 1 + src/routes/reviews/create-ai-review.js | 58 ++++++++++ src/routes/reviews/index.js | 2 + 4 files changed, 202 insertions(+), 3 deletions(-) create mode 100644 src/routes/reviews/create-ai-review.js diff --git a/package-lock.json b/package-lock.json index 860e757..dbc5dec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "multer": "1.3.0", "nodemailer": "6.9.14", "now": "11.4.6", + "openai": "^4.103.0", "randomstring": "1.3.0", "raven": "2.6.0", "speakingurl": "14.0.1", @@ -905,11 +906,20 @@ "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -923,6 +933,18 @@ "@types/webidl-conversions": "*" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -983,6 +1005,18 @@ } } }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "8.17.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", @@ -3232,6 +3266,15 @@ "es5-ext": "~0.10.14" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", @@ -3821,6 +3864,25 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -5649,6 +5711,15 @@ "node": ">=16.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/husky": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.1.tgz", @@ -7977,6 +8048,26 @@ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8305,6 +8396,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openai": { + "version": "4.103.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.103.0.tgz", + "integrity": "sha512-eWcz9kdurkGOFDtd5ySS5y251H2uBgq9+1a2lTBnjMMzlexJ40Am5t6Mu76SSE87VvitPa0dkIAp75F+dZVC0g==", + "license": "Apache-2.0", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.23.8" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.103", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.103.tgz", + "integrity": "sha512-hHTHp+sEz6SxFsp+SA+Tqrua3AbmlAw+Y//aEwdHrdZkYVRWdvWD3y5uPZ0flYOkgskaFWqZ/YGFm3FaFQ0pRw==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -10681,8 +10811,7 @@ "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==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/union-value": { "version": "1.0.1", @@ -11082,6 +11211,15 @@ "defaults": "^1.0.3" } }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 4f2f5df..675c4c9 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "multer": "1.3.0", "nodemailer": "6.9.14", "now": "11.4.6", + "openai": "^4.103.0", "randomstring": "1.3.0", "raven": "2.6.0", "speakingurl": "14.0.1", diff --git a/src/routes/reviews/create-ai-review.js b/src/routes/reviews/create-ai-review.js new file mode 100644 index 0000000..f300261 --- /dev/null +++ b/src/routes/reviews/create-ai-review.js @@ -0,0 +1,58 @@ +const OPENAI = require("openai"); +const sytemInstruction = `You are an assistant that writes a concise, natural, and helpful accessibility review summary for a location based on the answers given. The answers are boolean or null values representing accessibility features of the location. Use the information below to generate a short review that a person might write as a review comment. Mention only the positive and negative aspects explicitly answered true or false. Ignore any null or unknown fields. +the comment shouldn't be greater than 70 words. + +Use these guidelines to form your comment: +- If "hasWideEntrance" is false, but "hasSecondEntry" is true, mention that the main entrance was not wide enough, but there was a second entrance that was accessible. +- If "hasWashroom" is true, mention that the location has accessible restrooms that were comfortable to use. +- If "hasPermanentRamp" is true, mention the presence of a permanent ramp. +- If "multipleFloors" is true and "hasAccessibleElevator" is true, mention that accessible elevators are available to access multiple floors. +- Mention parking accessibility if "hasParking" or "hasWheelchairParking" is true. +- Include other features if answered true or false, focusing on accessibility and ease of use. + +Answer in a friendly and informative tone, as if a person is giving a brief review summary.`; + +module.exports = async (req, res, next) => { + try { + const openai = new OPENAI({ + apiKey:process.env.OPENAI_API_KEY, + }); + const response = await openai.chat.completions.create({ + model: "gpt-4", + messages: [ + { + role: "system", + content: sytemInstruction, + }, + { + role: "user", + content: ` + Here are the answers: + steps: ${req?.body?.steps} + has1Step: ${req?.body?.has1Step} + has2Step: ${req?.body?.has2Step} + hasWideEntrance: ${req?.body?.hasWideEntrance} + hasParking: ${req?.body?.hasParking} + hasSecondEntry: ${req?.body?.hasSecondEntry} + hasPermanentRamp: ${req?.body?.hasPermanentRamp} + multipleFloors: ${req.body?.multipleFloors} + hasAccessibleElevator: ${req.body?.hasAccessibleElevator} + hasWellLit: ${req.body?.hasWellLit} + brightLightTitle: ${req.body?.brightLightTitle} + hasPortableRamp: ${req.body?.hasPortableRamp} + hasSupportAroundToilet: ${req?.body?.hasSupportAroundToilet} + hasWashroom: ${req?.body?.hasWashroom} + hasWheelchairParking: ${req?.body?.hasWheelchairParking}`, + }, + ], + temperature: 0, + max_tokens: 1000, + top_p: 1, + }); + return res + .status(200) + .json({ general: "Success", data: response.choices[0].message.content }); + } catch (error) { + throw String(error); + } +}; diff --git a/src/routes/reviews/index.js b/src/routes/reviews/index.js index df1af41..9cc7488 100644 --- a/src/routes/reviews/index.js +++ b/src/routes/reviews/index.js @@ -4,6 +4,7 @@ const { isAuthenticated } = require('../../helpers'); const banReview = require('./ban-review'); const createReview = require('./create-review'); +const createAiReview = require('./create-ai-review'); const editReview = require('./edit-review'); const flagReview = require('./flag-review'); const listReviews = require('./list-reviews'); @@ -14,6 +15,7 @@ const router = new express.Router(); router.get('', isAuthenticated({ isOptional: false }), listReviews); router.post('', isAuthenticated({ isOptional: false }), createReview); router.put('/:reviewId', isAuthenticated({ isOptional: false }), editReview); +router.post('/create', isAuthenticated({ isOptional: false }), createAiReview); router.put( '/:reviewId/vote', isAuthenticated({ isOptional: false }), From 0013cba77a52191d5c854db073d089b61c29836d Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Wed, 28 May 2025 17:12:08 +0500 Subject: [PATCH 37/67] apple login integarted --- package-lock.json | 32 ++++++++++++++ package.json | 1 + src/models/user.js | 3 +- src/routes/auth/apple-sign-in.js | 60 ++++++++++++++++++++++++++ src/routes/auth/index.js | 2 + src/routes/auth/validations.js | 11 +++++ src/routes/reviews/create-ai-review.js | 2 +- 7 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 src/routes/auth/apple-sign-in.js diff --git a/package-lock.json b/package-lock.json index dbc5dec..e937042 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "api", "version": "2.0.0", "dependencies": { + "apple-signin-auth": "^2.0.0", "aws-sdk": "2.1660.0", "axios": "1.7.2", "bcrypt-nodejs": "0.0.3", @@ -1150,6 +1151,19 @@ "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" }, + "node_modules/apple-signin-auth": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/apple-signin-auth/-/apple-signin-auth-2.0.0.tgz", + "integrity": "sha512-/O5gvAby7OU2K7baYQCzY0e0tCiHzhFkzt9L2v3bMd2I2w0ckCZ/4hdVUOrbolRGMppME+Zo8TAKPVru8aYnzg==", + "license": "MIT", + "dependencies": { + "jsonwebtoken": "^9.0.0", + "node-rsa": "^1.1.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -1311,6 +1325,15 @@ "node": ">=0.10.0" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -8087,6 +8110,15 @@ } } }, + "node_modules/node-rsa": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", + "license": "MIT", + "dependencies": { + "asn1": "^0.2.4" + } + }, "node_modules/nodemailer": { "version": "6.9.14", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", diff --git a/package.json b/package.json index 675c4c9..017b542 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "prettier": "3.3.3" }, "dependencies": { + "apple-signin-auth": "^2.0.0", "aws-sdk": "2.1660.0", "axios": "1.7.2", "bcrypt-nodejs": "0.0.3", diff --git a/src/models/user.js b/src/models/user.js index a34e386..bc3390b 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -50,7 +50,6 @@ const userSchema = new mongoose.Schema( firstName: { type: String, maxlength: [24, "Should be less than 25 characters"], - required: [true, "Is required"], }, gender: { type: String, @@ -72,6 +71,7 @@ const userSchema = new mongoose.Schema( required: [true, "Is required"], }, googleId: String, + appleId: String, hashedPassword: { type: String, maxlength: [256, "Should be less than 255 characters"], @@ -99,7 +99,6 @@ const userSchema = new mongoose.Schema( lastName: { type: String, maxlength: [36, "Should be less than 37 characters"], - required: [true, "Is required"], }, language: { type: String, diff --git a/src/routes/auth/apple-sign-in.js b/src/routes/auth/apple-sign-in.js new file mode 100644 index 0000000..3279986 --- /dev/null +++ b/src/routes/auth/apple-sign-in.js @@ -0,0 +1,60 @@ +const crypto = require("crypto"); + +const axios = require("axios"); +const jwt = require("jsonwebtoken"); +const moment = require("moment"); + +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); + +const { validateAppleSignIn } = require("./validations"); + +const appleSignin = require("apple-signin-auth"); + +module.exports = async (req, res, next) => { + const { errors, isValid } = validateAppleSignIn(req.body); + const { identityToken } = req.body; + if (!isValid) { + return res.status(400).json(errors); + } + + try { + const appleResponse = await appleSignin.verifyIdToken(identityToken, { + audience: process?.env?.APPLE_APP_IDENTIFIER, // Your app's Bundle ID or Service ID + ignoreExpiration: false, // Set true only for testing (not recommended in production) + }); + console.log(appleResponse); + let user = await User.findOne({ + email: appleResponse?.email, + }); + if (!user) { + user = new User({ + email: appleResponse?.email, + firstName:appleResponse?.fullName?.givenName ?? "", + lastName:appleResponse?.fullName?.familyName ?? "", + appleId: appleResponse?.sub, + }); + + await user.save(); + } + const userId = user._id; + const today = moment.utc(); + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; + let refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { + expiresIn: "30d", + }); + res.json({ + refreshToken: refreshToken.key, + token, + }); + } catch (err) { + console.log(err) + res.status(401).json({ success: false, error: "Invalid Apple token" }); + } +}; diff --git a/src/routes/auth/index.js b/src/routes/auth/index.js index 431d0c8..e6cb121 100644 --- a/src/routes/auth/index.js +++ b/src/routes/auth/index.js @@ -4,6 +4,7 @@ const { isAuthenticated } = require('../../helpers'); const activateAccount = require('./activate-account'); const facebookSignIn = require('./facebook-sign-in'); +const appleSignin = require('./apple-sign-in'); const forgottenPassword = require('./forgotten-password'); const generateToken = require('./generate-token'); const googleSignIn = require('./google-sign-in'); @@ -16,6 +17,7 @@ const router = new express.Router(); router.get('/activate-account/:key', activateAccount); router.post('/facebook', facebookSignIn); +router.post('/apple', appleSignin); router.post('/forgotten-password', forgottenPassword); router.post('/google', googleSignIn); router.put('/reset-password', resetPassword); diff --git a/src/routes/auth/validations.js b/src/routes/auth/validations.js index 872db78..c276bee 100644 --- a/src/routes/auth/validations.js +++ b/src/routes/auth/validations.js @@ -18,6 +18,17 @@ module.exports = { return { errors, isValid: isEmpty(errors) }; }, + validateAppleSignIn(data) { + const errors = {}; + + if (!data.identityToken) { + errors.identityToken = "Is required"; + } else if (typeof data.identityToken !== "string") { + errors.identityToken = "Should be a string"; + } + + return { errors, isValid: isEmpty(errors) }; + }, validateForgottenPassword(data) { const errors = {}; diff --git a/src/routes/reviews/create-ai-review.js b/src/routes/reviews/create-ai-review.js index f300261..fbad3e6 100644 --- a/src/routes/reviews/create-ai-review.js +++ b/src/routes/reviews/create-ai-review.js @@ -12,7 +12,7 @@ Use these guidelines to form your comment: Answer in a friendly and informative tone, as if a person is giving a brief review summary.`; -module.exports = async (req, res, next) => { +module.exports = async (req, res,) => { try { const openai = new OPENAI({ apiKey:process.env.OPENAI_API_KEY, From e333ca5ac2382f0b58ed5264becb1a72f9c97ed1 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 2 Jun 2025 15:49:49 +0500 Subject: [PATCH 38/67] ai-prompt changed --- src/routes/reviews/create-ai-review.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/reviews/create-ai-review.js b/src/routes/reviews/create-ai-review.js index fbad3e6..2131120 100644 --- a/src/routes/reviews/create-ai-review.js +++ b/src/routes/reviews/create-ai-review.js @@ -1,6 +1,6 @@ const OPENAI = require("openai"); const sytemInstruction = `You are an assistant that writes a concise, natural, and helpful accessibility review summary for a location based on the answers given. The answers are boolean or null values representing accessibility features of the location. Use the information below to generate a short review that a person might write as a review comment. Mention only the positive and negative aspects explicitly answered true or false. Ignore any null or unknown fields. -the comment shouldn't be greater than 70 words. +the comment shouldn't be greater than 70 words. comment should only mention the features that are answered true. Use these guidelines to form your comment: - If "hasWideEntrance" is false, but "hasSecondEntry" is true, mention that the main entrance was not wide enough, but there was a second entrance that was accessible. From e086b1077e1c2fb296e2a4d06c54f90bcb4b685e Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sun, 8 Jun 2025 20:02:39 +0500 Subject: [PATCH 39/67] chaneg already existing mail error --- src/routes/auth/sign-up.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 72b997a..9d0b331 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -35,7 +35,6 @@ module.exports = async (req, res, next) => { data.lastName = cleanSpaces(data.lastName); data.username = `${slugify(data.firstName)}-${slugify(data.lastName)}`; - console.log(data) let activationTicket; try { @@ -80,7 +79,7 @@ module.exports = async (req, res, next) => { if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === data.email) { - return res.status(400).json({ email: "Is already taken" }); + return res.status(400).json({ message: "Email is already taken" }); } let repeatedUser; From 0bacfd5e16824ef2f8818bec23238e1a80962b17 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sun, 8 Jun 2025 20:05:22 +0500 Subject: [PATCH 40/67] chaneg already existing mail error --- src/routes/auth/sign-up.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 9d0b331..f040c55 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -79,7 +79,7 @@ module.exports = async (req, res, next) => { if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === data.email) { - return res.status(400).json({ message: "Email is already taken" }); + return res.status(400).json({ message: "This email address is already in use. Please try a different one." }); } let repeatedUser; From a506841f1770affa65e474e5b8ecea7a42ac44c2 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 10 Jun 2025 19:07:27 +0500 Subject: [PATCH 41/67] email template change --- src/helpers/mail-template.js | 2 +- src/routes/auth/forgotten-password.js | 6 ------ src/routes/auth/sign-up.js | 14 +------------- src/routes/reviews/create-review.js | 1 - 4 files changed, 2 insertions(+), 21 deletions(-) diff --git a/src/helpers/mail-template.js b/src/helpers/mail-template.js index c14d1b2..b1e7deb 100644 --- a/src/helpers/mail-template.js +++ b/src/helpers/mail-template.js @@ -29,7 +29,7 @@ const activationEmailTemplate = (link,name) => {

- If you didn’t sign up for [Your App Name], no worries — you can safely ignore this email. + If you didn’t sign up for AXS Map, no worries — you can safely ignore this email.

diff --git a/src/routes/auth/forgotten-password.js b/src/routes/auth/forgotten-password.js index c782c05..7e4c61b 100644 --- a/src/routes/auth/forgotten-password.js +++ b/src/routes/auth/forgotten-password.js @@ -49,14 +49,8 @@ module.exports = async (req, res, next) => { try { passwordTicket = await PasswordTicket.create({ email, expiresAt, key }); } catch (err) { - console.log( - `Password ticket failed to be created at forgotten-password.\nData: ${JSON.stringify( - { email, expiresAt, key } - )}` - ); return next(err); } - console.log(passwordTicket); const htmlContent = `

Hi from AXS Map!

diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index f040c55..bcfe6f4 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -72,14 +72,13 @@ module.exports = async (req, res, next) => { isArchived: false, }); } catch (err) { - console.log("Users failed to be found at sign-up."); return next(err); } if (repeatedUsers && repeatedUsers.length > 0) { for (const user of repeatedUsers) { if (user.email === data.email) { - return res.status(400).json({ message: "This email address is already in use. Please try a different one." }); + return res.status(400).json({ message: "This email address is already in use. Please use forgot password to login." }); } let repeatedUser; @@ -142,17 +141,6 @@ module.exports = async (req, res, next) => { const subject = "Activate Account"; // TODO change base URL for ACTIVATION - const htmlContent = ` -

Welcome to AXS Map!

-

To activate your account use the link below:

-
- - https://axsmap.com/auth/activate-account/${activationTicket.key} - -

-

Stay awesome.

- `; const textContent = ` Welcome to AXS Map! To activate your account use the link below: diff --git a/src/routes/reviews/create-review.js b/src/routes/reviews/create-review.js index 211c6ba..56619e3 100644 --- a/src/routes/reviews/create-review.js +++ b/src/routes/reviews/create-review.js @@ -50,7 +50,6 @@ module.exports = async (req, res, next) => { comments: req.body.comments, }; - console.log(data); let event; if (data.event) { From fe7d14c004d87e0d3214424fc43fa60c932297c4 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 19 Jun 2025 17:28:17 +0500 Subject: [PATCH 42/67] fix google login for mobile --- src/routes/auth/facebook-sign-in.js | 68 ++++++++++++++++------------- src/routes/auth/google-sign-in.js | 13 +++--- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index e12fe2a..949ad89 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -3,8 +3,6 @@ const crypto = require("crypto"); const axios = require("axios"); const jwt = require("jsonwebtoken"); const moment = require("moment"); -const randomstring = require("randomstring"); -const slugify = require("speakingurl"); const { RefreshToken } = require("../../models/refresh-token"); const { User } = require("../../models/user"); @@ -27,42 +25,50 @@ module.exports = async (req, res, next) => { }); const fbUser = fbUserResponse.data; + if (fbUser.email) { + const email = fbUser.email; - const email = fbUser.email || "No email available"; + let user = await User.findOne({ facebookId: fbUser.id }); - let user = await User.findOne({ facebookId: fbUser.id }); + const [firstName, lastName] = fbUser.name.split(" "); - const [firstName, lastName] = fbUser.name.split(" "); + if (!user) { + user = new User({ + fbId: fbUser.id, + email, + firstName: firstName || "", + lastName: lastName || "", + picture: fbUser.picture.data.url, + }); - if (!user) { - user = new User({ - fbId: fbUser.id, - email, - firstName: firstName || "", - lastName: lastName || "", - picture: fbUser.picture.data.url, + await user.save(); + } + const userId = user._id; + const today = moment.utc(); + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; + + let refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { + expiresIn: "30d", }); - await user.save(); + res.json({ + refreshToken: refreshToken.key, + token, + }); + } else { + res + .status(400) + .json({ + success: false, + error: "Email is not linked with this account", + }); } - const userId = user._id; - const today = moment.utc(); - const expiresAt = today.add(30, "days").toDate(); - const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; - - let refreshToken = await RefreshToken.findOneAndUpdate( - { userId }, - { expiresAt, key, userId }, - { new: true, setDefaultsOnInsert: true, upsert: true } - ); - const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { - expiresIn: "30d", - }); - - res.json({ - refreshToken: refreshToken.key, - token, - }); } catch (err) { res.status(401).json({ success: false, error: "Invalid Facebook token" }); } diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 17e86ac..5ea383b 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -23,18 +23,17 @@ module.exports = async (req, res) => { return res.status(400).json(errors); } + const code = req.body.code; - const oauth2Client = new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI); + const oauth2Client = new OAuth2Client(CLIENT_ID); try { - const { tokens } = await oauth2Client.getToken(code); - oauth2Client.setCredentials(tokens); const ticket = await oauth2Client.verifyIdToken({ - idToken: tokens.id_token, + idToken: code, audience: CLIENT_ID, }); const payload = ticket.getPayload(); - const { sub: googleId, email, name, picture } = payload; + const { email, name, picture } = payload; const [firstName, lastName] = name.split(" "); @@ -45,6 +44,7 @@ module.exports = async (req, res) => { firstName: firstName || name, lastName: lastName || "", createdAt: new Date(), + avatar:picture }); await user.save(); } @@ -69,6 +69,7 @@ module.exports = async (req, res) => { refreshToken: refreshToken.key, }); } catch (err) { - return res.status(401).json({ error: "Invalid ID token" }); + console.log(err) + return res.status(500).json({ error: "Something went wrong" }); } }; From 22f49e22ac5e845915ff004a93b5da790da2b7a5 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sat, 21 Jun 2025 02:25:11 +0500 Subject: [PATCH 43/67] google env updates --- src/routes/auth/google-sign-in.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 5ea383b..8b2e992 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -14,8 +14,6 @@ const { User } = require("../../models/user"); const { validateGoogleSignIn } = require("./validations"); const CLIENT_ID = process.env.GOOGLE_CLIENT_ID; -const CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET; -const REDIRECT_URI = process.env.GOOGLE_REDIRECT_URI; module.exports = async (req, res) => { const { errors, isValid } = validateGoogleSignIn(req.body); @@ -23,12 +21,27 @@ module.exports = async (req, res) => { return res.status(400).json(errors); } - - const code = req.body.code; + let token = req.body.code; const oauth2Client = new OAuth2Client(CLIENT_ID); try { + const deviceType = req.headers["x-device-type"]; + if (deviceType === "web") { + const tokenRes = await fetch("https://oauth2.googleapis.com/token", { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: new URLSearchParams({ + code: token, + client_id: process.env.GOOGLE_CLIENT_ID, + client_secret: process.env.GOOGLE_CLIENT_SECRET, + redirect_uri: process.env.GOOGLE_REDIRECT_URI, + grant_type: "authorization_code", + }), + }); + token = await tokenRes.json(); + } + const ticket = await oauth2Client.verifyIdToken({ - idToken: code, + idToken: token, audience: CLIENT_ID, }); @@ -44,7 +57,7 @@ module.exports = async (req, res) => { firstName: firstName || name, lastName: lastName || "", createdAt: new Date(), - avatar:picture + avatar: picture, }); await user.save(); } @@ -69,7 +82,7 @@ module.exports = async (req, res) => { refreshToken: refreshToken.key, }); } catch (err) { - console.log(err) + console.log(err); return res.status(500).json({ error: "Something went wrong" }); } }; From 569871b43d5d1de7e1c41850cf717d69b8375c16 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sat, 21 Jun 2025 02:31:44 +0500 Subject: [PATCH 44/67] google env updates --- src/routes/auth/google-sign-in.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 8b2e992..ef84ab5 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -25,6 +25,7 @@ module.exports = async (req, res) => { const oauth2Client = new OAuth2Client(CLIENT_ID); try { const deviceType = req.headers["x-device-type"]; + console.log(deviceType === "web",deviceType) if (deviceType === "web") { const tokenRes = await fetch("https://oauth2.googleapis.com/token", { method: "POST", From cd5f496c6caf0982fc46965db2983421abeb0724 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sat, 21 Jun 2025 02:33:29 +0500 Subject: [PATCH 45/67] google env updates --- src/routes/auth/google-sign-in.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index ef84ab5..b3624b4 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -21,7 +21,7 @@ module.exports = async (req, res) => { return res.status(400).json(errors); } - let token = req.body.code; + let code = req.body.code; const oauth2Client = new OAuth2Client(CLIENT_ID); try { const deviceType = req.headers["x-device-type"]; @@ -38,11 +38,11 @@ module.exports = async (req, res) => { grant_type: "authorization_code", }), }); - token = await tokenRes.json(); + code = await tokenRes.json(); } const ticket = await oauth2Client.verifyIdToken({ - idToken: token, + idToken: code, audience: CLIENT_ID, }); From 6479dec9a9c91edefe39569fe7fc60efd6c8cdac Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Sat, 21 Jun 2025 02:35:42 +0500 Subject: [PATCH 46/67] google env updates --- src/routes/auth/google-sign-in.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index b3624b4..8dd0554 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -31,7 +31,7 @@ module.exports = async (req, res) => { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ - code: token, + code, client_id: process.env.GOOGLE_CLIENT_ID, client_secret: process.env.GOOGLE_CLIENT_SECRET, redirect_uri: process.env.GOOGLE_REDIRECT_URI, From 95253e27d27cbb9e3fc5f7713b4bbeb01617b302 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 23 Jun 2025 12:51:34 +0500 Subject: [PATCH 47/67] servey submission user added and mail configred --- src/helpers/mail-template.js | 113 ++++++++++++++++++++++++++++-- src/models/survey.js | 5 ++ src/routes/auth/google-sign-in.js | 1 - src/routes/others/index.js | 3 +- src/routes/others/survey.js | 48 +++++++++++++ 5 files changed, 164 insertions(+), 6 deletions(-) diff --git a/src/helpers/mail-template.js b/src/helpers/mail-template.js index b1e7deb..6cdd100 100644 --- a/src/helpers/mail-template.js +++ b/src/helpers/mail-template.js @@ -1,4 +1,4 @@ -const activationEmailTemplate = (link,name) => { +const activationEmailTemplate = (link, name) => { return ` @@ -51,7 +51,112 @@ const activationEmailTemplate = (link,name) => { `; }; +const submitServeyUserMailTemplate = (userName) => { + return ` + + + + + + + +
+ + + + + + + + + + + +
+

Thank You for Sharing Your Voice! 🙌

+

Your recent AXS Map survey has been submitted.

+
+

+ Hi ${userName}, +

+

+ We truly appreciate your input! Your recent survey submission helps us make AXS Map more accessible and impactful for everyone. +

+ + -module.exports={ - activationEmailTemplate -} \ No newline at end of file +

+ Want to contribute more? You can always submit another review or share your experience with friends to help grow the community. +

+
+

+ Questions? Contact Support +

+

© 2025 AXS MAP. All rights reserved.

+
+
+ + +`; +}; + +const adminServeyMailTemplate = (name, email, answers) => { + return ` + + + + + + + +
+ + + + + + + + + + +
+

New Survey Submitted on AXS Map 📝

+

A new survey response has just been submitted by a user.

+
+

+ User Name: ${name}
+ Email: ${email} +

+ +
+ +

Survey Responses:

+ + ${answers.map((item, index) => { + return `

+ Q${index + 1}: ${item?.question}
+ A: ${item?.answer} +

`; + })} +
+

+ For any issues, reach out to Support +

+

© 2025 AXS MAP. Admin Notification Email

+
+
+ + +`; +}; + +module.exports = { + activationEmailTemplate, + submitServeyUserMailTemplate, + adminServeyMailTemplate, +}; diff --git a/src/models/survey.js b/src/models/survey.js index 7bb5445..44d0c0e 100644 --- a/src/models/survey.js +++ b/src/models/survey.js @@ -38,6 +38,11 @@ const surveySchema = new mongoose.Schema( type: String, required: false, }, + user: { + type: mongoose.Schema.Types.ObjectId, + ref: "User", + required: [true, "Is required"], + }, }, { timestamps: true } ); diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 8dd0554..670373f 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -25,7 +25,6 @@ module.exports = async (req, res) => { const oauth2Client = new OAuth2Client(CLIENT_ID); try { const deviceType = req.headers["x-device-type"]; - console.log(deviceType === "web",deviceType) if (deviceType === "web") { const tokenRes = await fetch("https://oauth2.googleapis.com/token", { method: "POST", diff --git a/src/routes/others/index.js b/src/routes/others/index.js index 68876b1..0ba2a70 100644 --- a/src/routes/others/index.js +++ b/src/routes/others/index.js @@ -3,11 +3,12 @@ const express = require("express"); const contact = require("./contact"); const migrateScores = require("./migrate-scores"); const survey = require("./survey"); +const { isAuthenticated } = require("../../helpers"); const router = new express.Router(); router.post("/contact", contact); -router.post("/survey", survey); +router.post("/survey", isAuthenticated({ isOptional: false }), survey); router.get("/migrate-scores", migrateScores); module.exports = router; diff --git a/src/routes/others/survey.js b/src/routes/others/survey.js index 33bdfa6..d7102b3 100644 --- a/src/routes/others/survey.js +++ b/src/routes/others/survey.js @@ -1,4 +1,21 @@ const { Survey } = require("../../models/survey"); +const { + adminServeyMailTemplate, + submitServeyUserMailTemplate, +} = require("../../helpers/mail-template"); +const { sendEmail } = require("../../helpers"); + +const questions = { + features: "What features do you use most on AXS Map?", + navigationEase: "How easy is it to navigate the app?", + motivation: "What motivates you to participate in Mapathons?", + accessibility: "How can we improve accessibility ratings?", + additionalFeatures: "Any additional features you'd like to see?", + satisfaction: "How satisfied are you with the app?", + challenges: "What challenges have you faced using AXS Map?", + recommend: "Would you recommend it to others?", + frequency: "What would make you use it more often?", +}; module.exports = async (req, res) => { const { @@ -23,12 +40,43 @@ module.exports = async (req, res) => { challenges, recommend, frequency, + user: req?.user?.id, }); await surveyForm.save(); + sendEmail({ + subject: "Survey Submission Confirmation", + htmlContent: submitServeyUserMailTemplate( + `${req?.user?.firstName ?? ""} ${req?.user?.lastName ?? ""}` + ), + textContent: "", + receiversEmails: [req?.user?.email], + }); + const aswers = [ + { question: questions.features, answer: features }, + { question: questions.navigationEase, answer: navigationEase }, + { question: questions.motivation, answer: motivation }, + { question: questions.accessibility, answer: accessibility }, + { question: questions.additionalFeatures, answer: additionalFeatures }, + { question: questions.satisfaction, answer: satisfaction }, + { question: questions.challenges, answer: challenges }, + { question: questions.recommend, answer: recommend }, + { question: questions.frequency, answer: frequency }, + ]; + sendEmail({ + subject: "Survey Submission Confirmation", + htmlContent: adminServeyMailTemplate( + `${req?.user?.firstName ?? ""} ${req?.user?.lastName ?? ""}`, + req?.user?.email, + aswers + ), + textContent: "", + receiversEmails: [`${process?.env?.SERVEY_SUBMISSION_MAIL}`], + }); res.status(201).json({ message: "Survey saved successfully." }); } catch (error) { + console.log(error) res.status(500).json({ error: "Something went wrong." }); } }; From 3534b33c63ee3ad079d07a951b029df49a4ece62 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 23 Jun 2025 15:03:11 +0500 Subject: [PATCH 48/67] login google issue resolve --- src/routes/auth/google-sign-in.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index 670373f..c98ddcb 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -37,7 +37,8 @@ module.exports = async (req, res) => { grant_type: "authorization_code", }), }); - code = await tokenRes.json(); + const googleToken = await tokenRes.json(); + code =googleToken?.id_token } const ticket = await oauth2Client.verifyIdToken({ From 55380a172cf52f8d9a6a2963ac4291a738f29c3f Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 27 Jun 2025 11:02:14 +0500 Subject: [PATCH 49/67] handle mapathon date --- src/routes/events/create-event.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/events/create-event.js b/src/routes/events/create-event.js index 068fd02..264d6a7 100644 --- a/src/routes/events/create-event.js +++ b/src/routes/events/create-event.js @@ -33,7 +33,8 @@ module.exports = async (req, res, next) => { data.address = cleanSpaces(data.address); - data.endDate = moment(data.endDate).endOf("day").utc().toDate(); + data.endDate = moment(data.endDate).endOf("day").toDate(); + data.startDate = moment(data.startDate).startOf("day").toDate(); data.location = { coordinates: [data.locationCoordinates[1], data.locationCoordinates[0]], @@ -69,7 +70,6 @@ module.exports = async (req, res, next) => { } } - data.startDate = moment(data.startDate).startOf("day").utc().toDate(); if (data.teamManager) { let team; From 0fce4d2c340bf0e692536bce3794d47df98e07d8 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 30 Jun 2025 11:59:53 +0500 Subject: [PATCH 50/67] comment error resolve --- src/models/review.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/models/review.js b/src/models/review.js index af9b67f..5ac2679 100644 --- a/src/models/review.js +++ b/src/models/review.js @@ -23,13 +23,11 @@ const reviewSchema = new mongoose.Schema( allowsGuideDog: Boolean, comments: { type: String, - maxlength: [300, "Should be less than 301 characters"], }, complaints: [ { comments: { type: String, - maxlength: [300, "Should be less than 30 characters"], }, createdAt: { type: Date, From fd7ba81a32ac939640ff51dfcd784e84c44de754 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Jul 2025 13:37:08 +0500 Subject: [PATCH 51/67] signup issue resolve --- src/routes/auth/sign-up.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index bcfe6f4..10886df 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -30,6 +30,7 @@ module.exports = async (req, res, next) => { "gender", "race", ]); + console.log(data) data.aboutMe = cleanSpaces(data.aboutMe ?? ""); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); @@ -83,8 +84,8 @@ module.exports = async (req, res, next) => { let repeatedUser; do { - data.username = `${slugify(data.firstName)}-${slugify( - data.lastName + data.username = `${slugify(data?.firstName)}-${slugify( + data?.lastName )}-${randomstring.generate({ length: 5, capitalization: "lowercase", @@ -128,6 +129,7 @@ module.exports = async (req, res, next) => { race: data?.race || '', }, }; + console.log(activationTicketData) try { activationTicket = await ActivationTicket.create(activationTicketData); } catch (err) { From 78c03fd74b5a909f5f6e5bd57ca3e2804a8ca94f Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Jul 2025 13:39:02 +0500 Subject: [PATCH 52/67] signup issue resolve --- src/routes/auth/sign-up.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 10886df..258ca2c 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -13,6 +13,7 @@ const { validateSignUp } = require("./validations"); const { activationEmailTemplate } = require("../../helpers/mail-template"); module.exports = async (req, res, next) => { + console.log(req.body) const { errors, isValid } = validateSignUp(req.body); if (!isValid) { return res.status(400).json(errors); @@ -30,7 +31,6 @@ module.exports = async (req, res, next) => { "gender", "race", ]); - console.log(data) data.aboutMe = cleanSpaces(data.aboutMe ?? ""); data.firstName = cleanSpaces(data.firstName); data.lastName = cleanSpaces(data.lastName); From cc7d6b839d02f7a2742a6879782c438c2728905c Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Jul 2025 13:40:36 +0500 Subject: [PATCH 53/67] signup issue resolve --- src/routes/auth/sign-up.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 258ca2c..4b49325 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -13,10 +13,11 @@ const { validateSignUp } = require("./validations"); const { activationEmailTemplate } = require("../../helpers/mail-template"); module.exports = async (req, res, next) => { - console.log(req.body) + const { errors, isValid } = validateSignUp(req.body); + console.log(errors) if (!isValid) { - return res.status(400).json(errors); + return res.status(400).json({message:errors}); } const data = pick(req.body, [ From 00ce1fc738382c8508e42b7b437547ff54487dd3 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Jul 2025 13:42:42 +0500 Subject: [PATCH 54/67] signup issue resolve --- src/routes/auth/sign-up.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/auth/sign-up.js b/src/routes/auth/sign-up.js index 4b49325..9845a13 100644 --- a/src/routes/auth/sign-up.js +++ b/src/routes/auth/sign-up.js @@ -17,7 +17,7 @@ module.exports = async (req, res, next) => { const { errors, isValid } = validateSignUp(req.body); console.log(errors) if (!isValid) { - return res.status(400).json({message:errors}); + return res.status(400).json({message:Object.entries(errors)[0][1]}); } const data = pick(req.body, [ From da46630b2a78ad2939d98e850b778f72289efd59 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 10 Jul 2025 13:48:08 +0500 Subject: [PATCH 55/67] signup issue resolve --- src/helpers/constants.js | 2 +- src/routes/auth/validations.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/helpers/constants.js b/src/helpers/constants.js index e250834..3fd5a1f 100644 --- a/src/helpers/constants.js +++ b/src/helpers/constants.js @@ -127,7 +127,7 @@ module.exports = { "subpremise", ], disability: [ - "yes", "No", "not-to-say", "" + "yes", "no", "not-to-say", "" ], genders: [ "female", diff --git a/src/routes/auth/validations.js b/src/routes/auth/validations.js index c276bee..70ae01c 100644 --- a/src/routes/auth/validations.js +++ b/src/routes/auth/validations.js @@ -163,15 +163,15 @@ module.exports = { errors.password = "Should have less than 31 characters"; } - if (data.disability && !disability.includes(data.disability)) { - errors.disability = "Please select a valid disability option"; - } - if (data.gender && !genders.includes(data.gender)) { - errors.gender = "Please select a valid gender option"; - } - if (data.race && !race.includes(data.race)) { - errors.race = "Please select a valid race option"; - } + // if (data.disability && !disability.includes(data.disability)) { + // errors.disability = "Please select a valid disability option"; + // } + // if (data.gender && !genders.includes(data.gender)) { + // errors.gender = "Please select a valid gender option"; + // } + // if (data.race && !race.includes(data.race)) { + // errors.race = "Please select a valid race option"; + // } return { errors, isValid: isEmpty(errors) }; }, From 8fc32c80081555bad2edf8dcf51d518f756b968e Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Thu, 28 Aug 2025 18:00:33 +0500 Subject: [PATCH 56/67] login with facebook website issue resolved --- src/helpers/index.js | 14 +-- src/routes/auth/facebook-sign-in.js | 31 ++++-- src/routes/venues/get-venue.js | 3 - src/routes/venues/list-venues.js | 8 +- src/routes/venues/validations.js | 150 ++++++++++++++-------------- 5 files changed, 108 insertions(+), 98 deletions(-) diff --git a/src/helpers/index.js b/src/helpers/index.js index a401165..e27326c 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -45,15 +45,17 @@ module.exports = { "-__v -createdAt -isAdmin -isArchived -isBlocked -hashedPassword -updatedAt" ); if (req.originalUrl.startsWith("/venues?") && req.method === "GET") { - const location = req.query.location; + const location = req?.query?.location; if (location) { const [lat, lng] = location .split(",") - .map((coord) => coord.trim()); - user.lastLocation = { - lat, - lng, - }; + .map((coord) => coord?.trim()); + if (lat && lng) { + user.lastLocation = { + lat, + lng, + }; + } } } user.lastActivityTime = new Date().toISOString(); diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 949ad89..018bacf 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -15,11 +15,26 @@ module.exports = async (req, res, next) => { return res.status(400).json(errors); } - const code = req.body.code; + let token = req.body.code; try { + if (req.body.web) { + const tokenResponse = await axios.get( + "https://graph.facebook.com/v17.0/oauth/access_token", + { + params: { + client_id: process.env.FACEBOOK_CLIENT_ID, + client_secret: process.env.FACEBOOK_CLIENT_SECRET, + redirect_uri: req.body.redirectUri, // must match exactly + code: req.body.code, + }, + } + ); + + token = tokenResponse.data.access_token; + } const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { params: { - access_token: code, + access_token: token, fields: "id,name,email,picture", }, }); @@ -28,7 +43,7 @@ module.exports = async (req, res, next) => { if (fbUser.email) { const email = fbUser.email; - let user = await User.findOne({ facebookId: fbUser.id }); + let user = await User.findOne({ fbId: fbUser.id }); const [firstName, lastName] = fbUser.name.split(" "); @@ -62,12 +77,10 @@ module.exports = async (req, res, next) => { token, }); } else { - res - .status(400) - .json({ - success: false, - error: "Email is not linked with this account", - }); + res.status(400).json({ + success: false, + error: "Email is not linked with this account", + }); } } catch (err) { res.status(401).json({ success: false, error: "Invalid Facebook token" }); diff --git a/src/routes/venues/get-venue.js b/src/routes/venues/get-venue.js index bc30464..2b9c719 100644 --- a/src/routes/venues/get-venue.js +++ b/src/routes/venues/get-venue.js @@ -293,19 +293,16 @@ module.exports = async (req, res, next) => { //calculate entranceScore, glyphs scoring = venueReviewSummary.calculateRatingLevel('entrance', venue[0]); - console.log('entrance score: ', scoring); dataResponse.entranceScore = scoring.ratingLevel; dataResponse.entranceGlyphs = scoring.ratingGlyphs; //calculate interiorScore, glyphs scoring = venueReviewSummary.calculateRatingLevel('interior', venue[0]); - console.log('interior score: ', scoring); dataResponse.interiorScore = scoring.ratingLevel; dataResponse.interiorGlyphs = scoring.ratingGlyphs; //calculate restroomScore, glyphs scoring = venueReviewSummary.calculateRatingLevel('restroom', venue[0]); - console.log('restroom score: ', scoring); dataResponse.restroomScore = scoring.ratingLevel; dataResponse.restroomGlyphs = scoring.ratingGlyphs; diff --git a/src/routes/venues/list-venues.js b/src/routes/venues/list-venues.js index b49cf50..67140ec 100644 --- a/src/routes/venues/list-venues.js +++ b/src/routes/venues/list-venues.js @@ -414,12 +414,9 @@ module.exports = async (req, res, next) => { let placesResponse; try { - // console.log( - // "performing google search: " + - // `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` - // ); + console.log(`https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}&fields=photos,place_id`) placesResponse = await axios.get( - `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}` + `https://maps.googleapis.com/maps/api/place/${searchType}/json${nearbyParams}&fields=photos,place_id` ); } catch (err) { console.log( @@ -456,6 +453,7 @@ module.exports = async (req, res, next) => { let places = []; const placesIds = []; placesResponse.data.results.forEach((place) => { + console.log(place?.photos) let photo = ""; if (place.photos) { photo = `https://maps.googleapis.com/maps/api/place/photo?key=${ diff --git a/src/routes/venues/validations.js b/src/routes/venues/validations.js index a234600..d85c043 100644 --- a/src/routes/venues/validations.js +++ b/src/routes/venues/validations.js @@ -57,16 +57,16 @@ module.exports = { } } - if (queryParams.allowsGuideDog) { - if (!isNumber(queryParams.allowsGuideDog)) { - errors.allowsGuideDog = 'Should be a number'; - } else if ( - parseFloat(queryParams.allowsGuideDog) !== 0 && - parseFloat(queryParams.allowsGuideDog) !== 1 - ) { - errors.allowsGuideDog = 'Should be 0 or 1'; - } - } + // if (queryParams.allowsGuideDog) { + // if (!isNumber(queryParams.allowsGuideDog)) { + // errors.allowsGuideDog = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.allowsGuideDog) !== 0 && + // parseFloat(queryParams.allowsGuideDog) !== 1 + // ) { + // errors.allowsGuideDog = 'Should be 0 or 1'; + // } + // } if (queryParams.hasParking) { if (!isNumber(queryParams.hasParking)) { @@ -79,71 +79,71 @@ module.exports = { } } - if (queryParams.hasRamp) { - if (!isNumber(queryParams.hasRamp)) { - errors.hasRamp = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasRamp) !== 0 && - parseFloat(queryParams.hasRamp) !== 1 - ) { - errors.hasRamp = 'Should be 0 or 1'; - } - } - - if (queryParams.hasSecondEntry) { - if (!isNumber(queryParams.hasSecondEntry)) { - errors.hasSecondEntry = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasSecondEntry) !== 0 && - parseFloat(queryParams.hasSecondEntry) !== 1 - ) { - errors.hasSecondEntry = 'Should be 0 or 1'; - } - } - - if (queryParams.hasWellLit) { - if (!isNumber(queryParams.hasWellLit)) { - errors.hasWellLit = 'Should be a number'; - } else if ( - parseFloat(queryParams.hasWellLit) !== 0 && - parseFloat(queryParams.hasWellLit) !== 1 - ) { - errors.hasWellLit = 'Should be 0 or 1'; - } - } - - if (queryParams.isQuiet) { - if (!isNumber(queryParams.isQuiet)) { - errors.isQuiet = 'Should be a number'; - } else if ( - parseFloat(queryParams.isQuiet) !== 0 && - parseFloat(queryParams.isQuiet) !== 1 - ) { - errors.isQuiet = 'Should be 0 or 1'; - } - } - - if (queryParams.isSpacious) { - if (!isNumber(queryParams.isSpacious)) { - errors.isSpacious = 'Should be a number'; - } else if ( - parseFloat(queryParams.isSpacious) !== 0 && - parseFloat(queryParams.isSpacious) !== 1 - ) { - errors.isSpacious = 'Should be 0 or 1'; - } - } - - if (queryParams.steps) { - if (!isNumber(queryParams.steps)) { - errors.steps = 'Should be a number'; - } else if ( - parseFloat(queryParams.steps) < 0 || - parseFloat(queryParams.steps) > 3 - ) { - errors.steps = 'Should be between 0 and 3'; - } - } + // if (queryParams.hasRamp) { + // if (!isNumber(queryParams.hasRamp)) { + // errors.hasRamp = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.hasRamp) !== 0 && + // parseFloat(queryParams.hasRamp) !== 1 + // ) { + // errors.hasRamp = 'Should be 0 or 1'; + // } + // } + + // if (queryParams.hasSecondEntry) { + // if (!isNumber(queryParams.hasSecondEntry)) { + // errors.hasSecondEntry = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.hasSecondEntry) !== 0 && + // parseFloat(queryParams.hasSecondEntry) !== 1 + // ) { + // errors.hasSecondEntry = 'Should be 0 or 1'; + // } + // } + + // if (queryParams.hasWellLit) { + // if (!isNumber(queryParams.hasWellLit)) { + // errors.hasWellLit = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.hasWellLit) !== 0 && + // parseFloat(queryParams.hasWellLit) !== 1 + // ) { + // errors.hasWellLit = 'Should be 0 or 1'; + // } + // } + + // if (queryParams.isQuiet) { + // if (!isNumber(queryParams.isQuiet)) { + // errors.isQuiet = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.isQuiet) !== 0 && + // parseFloat(queryParams.isQuiet) !== 1 + // ) { + // errors.isQuiet = 'Should be 0 or 1'; + // } + // } + + // if (queryParams.isSpacious) { + // if (!isNumber(queryParams.isSpacious)) { + // errors.isSpacious = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.isSpacious) !== 0 && + // parseFloat(queryParams.isSpacious) !== 1 + // ) { + // errors.isSpacious = 'Should be 0 or 1'; + // } + // } + + // if (queryParams.steps) { + // if (!isNumber(queryParams.steps)) { + // errors.steps = 'Should be a number'; + // } else if ( + // parseFloat(queryParams.steps) < 0 || + // parseFloat(queryParams.steps) > 3 + // ) { + // errors.steps = 'Should be between 0 and 3'; + // } + // } if (queryParams.type && !placesTypes.includes(queryParams.type)) { errors.type = 'Should be a valid type'; From 6d59317d035ec1f289b621bf0431264c17f70f49 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Fri, 29 Aug 2025 16:31:37 +0500 Subject: [PATCH 57/67] user avatar saved --- src/routes/auth/facebook-sign-in.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 018bacf..85af8cd 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -45,15 +45,15 @@ module.exports = async (req, res, next) => { let user = await User.findOne({ fbId: fbUser.id }); - const [firstName, lastName] = fbUser.name.split(" "); - + if (!user) { + const [firstName, lastName] = fbUser.name.split(" "); user = new User({ fbId: fbUser.id, email, firstName: firstName || "", lastName: lastName || "", - picture: fbUser.picture.data.url, + avatar: fbUser.picture.data.url, }); await user.save(); From 65b96172455d4e3e17c86f9bf5781654a23f4f7b Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 1 Sep 2025 12:25:54 +0500 Subject: [PATCH 58/67] add facebook login api for mobile --- src/routes/auth/facebook-sign-in.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 85af8cd..51ddd8d 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -30,6 +30,20 @@ module.exports = async (req, res, next) => { } ); + token = tokenResponse.data.access_token; + } else { + const tokenResponse = await axios.get( + "https://graph.facebook.com/v17.0/oauth/access_token", + { + params: { + client_id: process.env.FACEBOOK_CLIENT_ID, + client_secret: process.env.FACEBOOK_CLIENT_SECRET, + grant_type: 'fb_exchange_token', + fb_exchange_token: req.body.code, + }, + } + ); + token = tokenResponse.data.access_token; } const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { @@ -45,7 +59,6 @@ module.exports = async (req, res, next) => { let user = await User.findOne({ fbId: fbUser.id }); - if (!user) { const [firstName, lastName] = fbUser.name.split(" "); user = new User({ From 60529cc8f3a1da7a9ff75a98651689c8ee012501 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 1 Sep 2025 15:29:44 +0500 Subject: [PATCH 59/67] add facebook login api for mobile --- src/routes/auth/facebook-sign-in.js | 32 ++++++++++------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 51ddd8d..7f97040 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -30,30 +30,20 @@ module.exports = async (req, res, next) => { } ); - token = tokenResponse.data.access_token; - } else { - const tokenResponse = await axios.get( - "https://graph.facebook.com/v17.0/oauth/access_token", - { - params: { - client_id: process.env.FACEBOOK_CLIENT_ID, - client_secret: process.env.FACEBOOK_CLIENT_SECRET, - grant_type: 'fb_exchange_token', - fb_exchange_token: req.body.code, - }, - } - ); - token = tokenResponse.data.access_token; } - const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { - params: { - access_token: token, - fields: "id,name,email,picture", - }, - }); + + let fbUser = req.body?.profile || {}; + if (!req.body.ios) { + const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { + params: { + access_token: token, + fields: "id,name,email,picture", + }, + }); - const fbUser = fbUserResponse.data; + fbUser = fbUserResponse.data; + } if (fbUser.email) { const email = fbUser.email; From 6aa1a1ba9a788c24fa97fdb52ac6fc5ccec3b164 Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 1 Sep 2025 15:32:49 +0500 Subject: [PATCH 60/67] add facebook login api for mobile --- src/routes/auth/facebook-sign-in.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 7f97040..8272b7a 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -10,12 +10,12 @@ const { User } = require("../../models/user"); const { validateFacebookSignIn } = require("./validations"); module.exports = async (req, res, next) => { - const { errors, isValid } = validateFacebookSignIn(req.body); - if (!isValid) { - return res.status(400).json(errors); - } + // const { errors, isValid } = validateFacebookSignIn(req.body); + // if (!isValid) { + // return res.status(400).json(errors); + // } - let token = req.body.code; + let token = req?.body?.code; try { if (req.body.web) { const tokenResponse = await axios.get( @@ -32,7 +32,7 @@ module.exports = async (req, res, next) => { token = tokenResponse.data.access_token; } - + let fbUser = req.body?.profile || {}; if (!req.body.ios) { const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { @@ -44,7 +44,7 @@ module.exports = async (req, res, next) => { fbUser = fbUserResponse.data; } - if (fbUser.email) { + if (fbUser?.email) { const email = fbUser.email; let user = await User.findOne({ fbId: fbUser.id }); From c4f4632019c230a950fdae7061d0df3b02d0b1bb Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Mon, 1 Sep 2025 15:57:09 +0500 Subject: [PATCH 61/67] add facebook login api for mobile --- src/routes/auth/facebook-sign-in.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 8272b7a..0aec2c3 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -34,7 +34,7 @@ module.exports = async (req, res, next) => { } let fbUser = req.body?.profile || {}; - if (!req.body.ios) { + if (!req.body?.profile) { const fbUserResponse = await axios.get(`https://graph.facebook.com/me`, { params: { access_token: token, @@ -47,7 +47,7 @@ module.exports = async (req, res, next) => { if (fbUser?.email) { const email = fbUser.email; - let user = await User.findOne({ fbId: fbUser.id }); + let user = await User.findOne({ email: fbUser.email }); if (!user) { const [firstName, lastName] = fbUser.name.split(" "); From 66b564d7a1ac43a3f1ec2c1a85ff29e943edcafb Mon Sep 17 00:00:00 2001 From: abdul-rehman90 <> Date: Tue, 2 Sep 2025 18:06:10 +0500 Subject: [PATCH 62/67] add apple subscription for ios and send mail --- src/helpers/mail-template.js | 72 +++++++++++++++ src/models/donations.js | 24 +++++ src/routes/donatins/apple.webhook.js | 63 +++++++++++++ src/routes/donatins/donation.js | 126 ++++++++++++++++++++++++++ src/routes/donatins/google.webhook.js | 41 +++++++++ src/routes/donatins/index.js | 16 ++++ src/routes/index.js | 40 ++++---- 7 files changed, 363 insertions(+), 19 deletions(-) create mode 100644 src/models/donations.js create mode 100644 src/routes/donatins/apple.webhook.js create mode 100644 src/routes/donatins/donation.js create mode 100644 src/routes/donatins/google.webhook.js create mode 100644 src/routes/donatins/index.js diff --git a/src/helpers/mail-template.js b/src/helpers/mail-template.js index 6cdd100..bbb4960 100644 --- a/src/helpers/mail-template.js +++ b/src/helpers/mail-template.js @@ -155,8 +155,80 @@ const adminServeyMailTemplate = (name, email, answers) => { `; }; +const donationMailTemplate = (name) => { + return ` + + + + + + + +
+ + + + + + + + + + + + + + + + +
+

Thank You for Supporting AXS Map 🙏

+

Here’s your exclusive content

+
+

+ Hi ${name}, +

+ +

+ Thank you so much for supporting AXS Map. Your generosity helps us continue making accessibility more visible and empowering communities everywhere. +

+ +

+ As a token of our appreciation, we’re sharing exclusive content just for our donors. You can access it through this private playlist: +

+ + + +

+ Please keep this link private, as it’s reserved for supporters like you. +

+ +

+ We’re grateful to have you with us on this journey toward a more accessible world. Enjoy the content, and thank you again for being part of the AXS Map community. +

+ +

+ With gratitude,
The AXS Map Team +

+
+

+ Need help? Contact Support +

+

© 2025 AXS MAP. All rights reserved.

+
+
+ + +`; +}; + module.exports = { activationEmailTemplate, submitServeyUserMailTemplate, adminServeyMailTemplate, + donationMailTemplate, }; diff --git a/src/models/donations.js b/src/models/donations.js new file mode 100644 index 0000000..fa4cb67 --- /dev/null +++ b/src/models/donations.js @@ -0,0 +1,24 @@ +const mongoose = require("mongoose"); + +const donation = new mongoose.Schema({ + userId: { type: String, required: true }, + type: { type: String, enum: ["one_time", "monthly"], required: true }, + productId: String, // e.g. "monthlysupporter" or "donation_small" + transactionId: String, // Apple transaction ID + originalTransactionId: String, // same for subscription renewals + amount: Number, // optional, from Apple response + currency: String, // optional + country: String, // optional + status: { + type: String, + enum: ["purchased", "renewed", "canceled", "refunded"], + }, + platform: String, + purchasedAt: { type: Date, default: Date.now }, + expiresAt: Date, // only for subscriptions +}); + +module.exports = { + Donations: mongoose.model("Donations", donation), + donation, +}; diff --git a/src/routes/donatins/apple.webhook.js b/src/routes/donatins/apple.webhook.js new file mode 100644 index 0000000..0efbbc7 --- /dev/null +++ b/src/routes/donatins/apple.webhook.js @@ -0,0 +1,63 @@ +// services/apple.js +const axios = require("axios"); + +const APPLE_PROD = "https://buy.itunes.apple.com/verifyReceipt"; +const APPLE_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt"; + +async function verifyAppleReceipt(base64Receipt) { + const body = { + "receipt-data": base64Receipt, + password: process.env.APPLE_SHARED_SECRET, + "exclude-old-transactions": true, + }; + + // Try production then fallback to sandbox on 21007 + + const tryVerify = async (url) => + (await axios.post(url, body, { timeout: 10000 })).data; + + let data = await tryVerify(APPLE_PROD); + if (data.status === 21007) data = await tryVerify(APPLE_SANDBOX); + + if (data.status !== 0) { + const err = new Error(`Apple verify failed: status ${data.status}`); + err.apple = data; + throw err; + } + return data; +} + +// Extract latest transaction for a given product (auto-renewing sub) +function pickLatestForProduct(receipt, productId) { + const items = (receipt.latest_receipt_info || []).filter( + (i) => i.product_id === productId + ); + if (!items.length) return null; + + // newest by expires date if present, else by purchase date + const sorted = items.sort((a, b) => { + const aExp = Number(a.expires_date_ms || 0); + const bExp = Number(b.expires_date_ms || 0); + return bExp - aExp; + }); + + const latest = sorted[0]; + const pending = (receipt.pending_renewal_info || []).find( + (p) => p.product_id === productId + ); + return { + transactionId: latest.transaction_id, + originalTransactionId: latest.original_transaction_id, + purchasedAt: new Date(Number(latest.purchase_date_ms)), + expiresAt: latest.expires_date_ms + ? new Date(Number(latest.expires_date_ms)) + : undefined, + willRenew: pending + ? pending.auto_renew_status === "1" + : Boolean(latest.expires_date_ms), + environment: receipt.environment?.toLowerCase() || "production", + raw: { latest, pending }, + }; +} + +module.exports = { verifyAppleReceipt, pickLatestForProduct }; diff --git a/src/routes/donatins/donation.js b/src/routes/donatins/donation.js new file mode 100644 index 0000000..ad16601 --- /dev/null +++ b/src/routes/donatins/donation.js @@ -0,0 +1,126 @@ +// services/apple.js +const axios = require("axios"); +const { Donations } = require("../../models/donations"); +const { sendEmail } = require("../../helpers"); +const { donationMailTemplate } = require("../../helpers/mail-template"); + +const APPLE_PROD = "https://buy.itunes.apple.com/verifyReceipt"; +const APPLE_SANDBOX = "https://sandbox.itunes.apple.com/verifyReceipt"; + +async function verifyAppleReceipt(receipt) { + const payload = { + "receipt-data": receipt, + password: process.env.APP_SHARED_SECRET, // only needed for subscriptions + "exclude-old-transactions": true, + }; + + try { + // let response = await axios.post("https://buy.itunes.apple.com/verifyReceipt", payload, { + // headers: { "Content-Type": "application/json" } + // }); + + response = await axios.post(APPLE_SANDBOX, payload, { + headers: { "Content-Type": "application/json" }, + }); + + return response.data; + } catch (err) { + console.error("Apple verification failed", err); + throw err; + } +} + +async function purchaseProduct(req, res) { + try { + const receipt = await verifyAppleReceipt(req.body.transactionReceipt); + if (receipt.status === 0 || receipt?.environment === "Sandbox") { + const alreadyExists = await Donations.findOne({ + userId: req.user.id, + transactionId: req.body.transactionId, + }); + if (alreadyExists) { + return res.status(400).json({ message: "Already purchased" }); + } + sendEmail({ + receiversEmails: [req.user?.email], + subject: + "Thank You for Supporting AXS Map – Here’s Your Exclusive Content", + htmlContent: donationMailTemplate({ + name: req.user?.firstName + " " + req.user?.lastName, + }), + }); + // if (receipt?.environment === "Sandbox") + // return res.status(400).json({ message: "Apple verification failed" }); + + const result = await Donations.create({ + userId: req.user.id, + amount: req.body.amount, + type: "one_time", + currency: req.body.currency, + productId: req.body.productId, + transactionId: req.body.transactionId, + receipt: req.body.transactionReceipt, + status: "purchased", + purchasedAt: req?.body?.transactionDate, + country: req?.body?.country, + platform: req?.body?.platform, + }); + return res.status(200).json({ result }); + } else { + return res.status(400).json({ message: "verification failed" }); + } + } catch (error) { + console.log(error); + res.status(400).json({ message: "Apple verification failed" }); + } +} + +async function purchaseSubscription(req, res) { + try { + const receipt = + req.body.platform === "ios" + ? await verifyAppleReceipt(req.body.transactionReceipt) + : { receipt: { status: 0 } }; + // if (receipt.status !== 0 || receipt?.environment !== "Sandbox") { + // return res.status(400).json({ message: "verification failed" }); + // } + const alreadyExists = await Donations.findOne({ + userId: req.user.id, + transactionId: req.body.transactionId, + }); + if (alreadyExists) { + return res.status(400).json({ message: "Already purchased" }); + } + sendEmail({ + receiversEmails: [req.user?.email], + subject: + "Thank You for Supporting AXS Map – Here’s Your Exclusive Content", + htmlContent: donationMailTemplate({ + name: req.user?.firstName + " " + req.user?.lastName, + }), + }); + // if (receipt?.environment === "Sandbox") + // return res.status(400).json({ message: "Apple verification failed" }); + + const result = await Donations.create({ + userId: req.user.id, + amount: req.body.amount, + type: "monthly", + currency: req.body.currency, + productId: req.body.productId, + transactionId: req.body.transactionId, + originalTransactionId: req.body?.originalTransactionIdentifierIOS, + receipt: req.body.transactionReceipt, + status: "purchased", + purchasedAt: req?.body?.transactionDate, + country: req?.body?.country, + platform: req?.body?.platform, + }); + return res.status(200).json({ result }); + } catch (error) { + console.log(error); + res.status(400).json({ message: "Apple verification failed" }); + } +} + +module.exports = { purchaseProduct, purchaseSubscription }; diff --git a/src/routes/donatins/google.webhook.js b/src/routes/donatins/google.webhook.js new file mode 100644 index 0000000..b0e7f62 --- /dev/null +++ b/src/routes/donatins/google.webhook.js @@ -0,0 +1,41 @@ +// services/google.js +const { google } = require('googleapis'); + +async function androidPublisher() { + const auth = new google.auth.GoogleAuth({ + scopes: ['https://www.googleapis.com/auth/androidpublisher'], + keyFile: process.env.GOOGLE_SERVICE_ACCOUNT_JSON, + }); + const client = await auth.getClient(); + return google.androidpublisher({ version: 'v3', auth: client }); +} + +async function verifyAndroidProduct(productId, purchaseToken) { + const api = await androidPublisher(); + const res = await api.purchases.products.get({ + packageName: process.env.GOOGLE_PACKAGE_NAME, + productId, + token: purchaseToken, + }); + return res.data; // purchaseState, consumptionState, orderId... +} + +async function verifyAndroidSubscription(productId, purchaseToken) { + const api = await androidPublisher(); + const res = await api.purchases.subscriptions.get({ + packageName: process.env.GOOGLE_PACKAGE_NAME, + subscriptionId: productId, + token: purchaseToken, + }); + return res.data; // expiryTimeMillis, autoRenewing, paymentState, cancelReason... +} + +function mapAndroidStatus(d) { + // subscriptions + const expiresAt = d.expiryTimeMillis ? new Date(Number(d.expiryTimeMillis)) : undefined; + const willRenew = Boolean(d.autoRenewing); + // purchaseState: 0 purchased, 1 canceled, 2 pending (for INAPP) + return { expiresAt, willRenew }; +} + +module.exports = { verifyAndroidProduct, verifyAndroidSubscription, mapAndroidStatus }; diff --git a/src/routes/donatins/index.js b/src/routes/donatins/index.js new file mode 100644 index 0000000..693721a --- /dev/null +++ b/src/routes/donatins/index.js @@ -0,0 +1,16 @@ +const express = require("express"); +const { purchaseProduct, purchaseSubscription } = require("./donation"); +const { isAuthenticated } = require("../../helpers"); + +const router = new express.Router(); + +router.post("/product", isAuthenticated({ isOptional: false }), purchaseProduct); +router.post( + "/subscription", + isAuthenticated({ isOptional: false }), + purchaseSubscription +); +// router.post("/apple-webhook", appleSignin); +// router.post("/google-webhook", appleSignin); + +module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js index b7e0aae..c8ace7c 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -1,25 +1,27 @@ -const express = require('express'); +const express = require("express"); -const auth = require('./auth'); -const events = require('./events'); -const others = require('./others'); -const petitions = require('./petitions'); -const photos = require('./photos'); -const reviews = require('./reviews'); -const teams = require('./teams'); -const users = require('./users'); -const venues = require('./venues'); +const auth = require("./auth"); +const events = require("./events"); +const others = require("./others"); +const petitions = require("./petitions"); +const photos = require("./photos"); +const reviews = require("./reviews"); +const teams = require("./teams"); +const users = require("./users"); +const venues = require("./venues"); +const donations = require("./donatins"); const router = new express.Router(); -router.use('', others); -router.use('/auth', auth); -router.use('/events', events); -router.use('/petitions', petitions); -router.use('/photos', photos); -router.use('/reviews', reviews); -router.use('/teams', teams); -router.use('/users', users); -router.use('/venues', venues); +router.use("", others); +router.use("/auth", auth); +router.use("/events", events); +router.use("/petitions", petitions); +router.use("/photos", photos); +router.use("/reviews", reviews); +router.use("/teams", teams); +router.use("/users", users); +router.use("/venues", venues); +router.use("/donations", donations); module.exports = router; From 523c8e91b26798b4887ec0558ab8c75a663ab3a6 Mon Sep 17 00:00:00 2001 From: Abdul Rehman Date: Fri, 3 Oct 2025 15:28:35 +0500 Subject: [PATCH 63/67] allow repeating names for events --- package-lock.json | 3697 +++++++++++++++++++---------- src/routes/events/create-event.js | 12 - 2 files changed, 2469 insertions(+), 1240 deletions(-) diff --git a/package-lock.json b/package-lock.json index e937042..c61f639 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,53 +54,41 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "optional": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", "dev": true, + "license": "MIT", "optional": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@commitlint/config-validator": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.0.3.tgz", - "integrity": "sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==", + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-20.0.0.tgz", + "integrity": "sha512-BeyLMaRIJDdroJuYM2EGhDMGwVBMZna9UiIqV9hxj+J551Ctc6yoGuGSmghOy/qPhBSuhA6oMtbEiTmxECafsg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "@commitlint/types": "^19.0.3", + "@commitlint/types": "^20.0.0", "ajv": "^8.11.0" }, "engines": { @@ -108,29 +96,31 @@ } }, "node_modules/@commitlint/execute-rule": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.0.0.tgz", - "integrity": "sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==", + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-20.0.0.tgz", + "integrity": "sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=v18" } }, "node_modules/@commitlint/load": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.2.0.tgz", - "integrity": "sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-20.1.0.tgz", + "integrity": "sha512-qo9ER0XiAimATQR5QhvvzePfeDfApi/AFlC1G+YN+ZAY8/Ua6IRrDrxRvQAr+YXUKAxUsTDSp9KXeXLBPsNRWg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "@commitlint/config-validator": "^19.0.3", - "@commitlint/execute-rule": "^19.0.0", - "@commitlint/resolve-extends": "^19.1.0", - "@commitlint/types": "^19.0.3", + "@commitlint/config-validator": "^20.0.0", + "@commitlint/execute-rule": "^20.0.0", + "@commitlint/resolve-extends": "^20.1.0", + "@commitlint/types": "^20.0.0", "chalk": "^5.3.0", "cosmiconfig": "^9.0.0", - "cosmiconfig-typescript-loader": "^5.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0" @@ -140,10 +130,11 @@ } }, "node_modules/@commitlint/load/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -153,14 +144,15 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.1.0.tgz", - "integrity": "sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-20.1.0.tgz", + "integrity": "sha512-cxKXQrqHjZT3o+XPdqDCwOWVFQiae++uwd9dUBC7f2MdV58ons3uUvASdW7m55eat5sRiQ6xUHyMWMRm6atZWw==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "@commitlint/config-validator": "^19.0.3", - "@commitlint/types": "^19.0.3", + "@commitlint/config-validator": "^20.0.0", + "@commitlint/types": "^20.0.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", @@ -171,10 +163,11 @@ } }, "node_modules/@commitlint/types": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.0.3.tgz", - "integrity": "sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==", + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-20.0.0.tgz", + "integrity": "sha512-bVUNBqG6aznYcYjTjnc3+Cat/iBgbgpflxbIBTnsHTX0YVpnmINPEkSRWymT2Q8aSH3Y7aKnEbunilkYe8TybA==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/conventional-commits-parser": "^5.0.0", @@ -185,10 +178,11 @@ } }, "node_modules/@commitlint/types/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -198,16 +192,20 @@ } }, "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==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -217,6 +215,7 @@ "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, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -225,21 +224,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -248,12 +249,13 @@ } }, "node_modules/@eslint/config-array/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -264,11 +266,42 @@ } } }, + "node_modules/@eslint/config-array/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -292,6 +325,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -304,12 +338,13 @@ } }, "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -325,6 +360,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -332,35 +368,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "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" - } - }, "node_modules/@eslint/eslintrc/node_modules/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 + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/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==", + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", - "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", + "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -370,6 +424,7 @@ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -379,6 +434,7 @@ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", "dev": true, + "license": "MIT", "dependencies": { "is-negated-glob": "^1.0.0" }, @@ -386,11 +442,36 @@ "node": ">=10.13.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, "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, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -400,10 +481,11 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -416,6 +498,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "bmp-js": "^0.1.0" @@ -428,6 +511,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "any-base": "^1.1.0", @@ -457,6 +541,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -466,6 +551,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", + "license": "MIT", "dependencies": { "@jimp/core": "^0.22.12" } @@ -474,6 +560,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz", "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "gifwrap": "^0.10.1", @@ -487,6 +574,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz", "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "jpeg-js": "^0.4.4" @@ -499,6 +587,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz", "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -510,6 +599,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz", "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -521,6 +611,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz", "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -532,6 +623,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz", "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "tinycolor2": "^1.6.0" @@ -544,6 +636,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz", "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -558,6 +651,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz", "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -572,6 +666,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz", "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -583,6 +678,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz", "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -594,6 +690,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz", "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -605,6 +702,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz", "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -616,6 +714,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz", "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -628,6 +727,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz", "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -639,6 +739,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz", "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -650,6 +751,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz", "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -661,6 +763,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz", "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -672,6 +775,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz", "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "load-bmfont": "^1.4.1" @@ -685,6 +789,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz", "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -696,6 +801,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz", "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -710,6 +816,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz", "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -722,6 +829,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz", "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -735,6 +843,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz", "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12" }, @@ -748,6 +857,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz", "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==", + "license": "MIT", "dependencies": { "@jimp/plugin-blit": "^0.22.12", "@jimp/plugin-blur": "^0.22.12", @@ -780,6 +890,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz", "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==", + "license": "MIT", "dependencies": { "@jimp/utils": "^0.22.12", "pngjs": "^6.0.0" @@ -792,6 +903,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz", "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==", + "license": "MIT", "dependencies": { "utif2": "^4.0.1" }, @@ -803,6 +915,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz", "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==", + "license": "MIT", "dependencies": { "@jimp/bmp": "^0.22.12", "@jimp/gif": "^0.22.12", @@ -819,117 +932,97 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.3" } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz", - "integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.1.tgz", + "integrity": "sha512-6nZrq5kfAz0POWyhljnbWQQJQ5uT8oE2ddX303q1uY0tWsivWKgBDXBBvuFPwOqRRalXJuVO9EjOdVtuhLX0zg==", + "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } }, - "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/@tokenizer/token": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" }, "node_modules/@types/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", + "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.11", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.11.tgz", - "integrity": "sha512-sVBpJMf7UPo/wGecYOpk2aQya2VUGeHhe38WG7/mN5FufNSubf5VT9Uh9Uyp8/eLJpu1/tuhJ/qTo4mhSB4V4Q==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "24.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.6.2.tgz", + "integrity": "sha512-d2L25Y4j+W3ZlNAeMKcy7yDsK425ibcAOO2t7aPTz6gNMH0z2GThtwENCDc0d/Pw9wgyRqE5Px1wkV7naz8ang==", + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~7.13.0" } }, "node_modules/@types/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", "license": "MIT", "dependencies": { "@types/node": "*", - "form-data": "^4.0.0" + "form-data": "^4.0.4" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" } @@ -950,6 +1043,7 @@ "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==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -959,10 +1053,11 @@ } }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -975,37 +1070,20 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dependencies": { - "debug": "^4.3.4" - }, + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", "engines": { "node": ">= 14" } }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/agentkeepalive": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", @@ -1023,6 +1101,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "fast-deep-equal": "^3.1.3", @@ -1040,6 +1119,7 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-wrap": "^0.1.0" }, @@ -1052,6 +1132,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1067,6 +1148,7 @@ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", "dev": true, + "license": "MIT", "dependencies": { "ansi-wrap": "0.1.0" }, @@ -1079,6 +1161,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1088,6 +1171,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -1100,6 +1184,7 @@ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1107,13 +1192,15 @@ "node_modules/any-base": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1127,6 +1214,7 @@ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", "dev": true, + "license": "MIT", "dependencies": { "buffer-equal": "^1.0.0" }, @@ -1139,6 +1227,7 @@ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.4" }, @@ -1149,7 +1238,8 @@ "node_modules/append-field": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", - "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" + "integrity": "sha512-8BgHoIwbQZaAQgDZLBu2vQoXHgUpSx4vQK1qv7e6R8YfbiSf4fCaBPJRtM1BaxVn1rIHc5ftv0cklsJ78BkouQ==", + "license": "MIT" }, "node_modules/apple-signin-auth": { "version": "2.0.0", @@ -1168,19 +1258,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/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 + "dev": true, + "license": "Python-2.0" }, "node_modules/arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1190,6 +1283,7 @@ "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", "dev": true, + "license": "MIT", "dependencies": { "make-iterator": "^1.0.0" }, @@ -1202,6 +1296,7 @@ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1211,6 +1306,7 @@ "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", "dev": true, + "license": "MIT", "dependencies": { "make-iterator": "^1.0.0" }, @@ -1223,6 +1319,7 @@ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1232,6 +1329,7 @@ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1239,13 +1337,15 @@ "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" }, "node_modules/array-initial": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", "dev": true, + "license": "MIT", "dependencies": { "array-slice": "^1.0.0", "is-number": "^4.0.0" @@ -1259,6 +1359,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1268,6 +1369,7 @@ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^4.0.0" }, @@ -1280,6 +1382,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1289,6 +1392,7 @@ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1298,6 +1402,7 @@ "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", "dev": true, + "license": "MIT", "dependencies": { "default-compare": "^1.0.0", "get-value": "^2.0.6", @@ -1312,6 +1417,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1321,6 +1427,7 @@ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1339,6 +1446,7 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1348,6 +1456,7 @@ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.4", "once": "^1.4.0", @@ -1367,13 +1476,15 @@ "type": "individual", "url": "https://paulmillr.com/funding/" } - ] + ], + "license": "MIT" }, "node_modules/async-settle": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0" }, @@ -1384,13 +1495,15 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "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, + "license": "ISC", "engines": { "node": ">= 4.0.0" } @@ -1400,6 +1513,7 @@ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, + "license": "(MIT OR Apache-2.0)", "bin": { "atob": "bin/atob.js" }, @@ -1411,6 +1525,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -1426,6 +1541,7 @@ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1660.0.tgz", "integrity": "sha512-nyCEm6J4exq4gxeK5/LB5Q9unQTzFy6fbFHnrrmJZvp1KnRbJ10W2UtwQmeibPAz9b4w+RTKJMe6QEZ38eXeqA==", "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "buffer": "4.9.2", "events": "1.1.1", @@ -1446,6 +1562,7 @@ "version": "1.7.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1453,16 +1570,26 @@ } }, "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } }, "node_modules/bach": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0", "async-settle": "^2.0.0", @@ -1473,23 +1600,25 @@ } }, "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, - "optional": true + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", + "integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, + "license": "MIT", "dependencies": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -1508,6 +1637,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -1520,6 +1650,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -1545,12 +1676,14 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, @@ -1561,18 +1694,20 @@ "node_modules/basic-auth/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/bcrypt-nodejs": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", - "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=", + "integrity": "sha512-NmTbLm867btBHCBZ222FQXkQKzecB0KG6pTXFa6NeTVZaSnLfCsx7EK2PL3J+kX8xJThUquEBbhimRCKKZX9zA==", "deprecated": "bcrypt-nodejs is no longer actively maintained. Please use bcrypt or bcryptjs. See https://github.com/kelektiv/node.bcrypt.js/wiki/bcrypt-vs-brypt.js to learn more about these two options" }, "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", "engines": { "node": "*" } @@ -1582,6 +1717,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1594,6 +1730,7 @@ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "file-uri-to-path": "1.0.0" @@ -1604,6 +1741,7 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -1629,6 +1767,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -1639,6 +1778,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1653,6 +1793,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -1660,12 +1801,14 @@ "node_modules/bmp-js": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" + "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", + "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -1685,22 +1828,12 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/body-parser/node_modules/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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1711,6 +1844,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1719,9 +1853,10 @@ } }, "node_modules/bson": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", - "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "version": "6.10.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.4.tgz", + "integrity": "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng==", + "license": "Apache-2.0", "engines": { "node": ">=16.20.1" } @@ -1730,6 +1865,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "license": "MIT", "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -1740,6 +1876,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -1747,12 +1884,14 @@ "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" }, "node_modules/busboy": { "version": "0.2.14", @@ -1770,6 +1909,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -1779,6 +1919,7 @@ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, + "license": "MIT", "dependencies": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -1799,20 +1940,50 @@ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.0", "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" + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -1826,6 +1997,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1835,6 +2007,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1843,6 +2016,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/centra/-/centra-2.7.0.tgz", "integrity": "sha512-PbFMgMSrmgx6uxCdm57RUos9Tc3fclMvhLSATYN39XsDV29B89zZ3KA89jmY0vwSGazyU+uerqwa6t+KaodPcg==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6" } @@ -1852,6 +2026,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1865,12 +2040,14 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "license": "BSD-3-Clause", "engines": { "node": "*" } @@ -1880,6 +2057,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1904,6 +2082,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -1916,6 +2095,7 @@ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, + "license": "MIT", "dependencies": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -1931,6 +2111,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, + "license": "MIT", "dependencies": { "restore-cursor": "^3.1.0" }, @@ -1943,6 +2124,7 @@ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -1955,6 +2137,7 @@ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", "dev": true, + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" @@ -1967,10 +2150,11 @@ } }, "node_modules/cli-truncate/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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1979,16 +2163,18 @@ } }, "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "dev": true, + "license": "MIT" }, "node_modules/cli-truncate/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -2002,10 +2188,11 @@ } }, "node_modules/cli-truncate/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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2021,6 +2208,7 @@ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10" } @@ -2030,6 +2218,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -2041,6 +2230,7 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -2050,6 +2240,7 @@ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -2058,13 +2249,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cloneable-readable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "process-nextick-args": "^2.0.0", @@ -2076,6 +2269,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2090,13 +2284,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cloneable-readable/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -2106,6 +2302,7 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2115,6 +2312,7 @@ "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", "dev": true, + "license": "MIT", "dependencies": { "arr-map": "^2.0.2", "for-own": "^1.0.0", @@ -2129,6 +2327,7 @@ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", "dev": true, + "license": "MIT", "dependencies": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -2142,6 +2341,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -2150,13 +2350,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, + "license": "ISC", "bin": { "color-support": "bin.js" } @@ -2165,13 +2367,15 @@ "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.1.90" } @@ -2180,6 +2384,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2192,6 +2397,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } @@ -2201,6 +2407,7 @@ "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-4.3.0.tgz", "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==", "dev": true, + "license": "MIT", "dependencies": { "cachedir": "2.3.0", "cz-conventional-changelog": "3.3.0", @@ -2226,29 +2433,12 @@ "node": ">= 12" } }, - "node_modules/commitizen/node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/commitizen/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/component-emitter": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" } @@ -2256,8 +2446,9 @@ "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": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" }, "node_modules/concat-stream": { "version": "1.6.2", @@ -2266,6 +2457,7 @@ "engines": [ "node >= 0.8" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -2274,9 +2466,10 @@ } }, "node_modules/concat-stream/node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2290,12 +2483,14 @@ "node_modules/concat-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -2304,6 +2499,7 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -2315,6 +2511,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2323,18 +2520,21 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-3.0.0.tgz", "integrity": "sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2342,13 +2542,15 @@ "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==", + "license": "MIT" }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2358,6 +2560,7 @@ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", "dev": true, + "license": "MIT", "dependencies": { "each-props": "^3.0.0", "is-plain-object": "^5.0.0" @@ -2367,14 +2570,16 @@ } }, "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, "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==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -2388,6 +2593,7 @@ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "env-paths": "^2.2.1", @@ -2411,40 +2617,22 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz", - "integrity": "sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz", + "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { - "jiti": "^1.19.1" + "jiti": "^2.4.1" }, "engines": { - "node": ">=v16" + "node": ">=v18" }, "peerDependencies": { "@types/node": "*", - "cosmiconfig": ">=8.2", - "typescript": ">=4" - } - }, - "node_modules/cosmiconfig/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "optional": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "cosmiconfig": ">=9", + "typescript": ">=5" } }, "node_modules/cross-env": { @@ -2452,6 +2640,7 @@ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.1" }, @@ -2466,10 +2655,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2482,7 +2672,8 @@ "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "license": "BSD-3-Clause", "engines": { "node": "*" } @@ -2492,6 +2683,7 @@ "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-3.3.0.tgz", "integrity": "sha512-U466fIzU5U22eES5lTNiNbZ+d8dfcHcssH4o7QsdWaCcRs/feIPCxKYSWkYBNs5mny7MvEfwpTLWjvbm94hecw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^2.4.1", "commitizen": "^4.0.3", @@ -2512,6 +2704,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", "dev": true, + "license": "ISC", "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" @@ -2524,20 +2717,17 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, - "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/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2547,6 +2737,7 @@ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } @@ -2555,19 +2746,22 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/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 + "dev": true, + "license": "MIT" }, "node_modules/default-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^5.0.2" }, @@ -2580,6 +2774,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2589,6 +2784,7 @@ "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -2598,6 +2794,7 @@ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^1.0.2" }, @@ -2610,6 +2807,7 @@ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -2618,6 +2816,7 @@ "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==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2635,6 +2834,7 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -2652,6 +2852,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^0.1.0" }, @@ -2663,6 +2864,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -2671,6 +2873,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2679,6 +2882,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -2689,6 +2893,7 @@ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2698,6 +2903,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2723,6 +2929,7 @@ "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -2730,11 +2937,26 @@ "url": "https://dotenvx.com" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/duplexify": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", @@ -2747,6 +2969,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2761,6 +2984,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -2770,6 +2994,7 @@ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^5.0.0", "object.defaults": "^1.1.0" @@ -2782,6 +3007,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" } @@ -2789,27 +3015,31 @@ "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==", + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" } @@ -2819,27 +3049,40 @@ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "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" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -2848,20 +3091,49 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "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", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "hasInstallScript": true, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "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", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", "next-tick": "^1.1.0" }, "engines": { @@ -2873,6 +3145,7 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "^0.10.35", @@ -2884,6 +3157,7 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", "dev": true, + "license": "ISC", "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" @@ -2897,6 +3171,7 @@ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, + "license": "ISC", "dependencies": { "d": "1", "es5-ext": "^0.10.46", @@ -2905,10 +3180,11 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2916,39 +3192,47 @@ "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==", + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz", - "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==", + "version": "9.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", + "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.7.0", + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.36.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2958,15 +3242,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "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.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -2976,13 +3256,22 @@ }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2995,10 +3284,11 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -3011,6 +3301,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -3027,6 +3318,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -3042,6 +3334,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3058,6 +3351,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -3069,15 +3363,17 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/eslint/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3093,22 +3389,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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" - }, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3121,75 +3402,31 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "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" - } - }, "node_modules/eslint/node_modules/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 - }, - "node_modules/eslint/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/eslint/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" - } + "license": "MIT" }, - "node_modules/eslint/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==", + "node_modules/eslint/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==", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/eslint/node_modules/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, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3202,6 +3439,7 @@ "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", "dev": true, + "license": "ISC", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", @@ -3213,14 +3451,15 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3234,6 +3473,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -3246,6 +3486,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -3258,6 +3499,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3267,6 +3509,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -3275,6 +3518,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3284,6 +3528,7 @@ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "~0.10.14" @@ -3302,21 +3547,34 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "license": "MIT", "engines": { "node": ">=0.4.x" } }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -3340,6 +3598,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -3357,6 +3616,7 @@ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -3375,6 +3635,7 @@ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", "dev": true, + "license": "MIT", "dependencies": { "homedir-polyfill": "^1.0.1" }, @@ -3386,6 +3647,7 @@ "version": "4.19.2", "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -3423,30 +3685,12 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "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, + "license": "ISC", "dependencies": { "type": "^2.7.2" } @@ -3454,13 +3698,15 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" }, "node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dev": true, + "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" }, @@ -3473,6 +3719,7 @@ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, + "license": "MIT", "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -3487,6 +3734,7 @@ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, + "license": "MIT", "dependencies": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -3506,6 +3754,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -3518,6 +3767,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -3527,49 +3777,62 @@ } }, "node_modules/fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", + "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" + "color-support": "^1.1.3" }, "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" } }, "node_modules/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 + "dev": true, + "license": "MIT" }, "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/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 + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", "optional": true }, "node_modules/fastest-levenshtein": { @@ -3577,15 +3840,17 @@ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3595,6 +3860,7 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" }, @@ -3610,6 +3876,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" }, @@ -3621,6 +3888,7 @@ "version": "16.5.4", "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", @@ -3638,6 +3906,7 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/fill-range": { @@ -3645,6 +3914,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3656,6 +3926,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -3669,22 +3940,12 @@ "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/find-node-modules": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-2.1.3.tgz", "integrity": "sha512-UC2I2+nx1ZuOBclWVNdcnbDR5dlrOdVb7xNjmT/lHE+LsgztWks3dG7boJ37yTS/venXw84B/mAW9uHVoC5QRg==", "dev": true, + "license": "MIT", "dependencies": { "findup-sync": "^4.0.0", "merge": "^2.1.1" @@ -3694,31 +3955,24 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "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, + "license": "MIT", "dependencies": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/find-up/node_modules/path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", - "dev": true, - "dependencies": { - "pinkie-promise": "^2.0.0" + "node": ">=10" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/findup-sync": { @@ -3726,6 +3980,7 @@ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", "dev": true, + "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.0", @@ -3741,6 +3996,7 @@ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^5.0.0", @@ -3757,6 +4013,7 @@ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -3766,6 +4023,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -3775,16 +4033,18 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" @@ -3795,6 +4055,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3809,27 +4070,30 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/flush-write-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3840,11 +4104,18 @@ } }, "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", "dependencies": { - "is-callable": "^1.1.3" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/for-in": { @@ -3852,6 +4123,7 @@ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3861,6 +4133,7 @@ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", "dev": true, + "license": "MIT", "dependencies": { "for-in": "^1.0.1" }, @@ -3872,12 +4145,14 @@ "version": "0.0.4", "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", "integrity": "sha512-Pqq5NnT78ehvUnAk/We/Jr22vSvanRlFTpAmQ88xBY/M1TlHe+P0ILuEyXS595ysdGfaj22634LBkGMA2GTcpA==", - "dev": true + "dev": true, + "license": "BSD" }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3910,6 +4185,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3919,6 +4195,7 @@ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", "dev": true, + "license": "MIT", "dependencies": { "map-cache": "^0.2.2" }, @@ -3930,6 +4207,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/freemail/-/freemail-1.7.0.tgz", "integrity": "sha512-XzEdol9AxxwDN5ISi+J560MgQRKTiGOTRFakRQLUQDEjr48hBMzU5Eo7c2U13zzz3IwcaD+54jWHJrg6/wqRNA==", + "license": "ISC", "dependencies": { "tldjs": "^1.5.2" } @@ -3938,6 +4216,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3947,6 +4226,7 @@ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -3962,6 +4242,7 @@ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.8", "streamx": "^2.12.0" @@ -3974,7 +4255,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", @@ -3982,6 +4264,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3994,63 +4277,79 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gaxios": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz", - "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^10.0.0" + "uuid": "^9.0.1" }, "engines": { "node": ">=14" } }, "node_modules/gaxios/node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" ], + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/gcp-metadata": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", - "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", "dependencies": { - "gaxios": "^6.0.0", + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" }, "engines": { "node": ">=14" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "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, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -4059,15 +4358,21 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -4076,11 +4381,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -4093,6 +4412,7 @@ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4101,6 +4421,7 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", + "license": "MIT", "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" @@ -4112,6 +4433,7 @@ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4132,6 +4454,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -4140,10 +4463,11 @@ } }, "node_modules/glob-stream": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", - "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.3.tgz", + "integrity": "sha512-fqZVj22LtFJkHODT+M4N1RJQ3TjnnQhfE9GwZI8qXscYarnhpip70poMldRnP8ipQ/w0B621kOhfc53/J9bd/A==", "dev": true, + "license": "MIT", "dependencies": { "@gulpjs/to-absolute-glob": "^4.0.0", "anymatch": "^3.1.3", @@ -4163,6 +4487,7 @@ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^2.0.0", "chokidar": "^3.5.3" @@ -4175,6 +4500,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "license": "MIT", "dependencies": { "min-document": "^2.19.0", "process": "^0.11.10" @@ -4185,6 +4511,7 @@ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", "dev": true, + "license": "MIT", "optional": true, "dependencies": { "ini": "4.1.1" @@ -4201,6 +4528,7 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, + "license": "MIT", "dependencies": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", @@ -4215,6 +4543,7 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", @@ -4230,13 +4559,15 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4245,10 +4576,11 @@ } }, "node_modules/globals": { - "version": "15.8.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", - "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -4261,6 +4593,7 @@ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", "dev": true, + "license": "MIT", "dependencies": { "sparkles": "^2.1.0" }, @@ -4272,6 +4605,7 @@ "version": "9.11.0", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.11.0.tgz", "integrity": "sha512-epX3ww/mNnhl6tL45EQ/oixsY8JLEgUFoT4A5E/5iAR4esld9Kqv6IJGk7EmGuOgDvaarwF95hU2+v7Irql9lw==", + "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", @@ -4284,31 +4618,22 @@ "node": ">=14" } }, - "node_modules/google-auth-library/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/google-auth-library/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" } }, "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" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4318,12 +4643,14 @@ "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 + "dev": true, + "license": "ISC" }, "node_modules/gtoken": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" @@ -4332,30 +4659,12 @@ "node": ">=14.0.0" } }, - "node_modules/gtoken/node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/gtoken/node_modules/jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, "node_modules/gulp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", "dev": true, + "license": "MIT", "dependencies": { "glob-watcher": "^6.0.0", "gulp-cli": "^3.0.0", @@ -4370,17 +4679,18 @@ } }, "node_modules/gulp-cli": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", - "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.1.0.tgz", + "integrity": "sha512-zZzwlmEsTfXcxRKiCHsdyjZZnFvXWM4v1NqBJSYbuApkvVKivjcmOS2qruAJ+PkEHLFavcDKH40DPc1+t12a9Q==", "dev": true, + "license": "MIT", "dependencies": { "@gulpjs/messages": "^1.1.0", "chalk": "^4.1.2", "copy-props": "^4.0.0", "gulplog": "^2.2.0", "interpret": "^3.1.1", - "liftoff": "^5.0.0", + "liftoff": "^5.0.1", "mute-stdout": "^2.0.0", "replace-homedir": "^2.0.0", "semver-greatest-satisfied-range": "^2.0.0", @@ -4400,6 +4710,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4415,6 +4726,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4431,6 +4743,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4442,13 +4755,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/gulp-cli/node_modules/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -4458,6 +4773,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4466,58 +4782,24 @@ } }, "node_modules/gulp-eslint-new": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-eslint-new/-/gulp-eslint-new-2.2.0.tgz", - "integrity": "sha512-B9sBfILAW563MQM81vxWOMeeNbkZTgZEYiwEVmv3fndB5zmGINlA4wbc4qjgPd4kTCtq0sTlFZJV0fpxl8b5kg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-eslint-new/-/gulp-eslint-new-2.5.0.tgz", + "integrity": "sha512-sEF9dnihZ04oUybO4grpPO0zomJwiAeCKcVyYZouzfArkJut/cVcjN3KA0g9iaX1g05pZhhYTBH6pnrqGTiVOg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.10", - "@types/node": ">=12", "eslint": "8 || 9", "fancy-log": "^2.0.0", "plugin-error": "^2.0.1", - "semver": "^7.6.2", + "semver": "^7.7.2", "ternary-stream": "^3.0.0", - "vinyl-fs": "^4.0.0" + "vinyl-fs": "^4.0.2" }, "engines": { "node": "^12.20 || ^14.13 || >=16" - } - }, - "node_modules/gulp-eslint-new/node_modules/fancy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-2.0.0.tgz", - "integrity": "sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==", - "dev": true, - "dependencies": { - "color-support": "^1.1.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/gulp-eslint-new/node_modules/plugin-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.1.tgz", - "integrity": "sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/gulp-eslint-new/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "@types/node": ">=12" } }, "node_modules/gulp-nodemon": { @@ -4525,6 +4807,7 @@ "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz", "integrity": "sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "colors": "^1.2.1", "gulp": "^4.0.0", @@ -4536,6 +4819,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4545,6 +4829,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, + "license": "ISC", "dependencies": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -4555,6 +4840,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, + "license": "MIT", "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -4567,6 +4853,7 @@ "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.2", @@ -4582,6 +4869,7 @@ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", "dev": true, + "license": "MIT", "dependencies": { "async-done": "^1.2.2" }, @@ -4594,6 +4882,7 @@ "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", "dev": true, + "license": "MIT", "dependencies": { "arr-filter": "^1.1.1", "arr-flatten": "^1.0.1", @@ -4614,6 +4903,7 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4623,6 +4913,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "license": "MIT", "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -4643,8 +4934,8 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -4667,6 +4958,7 @@ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -4677,13 +4969,15 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gulp-nodemon/node_modules/copy-props": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", "dev": true, + "license": "MIT", "dependencies": { "each-props": "^1.3.2", "is-plain-object": "^5.0.0" @@ -4694,6 +4988,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -4707,6 +5002,7 @@ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.1", "object.defaults": "^1.1.0" @@ -4717,6 +5013,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -4724,17 +5021,35 @@ "node": ">=0.10.0" } }, + "node_modules/gulp-nodemon/node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/gulp-nodemon/node_modules/fast-levenshtein": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gulp-nodemon/node_modules/fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dev": true, + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -4750,6 +5065,7 @@ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "dev": true, + "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.0", @@ -4765,6 +5081,7 @@ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.2", "is-plain-object": "^2.0.3", @@ -4781,6 +5098,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -4793,6 +5111,7 @@ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -4802,6 +5121,7 @@ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.11", "through2": "^2.0.3" @@ -4814,9 +5134,10 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2", + "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -4833,13 +5154,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/gulp-nodemon/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -4850,6 +5173,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.0" }, @@ -4862,6 +5186,7 @@ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", "dev": true, + "license": "MIT", "dependencies": { "extend": "^3.0.0", "glob": "^7.1.1", @@ -4883,6 +5208,7 @@ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", "dev": true, + "license": "MIT", "dependencies": { "anymatch": "^2.0.0", "async-done": "^1.2.0", @@ -4901,6 +5227,7 @@ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", "dev": true, + "license": "MIT", "dependencies": { "sparkles": "^1.0.0" }, @@ -4913,6 +5240,7 @@ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", "dev": true, + "license": "MIT", "dependencies": { "glob-watcher": "^5.0.3", "gulp-cli": "^2.2.0", @@ -4931,6 +5259,7 @@ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-colors": "^1.0.1", "archy": "^1.0.0", @@ -4963,6 +5292,7 @@ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", "integrity": "sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==", "dev": true, + "license": "MIT", "dependencies": { "glogg": "^1.0.0" }, @@ -4975,6 +5305,7 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -4984,6 +5315,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^1.0.0" }, @@ -4996,6 +5328,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -5009,6 +5342,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -5021,6 +5355,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -5033,6 +5368,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "dev": true, + "license": "MIT", "dependencies": { "number-is-nan": "^1.0.0" }, @@ -5045,6 +5381,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^3.0.2" }, @@ -5057,6 +5394,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -5069,6 +5407,7 @@ "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", "dev": true, + "license": "MIT", "dependencies": { "default-resolution": "^2.0.0", "es6-weak-map": "^2.0.1" @@ -5082,6 +5421,7 @@ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", "dev": true, + "license": "MIT", "dependencies": { "flush-write-stream": "^1.0.2" }, @@ -5094,6 +5434,7 @@ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", "dev": true, + "license": "MIT", "dependencies": { "extend": "^3.0.0", "findup-sync": "^3.0.0", @@ -5113,6 +5454,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -5125,6 +5467,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "license": "MIT", "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -5149,6 +5492,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -5162,6 +5506,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5171,6 +5516,7 @@ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5180,6 +5526,7 @@ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.3.2" }, @@ -5192,6 +5539,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5207,6 +5555,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", @@ -5233,6 +5582,7 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5242,6 +5592,7 @@ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", "integrity": "sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==", "dev": true, + "license": "MIT", "dependencies": { "homedir-polyfill": "^1.0.1", "is-absolute": "^1.0.0", @@ -5256,6 +5607,7 @@ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", "dev": true, + "license": "MIT", "dependencies": { "value-or-function": "^3.0.0" }, @@ -5267,13 +5619,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/gulp-nodemon/node_modules/semver-greatest-satisfied-range": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", "integrity": "sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==", "dev": true, + "license": "MIT", "dependencies": { "sver-compat": "^1.5.0" }, @@ -5286,6 +5640,7 @@ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5295,6 +5650,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -5304,6 +5660,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "dev": true, + "license": "MIT", "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5318,6 +5675,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -5325,11 +5683,23 @@ "node": ">=0.10.0" } }, + "node_modules/gulp-nodemon/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, "node_modules/gulp-nodemon/node_modules/to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -5343,6 +5713,7 @@ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", "dev": true, + "license": "MIT", "dependencies": { "through2": "^2.0.3" }, @@ -5355,6 +5726,7 @@ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", "dev": true, + "license": "MIT", "dependencies": { "arr-flatten": "^1.0.1", "arr-map": "^2.0.0", @@ -5376,6 +5748,7 @@ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5385,6 +5758,7 @@ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", "dev": true, + "license": "MIT", "dependencies": { "homedir-polyfill": "^1.0.1" }, @@ -5397,6 +5771,7 @@ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5406,6 +5781,7 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", @@ -5423,6 +5799,7 @@ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", "dev": true, + "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^1.0.0", "glob-stream": "^6.1.0", @@ -5451,6 +5828,7 @@ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", "dev": true, + "license": "MIT", "dependencies": { "append-buffer": "^1.0.2", "convert-source-map": "^1.5.0", @@ -5469,6 +5847,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", "dev": true, + "license": "MIT", "dependencies": { "remove-trailing-separator": "^1.0.1" }, @@ -5481,6 +5860,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", "dev": true, + "license": "MIT", "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -5493,13 +5873,15 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/gulp-nodemon/node_modules/yargs": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^3.0.0", "cliui": "^3.2.0", @@ -5521,6 +5903,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^3.0.0", "object.assign": "^4.1.0" @@ -5531,6 +5914,7 @@ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", "dev": true, + "license": "MIT", "dependencies": { "glogg": "^2.2.0" }, @@ -5543,6 +5927,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5551,6 +5936,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -5558,21 +5944,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-proto": { - "version": "1.0.3", - "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5584,6 +5960,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" }, @@ -5599,6 +5976,7 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", "dev": true, + "license": "MIT", "dependencies": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -5613,6 +5991,7 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -5626,6 +6005,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^3.0.2" }, @@ -5638,6 +6018,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -5649,6 +6030,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -5660,6 +6042,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "license": "MIT", "engines": { "node": ">=16.0.0" } @@ -5669,6 +6052,7 @@ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, + "license": "MIT", "dependencies": { "parse-passwd": "^1.0.0" }, @@ -5680,12 +6064,14 @@ "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/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==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5698,11 +6084,12 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -5710,11 +6097,12 @@ } }, "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -5725,11 +6113,18 @@ } } }, - "node_modules/human-signals": { + "node_modules/https-proxy-agent/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==", + "license": "MIT" + }, + "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=16.17.0" } @@ -5748,6 +6143,7 @@ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.1.tgz", "integrity": "sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==", "dev": true, + "license": "MIT", "bin": { "husky": "bin.js" }, @@ -5762,6 +6158,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5772,18 +6169,31 @@ "node_modules/ieee754": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } }, "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/image-q": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "license": "MIT", "dependencies": { "@types/node": "16.9.1" } @@ -5791,13 +6201,15 @@ "node_modules/image-q/node_modules/@types/node": { "version": "16.9.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", + "license": "MIT" }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -5814,15 +6226,17 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", "dev": true, + "license": "MIT", "optional": true, "funding": { "type": "github", @@ -5832,8 +6246,9 @@ "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, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -5844,6 +6259,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5852,13 +6268,15 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, + "license": "ISC", "optional": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -5869,6 +6287,7 @@ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.5.tgz", "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -5895,6 +6314,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -5910,6 +6330,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -5926,6 +6347,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -5937,13 +6359,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/inquirer/node_modules/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -5953,6 +6377,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5965,6 +6390,7 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -5974,6 +6400,7 @@ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5981,12 +6408,14 @@ "node_modules/ip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", + "license": "MIT" }, "node_modules/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==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -5996,6 +6425,7 @@ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, + "license": "MIT", "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" @@ -6009,6 +6439,7 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -6017,12 +6448,13 @@ } }, "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6034,14 +6466,16 @@ "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -6052,12 +6486,14 @@ "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6066,10 +6502,11 @@ } }, "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.2" }, @@ -6085,6 +6522,7 @@ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", "dev": true, + "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -6097,6 +6535,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -6110,6 +6549,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6119,6 +6559,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6128,6 +6569,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6138,14 +6580,20 @@ "node_modules/is-function": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "license": "MIT" }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -6159,6 +6607,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -6171,6 +6620,7 @@ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6180,6 +6630,7 @@ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6189,33 +6640,45 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.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-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, + "license": "MIT", "dependencies": { "is-unc-path": "^1.0.0" }, @@ -6227,6 +6690,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -6235,11 +6699,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -6253,6 +6718,7 @@ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, + "license": "MIT", "dependencies": { "unc-path-regex": "^0.1.2" }, @@ -6265,6 +6731,7 @@ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -6275,14 +6742,16 @@ "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6292,6 +6761,7 @@ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6299,19 +6769,22 @@ "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -6320,6 +6793,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.1", "whatwg-fetch": "^3.4.1" @@ -6329,6 +6803,7 @@ "version": "0.22.12", "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz", "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==", + "license": "MIT", "dependencies": { "@jimp/custom": "^0.22.12", "@jimp/plugins": "^0.22.12", @@ -6337,19 +6812,21 @@ } }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, + "license": "MIT", "optional": true, "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/jmespath": { "version": "0.16.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "license": "Apache-2.0", "engines": { "node": ">= 0.6.0" } @@ -6357,13 +6834,15 @@ "node_modules/jpeg-js": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "license": "BSD-3-Clause" }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/js-yaml": { @@ -6371,6 +6850,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6382,6 +6862,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", "dependencies": { "bignumber.js": "^9.0.0" } @@ -6390,13 +6871,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/json-schema-traverse": { @@ -6404,19 +6887,22 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, + "license": "MIT", "optional": true }, "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=", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -6428,6 +6914,7 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", @@ -6445,39 +6932,58 @@ "npm": ">=6" } }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" } }, + "node_modules/jsonwebtoken/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==", + "license": "MIT" + }, "node_modules/just-debounce": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", "dependencies": { - "buffer-equal-constant-time": "1.0.1", + "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -6485,6 +6991,7 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } @@ -6494,6 +7001,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -6503,6 +7011,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -6515,6 +7024,7 @@ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -6524,6 +7034,7 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" }, @@ -6536,6 +7047,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6550,13 +7062,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -6566,6 +7080,7 @@ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", "dev": true, + "license": "MIT", "dependencies": { "invert-kv": "^1.0.0" }, @@ -6578,6 +7093,7 @@ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.13.0" } @@ -6587,6 +7103,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -6596,10 +7113,11 @@ } }, "node_modules/liftoff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", - "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.1.tgz", + "integrity": "sha512-wwLXMbuxSF8gMvubFcFRp56lkFV69twvbU5vDPbaw+Q+/rF8j0HKjGbIdlSi+LuJm9jf7k9PB+nTxnsLMPcv2Q==", "dev": true, + "license": "MIT", "dependencies": { "extend": "^3.0.2", "findup-sync": "^5.0.0", @@ -6618,6 +7136,7 @@ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", "dev": true, + "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^4.0.3", @@ -6629,10 +7148,11 @@ } }, "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" }, @@ -6645,6 +7165,7 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/lint-staged": { @@ -6652,6 +7173,7 @@ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "~5.3.0", "commander": "~12.1.0", @@ -6679,6 +7201,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -6687,12 +7210,13 @@ } }, "node_modules/lint-staged/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -6703,16 +7227,24 @@ } } }, + "node_modules/lint-staged/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==", + "dev": true, + "license": "MIT" + }, "node_modules/listr2": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", - "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", "dev": true, + "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", + "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, @@ -6721,10 +7253,11 @@ } }, "node_modules/listr2/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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6733,10 +7266,11 @@ } }, "node_modules/listr2/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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -6745,16 +7279,18 @@ } }, "node_modules/listr2/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "dev": true, + "license": "MIT" }, "node_modules/listr2/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -6768,10 +7304,11 @@ } }, "node_modules/listr2/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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -6783,10 +7320,11 @@ } }, "node_modules/listr2/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -6803,6 +7341,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.2.tgz", "integrity": "sha512-qElWkmjW9Oq1F9EI5Gt7aD9zcdHb9spJCW1L/dmPf7KzCCEJxq8nhHz5eCgI9aMf7vrG/wyaCqdsI+Iy9ZTlog==", + "license": "MIT", "dependencies": { "buffer-equal": "0.0.1", "mime": "^1.3.4", @@ -6819,6 +7358,7 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -6830,70 +7370,124 @@ "node": ">=0.10.0" } }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.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, + "license": "MIT", + "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", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" }, "node_modules/lodash.map": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", - "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", - "dev": true + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/log-symbols": { @@ -6901,6 +7495,7 @@ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -6917,6 +7512,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -6932,6 +7528,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6948,6 +7545,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -6959,13 +7557,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/log-symbols/node_modules/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -6975,6 +7575,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6983,14 +7584,15 @@ } }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -7002,22 +7604,27 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7026,10 +7633,11 @@ } }, "node_modules/log-update/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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7038,33 +7646,36 @@ } }, "node_modules/log-update/node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, + "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", + "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", + "dev": true, + "license": "MIT" }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, + "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.0.0" + "get-east-asian-width": "^1.3.1" }, "engines": { "node": ">=18" @@ -7073,57 +7684,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/log-update/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -7140,6 +7739,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -7153,10 +7753,11 @@ } }, "node_modules/log-update/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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -7168,10 +7769,11 @@ } }, "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -7189,6 +7791,7 @@ "resolved": "https://registry.npmjs.org/longest/-/longest-2.0.1.tgz", "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7198,6 +7801,7 @@ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -7210,6 +7814,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7219,6 +7824,7 @@ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7228,6 +7834,7 @@ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", "dev": true, + "license": "MIT", "dependencies": { "object-visit": "^1.0.0" }, @@ -7240,6 +7847,7 @@ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", "integrity": "sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==", "dev": true, + "license": "MIT", "dependencies": { "findup-sync": "^2.0.0", "micromatch": "^3.0.4", @@ -7255,6 +7863,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "license": "MIT", "dependencies": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -7276,6 +7885,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -7289,6 +7899,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", "dev": true, + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -7304,6 +7915,7 @@ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", "integrity": "sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-file": "^1.0.0", "is-glob": "^3.1.0", @@ -7319,6 +7931,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -7332,6 +7945,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -7344,6 +7958,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.0" }, @@ -7356,6 +7971,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^3.0.2" }, @@ -7368,6 +7984,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -7380,6 +7997,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -7392,6 +8010,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7401,6 +8020,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "license": "MIT", "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -7425,6 +8045,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -7438,6 +8059,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -7446,20 +8068,31 @@ "node": ">=0.10.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/md5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", - "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "license": "BSD-3-Clause", "dependencies": { - "charenc": "~0.0.1", - "crypt": "~0.0.1", - "is-buffer": "~1.1.1" + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" } }, "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7467,38 +8100,44 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" }, "node_modules/merge": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/merge/-/merge-2.1.1.tgz", "integrity": "sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7511,6 +8150,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -7522,6 +8162,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -7530,6 +8171,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -7542,6 +8184,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7549,6 +8192,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-document": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", @@ -7562,6 +8218,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7570,9 +8227,10 @@ } }, "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7582,6 +8240,7 @@ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, + "license": "MIT", "dependencies": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -7595,6 +8254,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -7607,6 +8267,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -7618,6 +8279,7 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -7629,6 +8291,7 @@ "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { "node": "*" } @@ -7637,6 +8300,7 @@ "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==", + "license": "MIT", "dependencies": { "moment": "^2.29.4" }, @@ -7645,57 +8309,63 @@ } }, "node_modules/mongodb-connection-string-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", - "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.2.tgz", + "integrity": "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA==", + "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", - "whatwg-url": "^13.0.0" + "whatwg-url": "^14.1.0 || ^13.0.0" } }, "node_modules/mongodb-connection-string-url/node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mongodb-connection-string-url/node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "license": "MIT", "dependencies": { - "punycode": "^2.3.0" + "punycode": "^2.3.1" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" } }, "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "license": "MIT", "dependencies": { - "tr46": "^4.1.1", + "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/mongodb-uri": { "version": "0.9.7", "resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz", - "integrity": "sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE=", + "integrity": "sha512-s6BdnqNoEYfViPJgkH85X5Nw5NpzxN8hoflKLweNa7vBxt2V7kaS06d74pAtqDxde8fn4r9h4dNdLiFGoNV0KA==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -7704,6 +8374,7 @@ "version": "8.5.1", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.5.1.tgz", "integrity": "sha512-OhVcwVl91A1G6+XpjDcpkGP7l7ikZkxa0DylX7NT/lcEqAjggzSdqDxb48A+xsDxqNAr0ntSJ1yiE3+KJTOd5Q==", + "license": "MIT", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", @@ -7725,6 +8396,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -7735,13 +8407,14 @@ } }, "node_modules/mongoose/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7752,17 +8425,11 @@ } } }, - "node_modules/mongoose/node_modules/debug/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==", - "optional": true, - "peer": true - }, "node_modules/mongoose/node_modules/gaxios": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -7779,6 +8446,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", + "license": "Apache-2.0", "optional": true, "peer": true, "dependencies": { @@ -7793,6 +8461,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "optional": true, "peer": true, "dependencies": { @@ -7807,6 +8476,7 @@ "version": "6.7.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.7.0.tgz", "integrity": "sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -7851,12 +8521,14 @@ "node_modules/mongoose/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==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", @@ -7868,10 +8540,23 @@ "node": ">= 0.8.0" } }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/mpath": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", "engines": { "node": ">=4.0.0" } @@ -7880,6 +8565,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "license": "MIT", "dependencies": { "debug": "4.x" }, @@ -7888,11 +8574,12 @@ } }, "node_modules/mquery/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -7903,16 +8590,24 @@ } } }, + "node_modules/mquery/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==", + "license": "MIT" + }, "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==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/multer": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", "integrity": "sha512-wbAkTsh0QXkvqvHCU2qSLEXLuRN7IKMEe80+JrXfJzANniPNgrNcDOMKfGgR1EhL7y7MHIbODVwT7uaVY20ggw==", "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "license": "MIT", "dependencies": { "append-field": "^0.1.0", "busboy": "^0.2.11", @@ -7930,7 +8625,8 @@ "node_modules/multer/node_modules/object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -7940,6 +8636,7 @@ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -7948,13 +8645,15 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nan": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "dev": true, + "license": "MIT", "optional": true }, "node_modules/nanomatch": { @@ -7962,6 +8661,7 @@ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, + "license": "MIT", "dependencies": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -7984,6 +8684,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -7997,6 +8698,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -8010,6 +8712,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -8023,6 +8726,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -8035,6 +8739,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -8047,6 +8752,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8054,13 +8760,15 @@ "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=", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8069,7 +8777,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/node-domexception": { "version": "1.0.0", @@ -8095,6 +8804,7 @@ "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8123,6 +8833,7 @@ "version": "6.9.14", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.14.tgz", "integrity": "sha512-Dobp/ebDKBvz91sbtRKhcznLThrKxKt97GI2FAlAyy+fk19j73Uz3sBXolVtmcXjaorivqsbbbjDY+Jkt4/bQA==", + "license": "MIT-0", "engines": { "node": ">=6.0.0" } @@ -8132,6 +8843,7 @@ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": "^3.5.2", "debug": "^3.2.7", @@ -8160,15 +8872,34 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, + "node_modules/nodemon/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -8176,11 +8907,22 @@ "validate-npm-package-license": "^3.0.1" } }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8191,6 +8933,7 @@ "integrity": "sha512-5SMS8lVuCzqD55CPQlGcjvOJJJPuDSLoqKIIGR4uEooCbDhHl//dHZmBpT1uLSwT1MYvhYUMf9OpFQRwXG4KEg==", "deprecated": "\"now\" is deprecated and will stop receiving updates on December 31, 2020. Please use \"vercel\" instead.", "hasInstallScript": true, + "license": "Apache-2.0", "bin": { "now": "download/dist/now" } @@ -8200,6 +8943,7 @@ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", "dev": true, + "license": "MIT", "dependencies": { "once": "^1.4.0" }, @@ -8212,6 +8956,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^4.0.0" }, @@ -8227,6 +8972,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -8239,6 +8985,7 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8246,7 +8993,8 @@ "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8256,6 +9004,7 @@ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", "dev": true, + "license": "MIT", "dependencies": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -8270,6 +9019,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -8278,9 +9028,10 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -8293,6 +9044,7 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8302,6 +9054,7 @@ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.0" }, @@ -8310,14 +9063,17 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -8332,6 +9088,7 @@ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", "dev": true, + "license": "MIT", "dependencies": { "array-each": "^1.0.1", "array-slice": "^1.0.0", @@ -8347,6 +9104,7 @@ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==", "dev": true, + "license": "MIT", "dependencies": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" @@ -8360,6 +9118,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -8372,6 +9131,7 @@ "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", "dev": true, + "license": "MIT", "dependencies": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" @@ -8383,12 +9143,14 @@ "node_modules/omggif": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "license": "MIT" }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -8400,6 +9162,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8409,6 +9172,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -8418,6 +9182,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^4.0.0" }, @@ -8429,9 +9194,9 @@ } }, "node_modules/openai": { - "version": "4.103.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.103.0.tgz", - "integrity": "sha512-eWcz9kdurkGOFDtd5ySS5y251H2uBgq9+1a2lTBnjMMzlexJ40Am5t6Mu76SSE87VvitPa0dkIAp75F+dZVC0g==", + "version": "4.104.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz", + "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==", "license": "Apache-2.0", "dependencies": { "@types/node": "^18.11.18", @@ -8459,19 +9224,26 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.103", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.103.tgz", - "integrity": "sha512-hHTHp+sEz6SxFsp+SA+Tqrua3AbmlAw+Y//aEwdHrdZkYVRWdvWD3y5uPZ0flYOkgskaFWqZ/YGFm3FaFQ0pRw==", + "version": "18.19.129", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.129.tgz", + "integrity": "sha512-hrmi5jWt2w60ayox3iIXwpMEnfUvOLJCRtrOPbHtH15nTjvO7uhnelvrdAs0dO0/zl5DZ3ZbahiaXEVb54ca/A==", "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/openai/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==", + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -8489,6 +9261,7 @@ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", @@ -8512,6 +9285,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -8527,6 +9301,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -8543,6 +9318,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -8554,13 +9330,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/ora/node_modules/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, + "license": "MIT", "engines": { "node": ">=8" } @@ -8570,6 +9348,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -8582,6 +9361,7 @@ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^2.0.1" } @@ -8591,6 +9371,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8605,13 +9386,15 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ordered-read-streams/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } @@ -8621,6 +9404,7 @@ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", "dev": true, + "license": "MIT", "dependencies": { "lcid": "^1.0.0" }, @@ -8633,20 +9417,55 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/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, + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/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, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -8657,17 +9476,20 @@ "node_modules/parse-bmfont-ascii": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", + "license": "MIT" }, "node_modules/parse-bmfont-binary": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", + "license": "MIT" }, "node_modules/parse-bmfont-xml": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", + "license": "MIT", "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" @@ -8677,6 +9499,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "license": "MIT", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -8690,6 +9513,7 @@ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", "dev": true, + "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", @@ -8700,20 +9524,29 @@ } }, "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz", + "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", + "license": "MIT" }, "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "error-ex": "^1.2.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parse-node-version": { @@ -8721,6 +9554,7 @@ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -8730,6 +9564,7 @@ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8738,6 +9573,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8747,6 +9583,7 @@ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8755,13 +9592,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -8771,6 +9610,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8780,6 +9620,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -8788,13 +9629,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", "dev": true, + "license": "MIT", "dependencies": { "path-root-regex": "^0.1.0" }, @@ -8807,6 +9650,7 @@ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8814,13 +9658,15 @@ "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==", + "license": "MIT" }, "node_modules/path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", @@ -8834,6 +9680,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -8846,6 +9693,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/phin/-/phin-3.7.1.tgz", "integrity": "sha512-GEazpTWwTZaEQ9RhL7Nyz0WwqilbqgLahDM3D0hxWwmVDI52nXEybHqiN6/elwpkJBhcuj+WbBu+QfT0uhPGfQ==", + "license": "MIT", "dependencies": { "centra": "^2.7.0" }, @@ -8854,10 +9702,11 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, + "license": "ISC", "optional": true }, "node_modules/picomatch": { @@ -8865,6 +9714,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -8877,6 +9727,7 @@ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -8889,6 +9740,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8898,6 +9750,7 @@ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -8907,6 +9760,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", "dev": true, + "license": "MIT", "dependencies": { "pinkie": "^2.0.0" }, @@ -8918,6 +9772,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", + "license": "ISC", "dependencies": { "pngjs": "^3.0.0" }, @@ -8929,14 +9784,29 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", "engines": { "node": ">=4.0.0" } }, + "node_modules/plugin-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-2.0.1.tgz", + "integrity": "sha512-zMakqvIDyY40xHOvzXka0kUvf40nYIuwRE8dWhti2WtjQZ31xAgBZBhxsK7vK3QbRXS1Xms/LO7B5cuAsfB2Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/pngjs": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "license": "MIT", "engines": { "node": ">=12.13.0" } @@ -8946,14 +9816,16 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -8963,6 +9835,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -8972,6 +9845,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -8987,6 +9861,7 @@ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -8995,6 +9870,7 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } @@ -9002,12 +9878,14 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" }, "node_modules/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==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -9019,19 +9897,22 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9042,6 +9923,7 @@ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, + "license": "MIT", "dependencies": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -9053,6 +9935,7 @@ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, + "license": "MIT", "dependencies": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -9065,6 +9948,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9079,26 +9963,30 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pumpify/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "license": "MIT" }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -9112,47 +10000,23 @@ "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "engines": { "node": ">=0.4.x" } }, - "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/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/randombytes": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz", - "integrity": "sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==" + "integrity": "sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==", + "license": "MIT" }, "node_modules/randomstring": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.3.0.tgz", "integrity": "sha512-gY7aQ4i1BgwZ8I1Op4YseITAyiDiajeZOPQUbIq9TPGPhUm5FX59izIaOpmKbME1nmnEiABf28d9K2VSii6BBg==", + "license": "MIT", "dependencies": { "randombytes": "2.0.3" }, @@ -9167,6 +10031,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9174,8 +10039,9 @@ "node_modules/raven": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.0.tgz", - "integrity": "sha1-OAaoLJ7ozT51w7fqe7GTWq0JLQw=", + "integrity": "sha512-9s2rMxaV03VUqj+rlK5uJZg0iz1EKFdihdXqz5I4DTpOrBZ/z22Od7/2mzE5+Q7tUrpk+mhIIuoaAt/SduIeTg==", "deprecated": "Please upgrade to @sentry/node. See the migration guide https://bit.ly/3ybOlo7", + "license": "BSD-2-Clause", "dependencies": { "cookie": "0.3.1", "md5": "^2.2.1", @@ -9190,11 +10056,21 @@ "node": ">= 4.0.0" } }, + "node_modules/raven/node_modules/cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/raven/node_modules/uuid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=", + "integrity": "sha512-rqE1LoOVLv3QrZMjb4NkF5UWlkurCfPyItVnFPNKDDGkHw4dQUdE4zMcLqx28+0Kcf3+bnUk4PisaiRJT4aiaQ==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", "bin": { "uuid": "bin/uuid" } @@ -9203,6 +10079,7 @@ "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==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -9218,6 +10095,7 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", "dev": true, + "license": "MIT", "dependencies": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", @@ -9232,6 +10110,7 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" @@ -9240,10 +10119,38 @@ "node": ">=0.10.0" } }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -9254,14 +10161,16 @@ "node_modules/readable-stream/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" }, "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", "dependencies": { - "readable-stream": "^3.6.0" + "readable-stream": "^4.7.0" }, "engines": { "node": ">=8" @@ -9271,23 +10180,80 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/readable-web-to-node-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">= 6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/readable-web-to-node-stream/node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } @@ -9297,6 +10263,7 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -9309,6 +10276,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve": "^1.20.0" }, @@ -9319,13 +10287,15 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "license": "MIT" }, "node_modules/regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, + "license": "MIT", "dependencies": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -9339,6 +10309,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -9352,6 +10323,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -9364,6 +10336,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -9376,6 +10349,7 @@ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5", "is-utf8": "^0.2.1" @@ -9389,6 +10363,7 @@ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", "dev": true, + "license": "MIT", "dependencies": { "remove-bom-buffer": "^3.0.0", "safe-buffer": "^5.1.0", @@ -9398,17 +10373,63 @@ "node": ">= 0.10" } }, + "node_modules/remove-bom-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/remove-bom-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/remove-bom-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/remove-bom-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, "node_modules/remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/repeat-element": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9418,6 +10439,7 @@ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } @@ -9427,6 +10449,7 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } @@ -9436,6 +10459,7 @@ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -9445,6 +10469,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -9454,6 +10479,7 @@ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -9463,21 +10489,26 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9487,6 +10518,7 @@ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", "dev": true, + "license": "MIT", "dependencies": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" @@ -9500,6 +10532,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=8" @@ -9510,6 +10543,7 @@ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", "dev": true, + "license": "MIT", "dependencies": { "value-or-function": "^4.0.0" }, @@ -9522,13 +10556,15 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, + "license": "MIT", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -9542,6 +10578,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -9551,6 +10588,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -9565,22 +10603,25 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12" } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -9590,45 +10631,25 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "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/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" } @@ -9650,34 +10671,58 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", "dev": true, + "license": "MIT", "dependencies": { "ret": "~0.1.10" } }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" }, "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", + "license": "ISC" }, "node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/semver-greatest-satisfied-range": { @@ -9685,6 +10730,7 @@ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", "dev": true, + "license": "MIT", "dependencies": { "sver": "^1.8.3" }, @@ -9696,6 +10742,7 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -9718,23 +10765,14 @@ "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/send/node_modules/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==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/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==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -9749,12 +10787,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "dev": true, + "license": "ISC" }, "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==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -9772,6 +10812,7 @@ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -9787,6 +10828,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -9797,13 +10839,15 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/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, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -9816,19 +10860,75 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/side-channel": { - "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==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -9840,13 +10940,15 @@ "node_modules/sift": { "version": "17.1.3", "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", - "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==" + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" }, "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, + "license": "ISC", "engines": { "node": ">=14" }, @@ -9859,6 +10961,7 @@ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", "dev": true, + "license": "MIT", "dependencies": { "semver": "~7.0.0" }, @@ -9871,6 +10974,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -9880,6 +10984,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -9892,10 +10997,11 @@ } }, "node_modules/slice-ansi/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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -9908,6 +11014,7 @@ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, + "license": "MIT", "dependencies": { "base": "^0.11.1", "debug": "^2.2.0", @@ -9927,6 +11034,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, + "license": "MIT", "dependencies": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -9941,6 +11049,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.0" }, @@ -9953,6 +11062,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -9966,6 +11076,7 @@ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^3.2.0" }, @@ -9978,6 +11089,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -9990,6 +11102,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -10000,6 +11113,7 @@ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", "dev": true, + "license": "MIT", "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0", @@ -10013,13 +11127,15 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sparkles": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -10028,6 +11144,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } @@ -10037,6 +11154,7 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -10046,28 +11164,32 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" }, "node_modules/speakingurl": { "version": "14.0.1", "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -10077,6 +11199,7 @@ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, + "license": "MIT", "dependencies": { "extend-shallow": "^3.0.0" }, @@ -10089,6 +11212,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -10102,6 +11226,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -10114,6 +11239,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -10124,7 +11250,8 @@ "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", "engines": { "node": "*" } @@ -10134,6 +11261,7 @@ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", "dev": true, + "license": "MIT", "dependencies": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -10146,6 +11274,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10155,6 +11284,7 @@ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.13.2" } @@ -10163,46 +11293,48 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/stream-shift": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/streamsearch": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", "engines": { "node": ">=0.8.0" } }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "dev": true, + "license": "MIT", "dependencies": { + "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -10212,6 +11344,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10226,6 +11359,7 @@ "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -10235,6 +11369,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10243,15 +11378,13 @@ } }, "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/strip-final-newline": { @@ -10259,6 +11392,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -10271,6 +11405,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -10282,6 +11417,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" @@ -10299,6 +11435,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -10311,6 +11448,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -10323,6 +11461,7 @@ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", "dev": true, + "license": "MIT", "optionalDependencies": { "semver": "^6.3.0" } @@ -10332,6 +11471,7 @@ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", "integrity": "sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==", "dev": true, + "license": "MIT", "dependencies": { "es6-iterator": "^2.0.1", "es6-symbol": "^3.1.1" @@ -10342,6 +11482,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver.js" @@ -10352,6 +11493,7 @@ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.12.5" } @@ -10361,6 +11503,7 @@ "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-3.0.0.tgz", "integrity": "sha512-oIzdi+UL/JdktkT+7KU5tSIQjj8pbShj3OASuvDEhm0NT5lppsm7aXWAmAq4/QMaBIyfuEcNLbAQA+HpaISobQ==", "dev": true, + "license": "MIT", "dependencies": { "duplexify": "^4.1.1", "fork-stream": "^0.0.4", @@ -10368,68 +11511,32 @@ "through2": "^3.0.1" } }, - "node_modules/ternary-stream/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/ternary-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/ternary-stream/node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, "node_modules/text-decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", - "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" } }, - "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/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", "dev": true, + "license": "MIT", "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "inherits": "^2.0.4", + "readable-stream": "2 || 3" } }, "node_modules/through2-filter": { @@ -10437,16 +11544,18 @@ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "dev": true, + "license": "MIT", "dependencies": { "through2": "~2.0.0", "xtend": "~4.0.0" } }, - "node_modules/through2/node_modules/readable-stream": { + "node_modules/through2-filter/node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10457,26 +11566,65 @@ "util-deprecate": "~1.0.1" } }, - "node_modules/through2/node_modules/safe-buffer": { + "node_modules/through2-filter/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/through2/node_modules/string_decoder": { + "node_modules/through2-filter/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/through2-filter/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10484,7 +11632,8 @@ "node_modules/timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10492,18 +11641,21 @@ "node_modules/timm": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" + "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", + "license": "MIT" }, "node_modules/tinycolor2": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT" }, "node_modules/tldjs": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/tldjs/-/tldjs-1.8.0.tgz", - "integrity": "sha1-ucFr1t41e1X/y+fVvkH2s8p24/o=", + "integrity": "sha512-oJHVrNdgPYlU7vszbSBMYDykdnJ8DmjaGML5KysOn2MIYtnpl1Yn+bCSF/vNo8vZkd0U+eRGg1qkQjHDLD/Teg==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "punycode": "^1.4.1" }, @@ -10511,16 +11663,12 @@ "node": ">= 0.10" } }, - "node_modules/tldjs/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, + "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -10533,6 +11681,7 @@ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", "dev": true, + "license": "MIT", "dependencies": { "is-absolute": "^1.0.0", "is-negated-glob": "^1.0.0" @@ -10546,6 +11695,7 @@ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", "dev": true, + "license": "MIT", "dependencies": { "kind-of": "^3.0.2" }, @@ -10558,6 +11708,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", "dev": true, + "license": "MIT", "dependencies": { "is-buffer": "^1.1.5" }, @@ -10570,6 +11721,7 @@ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, + "license": "MIT", "dependencies": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -10585,6 +11737,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -10597,6 +11750,7 @@ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, + "license": "MIT", "dependencies": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -10610,6 +11764,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", "dev": true, + "license": "MIT", "dependencies": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -10623,6 +11778,7 @@ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", "dev": true, + "license": "MIT", "dependencies": { "is-accessor-descriptor": "^1.0.1", "is-data-descriptor": "^1.0.1" @@ -10636,6 +11792,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4" }, @@ -10648,6 +11805,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -10660,6 +11818,7 @@ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", "dev": true, + "license": "MIT", "dependencies": { "streamx": "^2.12.5" }, @@ -10671,6 +11830,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } @@ -10679,6 +11839,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" @@ -10708,13 +11869,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/touch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", "dev": true, + "license": "ISC", "bin": { "nodetouch": "bin/nodetouch.js" } @@ -10722,25 +11885,29 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" }, "node_modules/type": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/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, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -10753,6 +11920,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -10764,6 +11932,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -10775,13 +11944,15 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", "optional": true, "peer": true, "bin": { @@ -10797,6 +11968,7 @@ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10805,13 +11977,15 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/undertaker": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", "dev": true, + "license": "MIT", "dependencies": { "bach": "^2.0.1", "fast-levenshtein": "^3.0.0", @@ -10827,6 +12001,7 @@ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -10836,20 +12011,23 @@ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", "dev": true, + "license": "MIT", "dependencies": { "fastest-levenshtein": "^1.0.7" } }, "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==" + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.13.0.tgz", + "integrity": "sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==", + "license": "MIT" }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, + "license": "MIT", "dependencies": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -10865,6 +12043,7 @@ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", "dev": true, + "license": "MIT", "dependencies": { "json-stable-stringify-without-jsonify": "^1.0.1", "through2-filter": "^3.0.0" @@ -10875,6 +12054,7 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -10882,7 +12062,8 @@ "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==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10892,6 +12073,7 @@ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", "dev": true, + "license": "MIT", "dependencies": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -10905,6 +12087,7 @@ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", "dev": true, + "license": "MIT", "dependencies": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -10919,6 +12102,7 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", "dev": true, + "license": "MIT", "dependencies": { "isarray": "1.0.0" }, @@ -10931,6 +12115,7 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10940,6 +12125,7 @@ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4", "yarn": "*" @@ -10950,6 +12136,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -10959,6 +12146,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10968,22 +12156,31 @@ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "license": "MIT", "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "license": "MIT" + }, "node_modules/use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -10992,6 +12189,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", + "license": "MIT", "dependencies": { "pako": "^1.0.11" } @@ -11000,6 +12198,7 @@ "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -11011,12 +12210,14 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } @@ -11025,6 +12226,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -11034,6 +12236,7 @@ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -11043,6 +12246,7 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -11052,6 +12256,7 @@ "version": "13.12.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -11061,6 +12266,7 @@ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.13.0" } @@ -11068,19 +12274,20 @@ "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==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.1.tgz", + "integrity": "sha512-0QwqXteBNXgnLCdWdvPQBX6FXRHtIH3VhJPTd5Lwn28tJXc34YqSCWUmkOvtJHBmB3gGoPtrOKk3Ts8/kEZ9aA==", "dev": true, + "license": "MIT", "dependencies": { "clone": "^2.1.2", - "clone-stats": "^1.0.0", "remove-trailing-separator": "^1.1.0", "replace-ext": "^2.0.0", "teex": "^1.0.1" @@ -11094,6 +12301,7 @@ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^5.0.0", "vinyl": "^3.0.0" @@ -11107,6 +12315,7 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", "dev": true, + "license": "MIT", "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", @@ -11132,6 +12341,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -11155,13 +12365,15 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/vinyl-contents/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -11176,18 +12388,20 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/vinyl-fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", - "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.2.tgz", + "integrity": "sha512-XRFwBLLTl8lRAOYiBqxY279wY46tVxLaRhSwo3GzKEuLz1giffsOquWWboD/haGf5lx+JyTigCFfe7DWHoARIA==", "dev": true, + "license": "MIT", "dependencies": { "fs-mkdirp-stream": "^2.0.1", - "glob-stream": "^8.0.0", + "glob-stream": "^8.0.3", "graceful-fs": "^4.2.11", "iconv-lite": "^0.6.3", "is-valid-glob": "^1.0.0", @@ -11198,7 +12412,7 @@ "streamx": "^2.14.0", "to-through": "^3.0.0", "value-or-function": "^4.0.0", - "vinyl": "^3.0.0", + "vinyl": "^3.0.1", "vinyl-sourcemap": "^2.0.0" }, "engines": { @@ -11210,6 +12424,7 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -11222,6 +12437,7 @@ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", "dev": true, + "license": "MIT", "dependencies": { "convert-source-map": "^2.0.0", "graceful-fs": "^4.2.10", @@ -11239,6 +12455,7 @@ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", "dev": true, + "license": "MIT", "dependencies": { "defaults": "^1.0.3" } @@ -11255,17 +12472,20 @@ "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" }, "node_modules/whatwg-fetch": { "version": "3.6.20", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", - "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "license": "MIT" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -11276,6 +12496,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -11290,17 +12511,21 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -11315,6 +12540,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -11324,6 +12550,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11341,6 +12568,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -11356,6 +12584,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -11367,18 +12596,21 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/xhr": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "license": "MIT", "dependencies": { "global": "~4.4.0", "is-function": "^1.0.1", @@ -11389,12 +12621,14 @@ "node_modules/xml-parse-from-string": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", + "license": "MIT" }, "node_modules/xml2js": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "license": "MIT", "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" @@ -11407,6 +12641,7 @@ "version": "11.0.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", "engines": { "node": ">=4.0" } @@ -11415,6 +12650,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } @@ -11424,6 +12660,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -11433,6 +12670,7 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "dev": true, + "license": "ISC", "bin": { "yaml": "bin.mjs" }, @@ -11445,6 +12683,7 @@ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -11463,6 +12702,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -11472,6 +12712,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/src/routes/events/create-event.js b/src/routes/events/create-event.js index 264d6a7..6712dc2 100644 --- a/src/routes/events/create-event.js +++ b/src/routes/events/create-event.js @@ -44,17 +44,6 @@ module.exports = async (req, res, next) => { data.managers = [req.user.id]; data.name = cleanSpaces(data.name); - let repeatedEvent; - try { - repeatedEvent = await Event.findOne({ name: data.name, isArchived: false }); - } catch (err) { - console.log(`Event ${data.name} failed to be found at create-event`); - return next(err); - } - console.log("repeatedEvent", repeatedEvent); - if (repeatedEvent) { - return res.status(400).json(sendError({ name: "Is already taken" })); - } if (data.poster) { let poster; @@ -70,7 +59,6 @@ module.exports = async (req, res, next) => { } } - if (data.teamManager) { let team; try { From 76c928fb87534072207c7fe548108c03d4eb5215 Mon Sep 17 00:00:00 2001 From: Abdul Rehman Date: Wed, 8 Oct 2025 14:12:20 +0500 Subject: [PATCH 64/67] add isTest query param in the list events API --- src/routes/events/list-events.js | 15 ++++++++++++++- src/routes/events/validations.js | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 9284de3..719f922 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -28,6 +28,20 @@ module.exports = async (req, res, next) => { eventsQuery.startDate = { $lte: currentDate }; eventsQuery.endDate = { $gte: currentDate }; + const isTest = + typeof queryParams.isTest === "boolean" + ? queryParams.isTest + : queryParams.isTest?.toLowerCase?.() === "true"; + + if (!isTest) { + eventsQuery.name = { + $not: { + $regex: + /\b(tst|test|testing|tsting|testt|t3st|t[e3]sting|t3sting|testin)\b/i, + }, + }; + } + let events; let total; try { @@ -68,7 +82,6 @@ module.exports = async (req, res, next) => { page = null; lastPage = null; } - console.log(events); return res.status(200).json({ page: page + 1, lastPage, diff --git a/src/routes/events/validations.js b/src/routes/events/validations.js index 4dc0762..c468b50 100644 --- a/src/routes/events/validations.js +++ b/src/routes/events/validations.js @@ -387,6 +387,7 @@ module.exports = { validateListEvents(queryParams) { const errors = {}; + // --- afterDate validation --- let isAfterDateValid = false; if ( queryParams.afterDate && @@ -397,6 +398,7 @@ module.exports = { isAfterDateValid = true; } + // --- beforeDate validation --- let isBeforeDateValid = false; if ( queryParams.beforeDate && @@ -407,6 +409,7 @@ module.exports = { isBeforeDateValid = true; } + // --- afterDate and beforeDate validation --- if (isAfterDateValid && isBeforeDateValid) { const afterDate = moment(queryParams.afterDate, "YYYY-MM-DD").utc(); const beforeDate = moment(queryParams.beforeDate, "YYYY-MM-DD").utc(); @@ -416,6 +419,7 @@ module.exports = { } } + // --- sortBy validation --- const sortOptions = [ "name", "-name", @@ -428,6 +432,7 @@ module.exports = { errors.sortBy = "Should be a valid sort"; } + // --- page validation --- if (queryParams.page) { if (!isInt(queryParams.page)) { errors.page = "Should be a integer"; @@ -436,6 +441,7 @@ module.exports = { } } + // --- pageLimit validation --- if (queryParams.pageLimit) { if (!isInt(queryParams.pageLimit)) { errors.pageLimit = "Should be a integer"; @@ -446,6 +452,23 @@ module.exports = { } } + // --- isTest validation --- + if (queryParams.isTest !== undefined) { + const value = + typeof queryParams.isTest === "boolean" + ? queryParams.isTest + : queryParams.isTest.toLowerCase?.(); + + if ( + value !== true && + value !== false && + value !== "true" && + value !== "false" + ) { + errors.isTest = "Should be a boolean (true or false)"; + } + } + return { errors, isValid: isEmpty(errors) }; }, }; From 74735bba885bfb5c2c762e05de3bee923c1e14e1 Mon Sep 17 00:00:00 2001 From: Abdul Rehman Date: Wed, 8 Oct 2025 15:41:14 +0500 Subject: [PATCH 65/67] apply regex in events listing API --- src/routes/events/list-events.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/routes/events/list-events.js b/src/routes/events/list-events.js index 719f922..faafab5 100644 --- a/src/routes/events/list-events.js +++ b/src/routes/events/list-events.js @@ -7,10 +7,10 @@ const { validateListEvents } = require("./validations"); module.exports = async (req, res, next) => { const queryParams = req.query; - console.log(queryParams); - const { errors, isValid } = validateListEvents(queryParams); - if (!isValid) return res.status(400).json(errors); + if (!isValid) { + return res.status(400).json(errors); + } const eventsQuery = {}; @@ -35,10 +35,7 @@ module.exports = async (req, res, next) => { if (!isTest) { eventsQuery.name = { - $not: { - $regex: - /\b(tst|test|testing|tsting|testt|t3st|t[e3]sting|t3sting|testin)\b/i, - }, + $not: /t[\W_0-9]*e[\W_0-9]*s[\W_0-9]*t/i, }; } From 82b4b0acbe41cec9cc344162fea1570659eea9f1 Mon Sep 17 00:00:00 2001 From: Abdul Rehman Date: Wed, 22 Oct 2025 19:58:29 +0500 Subject: [PATCH 66/67] fix issue of test events --- src/index.js | 3 --- src/routes/events/joined-events.js | 14 +++++++++++++- src/routes/events/list-old-events.js | 12 +++++++++++- src/routes/events/list-upcoimg-events.js | 12 +++++++++++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/index.js b/src/index.js index 98bb8e6..e3eee62 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,3 @@ -const fs = require("fs"); -const https = require("https"); - const bodyParser = require("body-parser"); const cors = require("cors"); const express = require("express"); diff --git a/src/routes/events/joined-events.js b/src/routes/events/joined-events.js index 079697c..346f70b 100644 --- a/src/routes/events/joined-events.js +++ b/src/routes/events/joined-events.js @@ -3,7 +3,7 @@ const moment = require("moment"); const { Event } = require("../../models/event"); const jwt = require("jsonwebtoken"); -module.exports = async (req, res, next) => { +module.exports = async (req, res) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith("Bearer ")) { return res @@ -23,6 +23,18 @@ module.exports = async (req, res, next) => { eventsQuery.endDate = { $gte: currentDate }; eventsQuery.$or = [{ managers: userId }, { participants: userId }]; + const queryParams = req.query; + const isTest = + typeof queryParams.isTest === "boolean" + ? queryParams.isTest + : queryParams.isTest?.toLowerCase?.() === "true"; + + if (!isTest) { + eventsQuery.name = { + $not: /t[\W_0-9]*e[\W_0-9]*s[\W_0-9]*t/i, + }; + } + let events; let total; try { diff --git a/src/routes/events/list-old-events.js b/src/routes/events/list-old-events.js index ec024ff..1101e00 100644 --- a/src/routes/events/list-old-events.js +++ b/src/routes/events/list-old-events.js @@ -27,6 +27,17 @@ module.exports = async (req, res, next) => { { participants: req?.user?.id }, ]; + const isTest = + typeof queryParams.isTest === "boolean" + ? queryParams.isTest + : queryParams.isTest?.toLowerCase?.() === "true"; + + if (!isTest) { + eventsQuery.name = { + $not: /t[\W_0-9]*e[\W_0-9]*s[\W_0-9]*t/i, + }; + } + let events; let total; try { @@ -67,7 +78,6 @@ module.exports = async (req, res, next) => { page = null; lastPage = null; } - console.log(events); return res.status(200).json({ page: page + 1, lastPage, diff --git a/src/routes/events/list-upcoimg-events.js b/src/routes/events/list-upcoimg-events.js index e2ef12d..d0c3886 100644 --- a/src/routes/events/list-upcoimg-events.js +++ b/src/routes/events/list-upcoimg-events.js @@ -25,6 +25,17 @@ module.exports = async (req, res, next) => { eventsQuery.startDate = { $gte: currentDate }; + const isTest = + typeof queryParams.isTest === "boolean" + ? queryParams.isTest + : queryParams.isTest?.toLowerCase?.() === "true"; + + if (!isTest) { + eventsQuery.name = { + $not: /t[\W_0-9]*e[\W_0-9]*s[\W_0-9]*t/i, + }; + } + let events; let total; try { @@ -65,7 +76,6 @@ module.exports = async (req, res, next) => { page = null; lastPage = null; } - console.log(events); return res.status(200).json({ page: page + 1, lastPage, From 017ed501e732106b6cb087630ed3b7d1bc2a2f50 Mon Sep 17 00:00:00 2001 From: Muhammad Saffi Ullah <42832684+saffiullah200@users.noreply.github.com> Date: Thu, 25 Dec 2025 20:20:11 +0100 Subject: [PATCH 67/67] feat: implement user inactivity tracking and account reactivation system - Add lastLogin, inactivityEmailSent, and inactivityEmailSentAt fields to User model - Update all authentication endpoints (sign-in, Google, Facebook, Apple) to track lastLogin - Add archived account check for OAuth logins (returns 403 with userId) - Create new /auth/reactivate-account endpoint for archived users - Support password reset and profile update during reactivation - Auto-login users after successful reactivation with JWT tokens - Prepare backend for Salesforce integration for inactivity email workflows --- src/models/user.js | 13 +++ src/routes/auth/apple-sign-in.js | 14 +++ src/routes/auth/facebook-sign-in.js | 14 +++ src/routes/auth/google-sign-in.js | 13 +++ src/routes/auth/index.js | 2 + src/routes/auth/reactivate-account.js | 152 ++++++++++++++++++++++++++ src/routes/auth/sign-in.js | 9 ++ 7 files changed, 217 insertions(+) create mode 100644 src/routes/auth/reactivate-account.js diff --git a/src/models/user.js b/src/models/user.js index bc3390b..6dd097a 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -86,6 +86,19 @@ const userSchema = new mongoose.Schema( default: false, required: [true, "Is required"], }, + lastLogin: { + type: Date, + default: null, + }, + inactivityEmailSent: { + type: Boolean, + default: false, + required: [true, "Is required"], + }, + inactivityEmailSentAt: { + type: Date, + default: null, + }, isBlocked: { type: Boolean, default: false, diff --git a/src/routes/auth/apple-sign-in.js b/src/routes/auth/apple-sign-in.js index 3279986..9bbdc1f 100644 --- a/src/routes/auth/apple-sign-in.js +++ b/src/routes/auth/apple-sign-in.js @@ -33,10 +33,24 @@ module.exports = async (req, res, next) => { firstName:appleResponse?.fullName?.givenName ?? "", lastName:appleResponse?.fullName?.familyName ?? "", appleId: appleResponse?.sub, + lastLogin: new Date(), }); await user.save(); + } else { + // Check if user is archived + if (user.isArchived) { + return res.status(403).json({ + error: "Account archived", + isArchived: true, + userId: user._id.toString() + }); + } + + // Update lastLogin for existing users + await User.findByIdAndUpdate(user._id, { lastLogin: new Date() }); } + const userId = user._id; const today = moment.utc(); const expiresAt = today.add(30, "days").toDate(); diff --git a/src/routes/auth/facebook-sign-in.js b/src/routes/auth/facebook-sign-in.js index 0aec2c3..42c44a8 100644 --- a/src/routes/auth/facebook-sign-in.js +++ b/src/routes/auth/facebook-sign-in.js @@ -57,10 +57,24 @@ module.exports = async (req, res, next) => { firstName: firstName || "", lastName: lastName || "", avatar: fbUser.picture.data.url, + lastLogin: new Date(), }); await user.save(); + } else { + // Check if user is archived + if (user.isArchived) { + return res.status(403).json({ + error: "Account archived", + isArchived: true, + userId: user._id.toString() + }); + } + + // Update lastLogin for existing users + await User.findByIdAndUpdate(user._id, { lastLogin: new Date() }); } + const userId = user._id; const today = moment.utc(); const expiresAt = today.add(30, "days").toDate(); diff --git a/src/routes/auth/google-sign-in.js b/src/routes/auth/google-sign-in.js index c98ddcb..216a02a 100644 --- a/src/routes/auth/google-sign-in.js +++ b/src/routes/auth/google-sign-in.js @@ -59,8 +59,21 @@ module.exports = async (req, res) => { lastName: lastName || "", createdAt: new Date(), avatar: picture, + lastLogin: new Date(), }); await user.save(); + } else { + // Check if user is archived + if (user.isArchived) { + return res.status(403).json({ + error: "Account archived", + isArchived: true, + userId: user._id.toString() + }); + } + + // Update lastLogin for existing users + await User.findByIdAndUpdate(user._id, { lastLogin: new Date() }); } const token = jwt.sign({ userId: user._id }, process.env.JWT_SECRET, { diff --git a/src/routes/auth/index.js b/src/routes/auth/index.js index e6cb121..7ed6889 100644 --- a/src/routes/auth/index.js +++ b/src/routes/auth/index.js @@ -8,6 +8,7 @@ const appleSignin = require('./apple-sign-in'); const forgottenPassword = require('./forgotten-password'); const generateToken = require('./generate-token'); const googleSignIn = require('./google-sign-in'); +const reactivateAccount = require('./reactivate-account'); const resetPassword = require('./reset-password'); const signIn = require('./sign-in'); const signOut = require('./sign-out'); @@ -20,6 +21,7 @@ router.post('/facebook', facebookSignIn); router.post('/apple', appleSignin); router.post('/forgotten-password', forgottenPassword); router.post('/google', googleSignIn); +router.post('/reactivate-account', reactivateAccount); router.put('/reset-password', resetPassword); router.post('/sign-in', signIn); router.delete('/sign-out', isAuthenticated({ isOptional: false }), signOut); diff --git a/src/routes/auth/reactivate-account.js b/src/routes/auth/reactivate-account.js new file mode 100644 index 0000000..85dd55d --- /dev/null +++ b/src/routes/auth/reactivate-account.js @@ -0,0 +1,152 @@ +const bcrypt = require("bcrypt-nodejs"); +const crypto = require("crypto"); + +const jwt = require("jsonwebtoken"); +const moment = require("moment"); + +const { RefreshToken } = require("../../models/refresh-token"); +const { User } = require("../../models/user"); + +/** + * Reactivate an archived user account + * Requires: userId, new password, and updated profile information + * Sets isArchived to false and updates lastLogin + */ +module.exports = async (req, res, next) => { + const { + userId, + password, + firstName, + lastName, + email, + disabilities, + gender, + zip, + phone, + showDisabilities, + showEmail, + showPhone, + aboutMe, + birthday, + race, + disability, + } = req.body; + + // Validation + if (!userId) { + return res.status(400).json({ general: "User ID is required" }); + } + + if (!password || password.length < 6) { + return res.status(400).json({ + password: "Password must be at least 6 characters" + }); + } + + if (!firstName || !lastName) { + return res.status(400).json({ + general: "First name and last name are required" + }); + } + + if (!email) { + return res.status(400).json({ email: "Email is required" }); + } + + // Find user + let user; + try { + user = await User.findById(userId); + } catch (err) { + console.log(`User with ID ${userId} failed to be found at reactivation.`); + return next(err); + } + + if (!user) { + return res.status(404).json({ general: "User not found" }); + } + + if (!user.isArchived) { + return res.status(400).json({ + general: "Account is not archived" + }); + } + + // Hash new password + let hashedPassword; + try { + hashedPassword = await new Promise((resolve, reject) => { + bcrypt.genSalt(10, (saltErr, salt) => { + if (saltErr) return reject(saltErr); + + bcrypt.hash(password, salt, null, (hashErr, hash) => { + if (hashErr) return reject(hashErr); + resolve(hash); + }); + }); + }); + } catch (err) { + console.log("Failed to hash password during reactivation"); + return next(err); + } + + // Prepare update data + const updateData = { + hashedPassword, + firstName, + lastName, + email, + isArchived: false, + lastLogin: new Date(), + inactivityEmailSent: false, + inactivityEmailSentAt: null, + }; + + // Add optional fields if provided + if (disabilities !== undefined) updateData.disabilities = disabilities; + if (gender !== undefined) updateData.gender = gender; + if (zip !== undefined) updateData.zip = zip; + if (phone !== undefined) updateData.phone = phone; + if (showDisabilities !== undefined) updateData.showDisabilities = showDisabilities; + if (showEmail !== undefined) updateData.showEmail = showEmail; + if (showPhone !== undefined) updateData.showPhone = showPhone; + if (aboutMe !== undefined) updateData.aboutMe = aboutMe; + if (birthday !== undefined) updateData.birthday = birthday; + if (race !== undefined) updateData.race = race; + if (disability !== undefined) updateData.disability = disability; + + // Update user + try { + user = await User.findByIdAndUpdate(userId, updateData, { new: true }); + } catch (err) { + console.log(`Failed to reactivate user ${userId}`); + return next(err); + } + + // Generate tokens + const today = moment.utc(); + const expiresAt = today.add(30, "days").toDate(); + const key = `${userId}${crypto.randomBytes(28).toString("hex")}`; + + let refreshToken; + try { + refreshToken = await RefreshToken.findOneAndUpdate( + { userId }, + { expiresAt, key, userId }, + { new: true, setDefaultsOnInsert: true, upsert: true } + ); + } catch (err) { + console.log(`Refresh Token for userId ${userId} failed to be created at reactivation.`); + return next(err); + } + + const token = jwt.sign({ userId }, process.env.JWT_SECRET, { + expiresIn: '30d', + }); + + return res.status(200).json({ + refreshToken: refreshToken.key, + token, + message: "Account reactivated successfully" + }); +}; diff --git a/src/routes/auth/sign-in.js b/src/routes/auth/sign-in.js index 4a96d3e..3290057 100644 --- a/src/routes/auth/sign-in.js +++ b/src/routes/auth/sign-in.js @@ -45,6 +45,15 @@ module.exports = async (req, res, next) => { } const userId = user.id; + + // Update lastLogin timestamp + try { + await User.findByIdAndUpdate(userId, { lastLogin: new Date() }); + } catch (updateErr) { + console.log(`Failed to update lastLogin for userId ${userId}: ${updateErr.message}`); + // Continue with login even if lastLogin update fails + } + const today = moment.utc(); const expiresAt = today.add(30, "days").toDate(); const key = `${userId}${crypto.randomBytes(28).toString("hex")}`;