Created migrate script, updated CONTRIBUTING.md

This commit is contained in:
lukew3 2021-06-02 22:03:37 -04:00
parent 46e79d36af
commit 7845135c8a
10 changed files with 936 additions and 940 deletions

View file

@ -5,15 +5,53 @@
- NodeJS v10
- Firebase
## Prerequisite - Mongo setup
## Prerequisite - Firebase Setup
1. [Install MongoDB: Community Edition](https://docs.mongodb.com/manual/administration/install-community/)
1. Optional: [Install Mongodb Compass](https://www.mongodb.com/products/compass) for easier viewing and manipulation of data
1. [Create a new Firebase project.](https://console.firebase.google.com/u/0/)
- The project name doesn't really matter, but just name it `monkeytype`.
- Google Analytics is not necessary.
1. [Install the Firebase CLI](https://firebase.google.com/docs/cli)
1. Run `firebase login` on your terminal to log in to the same google account as you just used to create the project.
1. Git clone this project.
1. Duplicate `.firebaserc_example`, rename the new file to `.firebaserc` and change the project name of default to the firebase project id you just created.
- If `.firebaserc_example` does not exist after cloning, create your own with:
```.firebaserc
{
"projects": {
"default": "your-firebase-project-id"
}
}
```
- Run `firebase projects:list` to find your firebase project id.
1. Generate a Firebase Admin private key
- In your Firebase console, go to Project Settings > Service Accounts
- Click "Generate New Private Key"
- Save as `serviceAccountKey.json` in the `functions/` directory
1. Enable Firebase Authentication
- In the Firebase console, go to Authentication
- Click on `Email/Password`, enable it and save
- Click on `Google`, add a support email and save
## Prerequisite - Mongo Setup
1. Install [Mongodb Community Edition](https://docs.mongodb.com/manual/administration/install-community/) and ensure that it is running
1. Optional - Install [Mongodb-compass](https://www.mongodb.com/try/download/compass?tck=docs_compass). This tool can be used to see and manipulate your data visually.
## Building and Running
1. Run `npm ci` in the project root directory to install dependencies.
1. Run `npm run start:dev` to start a local dev server on port 5000. It will watch for changes and rebuild when you edit files in `src/` or `public/`. Use ctrl+c to stop it.
- Run `firebase use <your-project-id>` if you run into any errors for this.
## Standards and Conventions

81
backend/migrate.js Normal file
View file

@ -0,0 +1,81 @@
const admin = require("firebase-admin");
const mongoose = require("mongoose");
const { User } = require("./models/user");
const { Leaderboard } = require("./models/leaderboard");
const serviceAccount = require("../functions/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
var db = admin.firestore();
const port = process.env.PORT || "5005";
mongoose.connect("mongodb://localhost:27017/monkeytype", {
useNewUrlParser: true,
useUnifiedTopology: true,
});
userCount = 1;
db.collection("users")
.get()
.then((querySnapshot) => {
querySnapshot.forEach((userDoc) => {
let newUser = new User(userDoc.data());
newUser.uid = userDoc.id;
newUser.globalStats = {
started: userDoc.data().startedTests,
completed: userDoc.data().completedTests,
time: userDoc.data().timeTyping,
};
let tagIdDict = {};
db.collection(`users/${userDoc.id}/tags`)
.get()
.then((tagsSnapshot) => {
tagsSnapshot.forEach((tagDoc) => {
let formattedTag = tagDoc.data();
formattedTag._id = mongoose.Types.ObjectId(); //generate new objectId
tagIdDict[tagDoc.id] = formattedTag._id; //save pair of ids in memory to determine what to set new id as in result tags
newUser.tags.push(formattedTag);
});
db.collection(`users/${userDoc.id}/results`)
.get()
.then((resultsSnapshot) => {
resultsSnapshot.forEach((result) => {
let formattedResult = result.data();
formattedResult.tags.forEach((tag, index) => {
if (tagIdDict[tag])
formattedResult.tags[index] = tagIdDict[tag];
});
newUser.results.push(formattedResult);
});
newUser.results.sort((a, b) => {
return a.timestamp - b.timestamp;
});
db.collection(`users/${userDoc.id}/presets`)
.get()
.then((presetsSnapshot) => {
presetsSnapshot.forEach((preset) => {
newUser.presets.push(preset.data());
});
newUser.save();
console.log("User", userCount, "saved");
userCount++;
});
});
});
});
});
//not tested because I can't get leaderboards to work on my fork for some reason
db.collection("leaderboards")
.get()
.then((leaderboardsSnapshot) => {
leaderboardsSnapshot.forEach((lbDoc) => {
console.log(lbDoc);
let newLb = new Leaderboard(lbDoc);
newLb.save();
});
});

View file

@ -16,11 +16,11 @@ const leaderboardEntrySchema = new Schema({
const leaderboardSchema = new Schema(
{
resetTime: { type: Date }, //or Number, only on daily lb
size: { type: Number },
size: { type: Number, required: true },
board: [{ type: leaderboardEntrySchema }], //contents of leaderbaord
mode: { type: String }, //only equal to 'time' for now
mode2: { type: Number }, //only equal to 15 and 60 for now
type: { type: String }, //global or local
mode: { type: String, required: true }, //only equal to 'time' for now
mode2: { type: Number, required: true }, //only equal to 15 and 60 for now
type: { type: String, required: true }, //global or local
},
{
timestamps: true,

View file

@ -16,7 +16,7 @@ const configSchema = new Schema({
words: { type: Number },
time: { type: Number },
mode: { type: String },
quoteLength: [{ type: Number }], //not sure why this is an array
quoteLength: [{ type: Number }],
language: { type: String },
fontSize: { type: Number },
freedomMode: { type: Boolean },

View file

@ -12,15 +12,15 @@ const resultSchema = new Schema({
mode2: { type: Number, required: true }, //is this always number type?
quoteLength: { type: Number, required: true },
timestamp: { type: Number, required: true }, //can this be removed if timestamps are added to mongoose
language: { type: String, required: true },
language: { type: String, default: "english" },
restartCount: { type: Number, required: true },
incompleteTestSeconds: { type: Number, required: true },
testDuration: { type: Number, required: true },
afkDuration: { type: Number, required: true },
theme: { type: String, required: true },
tags: [{ type: String }], //the id of each tag
keySpacing: { type: String, required: true },
keyDuration: { type: String, required: true },
keySpacing: { type: String, default: "removed" }, //not sure what this or keyDuration is
keyDuration: { type: String, default: "removed" },
consistency: { type: Number, required: true },
keyConsistency: { type: Number, required: true },
chartData: {
@ -32,7 +32,7 @@ const resultSchema = new Schema({
customText: { type: Schema.Types.Mixed },
keySpacingStats: { type: Schema.Types.Mixed }, //not sure that this needs to exist, it's set as null in all of mine
name: { type: String, required: true }, //name of the user who took the test //should probably be typistName/username or something
isPb: { type: Boolean, required: true },
isPb: { type: Boolean, default: false },
});
module.exports = { resultSchema };

View file

@ -24,11 +24,9 @@ const userSchema = new Schema(
banned: { type: Boolean, default: false },
verified: { type: Boolean, default: false }, //Verified is actually whether or not discord account is connected
emailVerified: { type: Boolean, default: false },
verificationHashes: [{ type: String }],
lbMemory: {
//short for leaderboard memory
time15: {
global: { type: Number, default: -1 }, //might not be an Number, I'm not sure
global: { type: Number, default: -1 },
daily: { type: Number, default: -1 },
},
time60: {

View file

@ -1,17 +1,17 @@
# Mongo todo
## Todo
- Create a script to pull all data from monkeytype and move it to the new mongo server
## Bugs
- Graph bugs out when new result is added but page is not refreshed
- Graph loops back from earliest point to the new points
- Results list isn't updated either
- Result is added to end of list instead of front I think
- Could be fixed if list wasn't reversed and results were just rendered backwards
- Some methods in functions/index.js may be broken
- I think bot commands like lbUpdate and such
- Leaderboard entries that should be hidden are not
- If you are in first place and you place on the leaderboard but not above yourself, you get glb undefined error
- Might also occur if you are simply on the leaderboard and make the leaderboard but not above your current position
### Minor/efficiency bugs
@ -20,8 +20,6 @@
- For loop in account could work backwards instead, but this would add complexity
- Why does `if (page == "account") pageTransition = false;` get rid of endless account loading bug when accessing via url
- Name is not passed in user token/auth().currentUser
- Firestore read operations seem high
- Does this include index.html serving as well as user authentication or is there more?
- Account button sometimes shows loading infinitely after a test
- Can't navigate to user until page is refreshed
- After refresh, pr is not saved

View file

@ -576,6 +576,7 @@ app.get("/api/nameCheck/:name", (req, res) => {
return;
}
User.findOne({ name: req.params.name }, (err, user) => {
console.log(err);
if (user) {
res.status(200).send({
resultCode: -1,
@ -589,6 +590,11 @@ app.get("/api/nameCheck/:name", (req, res) => {
});
return;
}
}).catch(() => {
res.status(200).send({
resultCode: -1,
message: "Error when checking for names",
});
});
});

View file

@ -68,9 +68,9 @@
}
},
"node_modules/@firebase/database": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.1.tgz",
"integrity": "sha512-umT0kynJKc5VpVBOg3+YTDzdJORssh+QqPjoHfbSvtmgZizNiV8mgmKRcDhlVM6CisPb6v5xBn9l8JbK/WRQ1Q==",
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.2.tgz",
"integrity": "sha512-jMGtl5eBES9k0rOIZd6/EAuVB6m3LzRei1lvEiqWWBje2Xoz//7sjZcxOYtAKCCLldEI1EUrzW8Tv5yEAoPPpg==",
"dependencies": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.0",
@ -123,9 +123,9 @@
}
},
"node_modules/@google-cloud/firestore": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.1.tgz",
"integrity": "sha512-iNsCGYwKBxYZS+TpkUAJLGkGko2QtWaf11JDNx6kvqOVN0359qSnZlF1SWFTvm26ZsKyX6uR4oAiFmmjfXTlCg==",
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.12.2.tgz",
"integrity": "sha512-5rurTAJXQ0SANEf8K9eA2JAB5zAh+pu4tGRnkZx5gBWQLZXdBFdtepS+irvKuSXw1KbeAQOuRANSc/nguys6SQ==",
"optional": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
@ -201,9 +201,9 @@
}
},
"node_modules/@grpc/grpc-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.1.tgz",
"integrity": "sha512-zyFq9eW0U4vGyhJS/oeW3mIeKTzB13we9rBclcisfRHxGQbC9FCOKQ5BBA2129yZwRVMt4hQia1igGzECeuY9g==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz",
"integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==",
"optional": true,
"dependencies": {
"@types/node": ">=12.12.47"
@ -349,9 +349,9 @@
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz",
"integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz",
"integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==",
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
@ -367,9 +367,9 @@
}
},
"node_modules/@types/lodash": {
"version": "4.14.169",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz",
"integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw==",
"version": "4.14.170",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz",
"integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==",
"dev": true
},
"node_modules/@types/long": {
@ -389,9 +389,9 @@
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
},
"node_modules/@types/node": {
"version": "15.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz",
"integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ=="
"version": "15.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.9.0.tgz",
"integrity": "sha512-AR1Vq1Ei1GaA5FjKL5PBqblTZsL5M+monvGSZwe6sSIdGiuu7Xr/pNwWJY+0ZQuN8AapD/XMB5IzBAyYRFbocA=="
},
"node_modules/@types/qs": {
"version": "6.9.6",
@ -881,9 +881,9 @@
}
},
"node_modules/date-and-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.0.tgz",
"integrity": "sha512-477D7ypIiqlXBkxhU7YtG9wWZJEQ+RUpujt2quTfgf4+E8g5fNUkB0QIL0bVyP5/TKBg8y55Hfa1R/c4bt3dEw==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.1.tgz",
"integrity": "sha512-7u+uNfnjWkX+YFQfivvW24TjaJG6ahvTrfw1auq7KlC7osuGcZBIWGBvB9UcENjH6JnLVhMqlRripk1dSHjAUA==",
"optional": true
},
"node_modules/debug": {
@ -1494,9 +1494,9 @@
}
},
"node_modules/firebase-admin": {
"version": "9.8.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.8.0.tgz",
"integrity": "sha512-v8B1qU8McZZT2hlLZ018TKz2FoKlfFkZq9mOIyzN7wJUOlAywqQX0JyqNpVGyPeU+B+77ojlvmkGTNXt2OFkgw==",
"version": "9.9.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.9.0.tgz",
"integrity": "sha512-04HT7JAAqcJYty95qf15IBD9CXf+vr7S8zNU6Zt1ayC1J05DLaCsUd19/sCNAjZ614KHexAYUtyLgZoJwu2wOQ==",
"dependencies": {
"@firebase/database": "^0.10.0",
"@firebase/database-types": "^0.7.2",
@ -1507,7 +1507,7 @@
"node-forge": "^0.10.0"
},
"engines": {
"node": ">=10.10.0"
"node": ">=10.13.0"
},
"optionalDependencies": {
"@google-cloud/firestore": "^4.5.0",
@ -1515,9 +1515,9 @@
}
},
"node_modules/firebase-functions": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.0.tgz",
"integrity": "sha512-8f/UNxxbMBoNJkakGRmEoV+3i6LUVEOuiJdsMZR0L9x9NQ3rV0xCpUMPCA01HB+Mcx/NqAJCzE6n4gxg2uzcxg==",
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.1.tgz",
"integrity": "sha512-hL/qm+i5i1qKYmAFMlQ4mwRngDkP+3YT3F4E4Nd5Hj2QKeawBdZiMGgEt6zqTx08Zq04vHiSnSM0z75UJRSg6Q==",
"dependencies": {
"@types/express": "4.17.3",
"cors": "^2.8.5",
@ -1569,9 +1569,9 @@
"dev": true
},
"node_modules/forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"engines": {
"node": ">= 0.6"
}
@ -1597,9 +1597,9 @@
"devOptional": true
},
"node_modules/gaxios": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.1.tgz",
"integrity": "sha512-s+rTywpw6CmfB8r9TXYkpix7YFeuRjnR/AqhaJrQqsNhsAqej+IAiCc3hadzQH3gHyWth30tvYjxH8EVjQt/8Q==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz",
"integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==",
"optional": true,
"dependencies": {
"abort-controller": "^3.0.0",
@ -1697,9 +1697,9 @@
}
},
"node_modules/google-auth-library": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz",
"integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.1.tgz",
"integrity": "sha512-+Q1linq/To3DYLyPz4UTEkQ0v5EOXadMM/S+taLV3W9611hq9zqg8kgGApqbTQnggtwdO9yU1y2YT7+83wdTRg==",
"optional": true,
"dependencies": {
"arrify": "^2.0.0",
@ -1717,9 +1717,9 @@
}
},
"node_modules/google-gax": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.13.0.tgz",
"integrity": "sha512-aKNJy2+Vv2I7flyNYbwpq0aYBHp6Qv32HZn+wr6ZhZ8xlSCLS9K9k7izfh2nd1rCJQcsqB6KMxHV0Vwny6Rc1g==",
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.14.1.tgz",
"integrity": "sha512-I5RDEN7MEptrCxeHX3ht7nKFGfyjgYX4hQKI9eVMBohMzVbFSwWUndo0CcKXu8es7NhB4gt2XYLm1AHkXhtHpA==",
"optional": true,
"dependencies": {
"@grpc/grpc-js": "~1.3.0",
@ -2323,19 +2323,19 @@
}
},
"node_modules/mime-db": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"version": "2.1.31",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"dependencies": {
"mime-db": "1.47.0"
"mime-db": "1.48.0"
},
"engines": {
"node": ">= 0.6"
@ -2477,9 +2477,9 @@
}
},
"node_modules/object-hash": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz",
"integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
"optional": true,
"engines": {
"node": ">= 6"
@ -2797,11 +2797,11 @@
}
},
"node_modules/proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
"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.1.2",
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
@ -3325,9 +3325,9 @@
}
},
"node_modules/teeny-request": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz",
"integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.0.tgz",
"integrity": "sha512-hPfSc05a7Mf3syqVhSkrVMb844sMiP60MrfGMts3ft6V6UlSkEIGQzgwf0dy1KjdE3FV2lJ5s7QCBFcaoQLA6g==",
"optional": true,
"dependencies": {
"http-proxy-agent": "^4.0.0",
@ -3791,9 +3791,9 @@
}
},
"@firebase/database": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.1.tgz",
"integrity": "sha512-umT0kynJKc5VpVBOg3+YTDzdJORssh+QqPjoHfbSvtmgZizNiV8mgmKRcDhlVM6CisPb6v5xBn9l8JbK/WRQ1Q==",
"version": "0.10.2",
"resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.10.2.tgz",
"integrity": "sha512-jMGtl5eBES9k0rOIZd6/EAuVB6m3LzRei1lvEiqWWBje2Xoz//7sjZcxOYtAKCCLldEI1EUrzW8Tv5yEAoPPpg==",
"requires": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.0",
@ -3843,9 +3843,9 @@
}
},
"@google-cloud/firestore": {
"version": "4.11.1",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.11.1.tgz",
"integrity": "sha512-iNsCGYwKBxYZS+TpkUAJLGkGko2QtWaf11JDNx6kvqOVN0359qSnZlF1SWFTvm26ZsKyX6uR4oAiFmmjfXTlCg==",
"version": "4.12.2",
"resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.12.2.tgz",
"integrity": "sha512-5rurTAJXQ0SANEf8K9eA2JAB5zAh+pu4tGRnkZx5gBWQLZXdBFdtepS+irvKuSXw1KbeAQOuRANSc/nguys6SQ==",
"optional": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@ -3906,9 +3906,9 @@
}
},
"@grpc/grpc-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.1.tgz",
"integrity": "sha512-zyFq9eW0U4vGyhJS/oeW3mIeKTzB13we9rBclcisfRHxGQbC9FCOKQ5BBA2129yZwRVMt4hQia1igGzECeuY9g==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz",
"integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==",
"optional": true,
"requires": {
"@types/node": ">=12.12.47"
@ -4039,9 +4039,9 @@
}
},
"@types/express-serve-static-core": {
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz",
"integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz",
"integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==",
"requires": {
"@types/node": "*",
"@types/qs": "*",
@ -4057,9 +4057,9 @@
}
},
"@types/lodash": {
"version": "4.14.169",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz",
"integrity": "sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw==",
"version": "4.14.170",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz",
"integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==",
"dev": true
},
"@types/long": {
@ -4079,9 +4079,9 @@
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
},
"@types/node": {
"version": "15.0.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.3.tgz",
"integrity": "sha512-/WbxFeBU+0F79z9RdEOXH4CsDga+ibi5M8uEYr91u3CkT/pdWcV8MCook+4wDPnZBexRdwWS+PiVZ2xJviAzcQ=="
"version": "15.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.9.0.tgz",
"integrity": "sha512-AR1Vq1Ei1GaA5FjKL5PBqblTZsL5M+monvGSZwe6sSIdGiuu7Xr/pNwWJY+0ZQuN8AapD/XMB5IzBAyYRFbocA=="
},
"@types/qs": {
"version": "6.9.6",
@ -4465,9 +4465,9 @@
"optional": true
},
"date-and-time": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.0.tgz",
"integrity": "sha512-477D7ypIiqlXBkxhU7YtG9wWZJEQ+RUpujt2quTfgf4+E8g5fNUkB0QIL0bVyP5/TKBg8y55Hfa1R/c4bt3dEw==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-1.0.1.tgz",
"integrity": "sha512-7u+uNfnjWkX+YFQfivvW24TjaJG6ahvTrfw1auq7KlC7osuGcZBIWGBvB9UcENjH6JnLVhMqlRripk1dSHjAUA==",
"optional": true
},
"debug": {
@ -4956,9 +4956,9 @@
}
},
"firebase-admin": {
"version": "9.8.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.8.0.tgz",
"integrity": "sha512-v8B1qU8McZZT2hlLZ018TKz2FoKlfFkZq9mOIyzN7wJUOlAywqQX0JyqNpVGyPeU+B+77ojlvmkGTNXt2OFkgw==",
"version": "9.9.0",
"resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.9.0.tgz",
"integrity": "sha512-04HT7JAAqcJYty95qf15IBD9CXf+vr7S8zNU6Zt1ayC1J05DLaCsUd19/sCNAjZ614KHexAYUtyLgZoJwu2wOQ==",
"requires": {
"@firebase/database": "^0.10.0",
"@firebase/database-types": "^0.7.2",
@ -4972,9 +4972,9 @@
}
},
"firebase-functions": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.0.tgz",
"integrity": "sha512-8f/UNxxbMBoNJkakGRmEoV+3i6LUVEOuiJdsMZR0L9x9NQ3rV0xCpUMPCA01HB+Mcx/NqAJCzE6n4gxg2uzcxg==",
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.14.1.tgz",
"integrity": "sha512-hL/qm+i5i1qKYmAFMlQ4mwRngDkP+3YT3F4E4Nd5Hj2QKeawBdZiMGgEt6zqTx08Zq04vHiSnSM0z75UJRSg6Q==",
"requires": {
"@types/express": "4.17.3",
"cors": "^2.8.5",
@ -5010,9 +5010,9 @@
"dev": true
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fresh": {
"version": "0.5.2",
@ -5032,9 +5032,9 @@
"devOptional": true
},
"gaxios": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.2.1.tgz",
"integrity": "sha512-s+rTywpw6CmfB8r9TXYkpix7YFeuRjnR/AqhaJrQqsNhsAqej+IAiCc3hadzQH3gHyWth30tvYjxH8EVjQt/8Q==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.0.tgz",
"integrity": "sha512-pHplNbslpwCLMyII/lHPWFQbJWOX0B3R1hwBEOvzYi1GmdKZruuEHK4N9V6f7tf1EaPYyF80mui1+344p6SmLg==",
"optional": true,
"requires": {
"abort-controller": "^3.0.0",
@ -5102,9 +5102,9 @@
"dev": true
},
"google-auth-library": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.4.tgz",
"integrity": "sha512-o8irYyeijEiecTXeoEe8UKNEzV1X+uhR4b2oNdapDMZixypp0J+eHimGOyx5Joa3UAeokGngdtDLXtq9vDqG2Q==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.1.1.tgz",
"integrity": "sha512-+Q1linq/To3DYLyPz4UTEkQ0v5EOXadMM/S+taLV3W9611hq9zqg8kgGApqbTQnggtwdO9yU1y2YT7+83wdTRg==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
@ -5119,9 +5119,9 @@
}
},
"google-gax": {
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.13.0.tgz",
"integrity": "sha512-aKNJy2+Vv2I7flyNYbwpq0aYBHp6Qv32HZn+wr6ZhZ8xlSCLS9K9k7izfh2nd1rCJQcsqB6KMxHV0Vwny6Rc1g==",
"version": "2.14.1",
"resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.14.1.tgz",
"integrity": "sha512-I5RDEN7MEptrCxeHX3ht7nKFGfyjgYX4hQKI9eVMBohMzVbFSwWUndo0CcKXu8es7NhB4gt2XYLm1AHkXhtHpA==",
"optional": true,
"requires": {
"@grpc/grpc-js": "~1.3.0",
@ -5623,16 +5623,16 @@
"optional": true
},
"mime-db": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw=="
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
},
"mime-types": {
"version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"version": "2.1.31",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"requires": {
"mime-db": "1.47.0"
"mime-db": "1.48.0"
}
},
"mimic-fn": {
@ -5740,9 +5740,9 @@
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-hash": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.1.1.tgz",
"integrity": "sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
"integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
"optional": true
},
"on-finished": {
@ -5966,11 +5966,11 @@
}
},
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "~0.1.2",
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
@ -6384,9 +6384,9 @@
}
},
"teeny-request": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz",
"integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.1.0.tgz",
"integrity": "sha512-hPfSc05a7Mf3syqVhSkrVMb844sMiP60MrfGMts3ft6V6UlSkEIGQzgwf0dy1KjdE3FV2lJ5s7QCBFcaoQLA6g==",
"optional": true,
"requires": {
"http-proxy-agent": "^4.0.0",

1487
package-lock.json generated

File diff suppressed because it is too large Load diff