Compare commits
10 Commits
60697d80be
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| abd3458606 | |||
| 8841b571c9 | |||
| cf2df504b1 | |||
| 584ef9cbb7 | |||
| 597df4e886 | |||
|
|
63070fd90c | ||
| e50a6c91e6 | |||
| a49eb4e77c | |||
| 2a7eea5733 | |||
| ce0aa4f789 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
backend\node_modules
|
||||
backend/node_modules
|
||||
backend/.env
|
||||
|
||||
BIN
Documentation.docx
Normal file
BIN
Documentation.docx
Normal file
Binary file not shown.
BIN
Documentation.pdf
Normal file
BIN
Documentation.pdf
Normal file
Binary file not shown.
@@ -1,2 +1,3 @@
|
||||
PORT = 3001
|
||||
MONGO_URI = "mongodb+srv://timmybee:EMqczsTr1oYPBtCd@cluster0.dombm2a.mongodb.net/?appName=Cluster0"
|
||||
MONGO_URI = "mongodb+srv://timmybee:EMqczsTr1oYPBt@cluster0.dombm2a.mongodb.net/?appName=Cluster0"
|
||||
APP_URI = "http://localhost:3001"
|
||||
236
backend/index.js
236
backend/index.js
@@ -1,88 +1,184 @@
|
||||
require("dotenv").config();
|
||||
const express = require('express');
|
||||
const mongoose = require("mongoose")
|
||||
const cors = require('cors');
|
||||
|
||||
const port = 3001;
|
||||
const app = express();
|
||||
|
||||
app.use(express.json());
|
||||
app.use(cors());
|
||||
|
||||
app.use(cors("*"));
|
||||
|
||||
app.get("/test", async (req, res) => {
|
||||
res.send("Hello World!");
|
||||
});
|
||||
|
||||
const tasks = [
|
||||
{
|
||||
id: 1,
|
||||
completed: false,
|
||||
title: "Buy groceries for the week",
|
||||
description: "Pick up vegetables, fruits, milk, eggs, and bread from the supermarket.",
|
||||
dueDate: "14/03/2026",
|
||||
dateCreated: new Date(Date.now()).toLocaleDateString("en-AU")
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
completed: false,
|
||||
title: "Clean the apartment",
|
||||
description: "Vacuum the floors, wipe kitchen surfaces, and take out the trash.",
|
||||
dueDate: "16/03/2026",
|
||||
dateCreated: new Date(Date.now()).toLocaleDateString("en-AU")
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
completed: false,
|
||||
title: "Call the dentist for appointment",
|
||||
description: "Book a routine checkup and confirm available time slots for next week.",
|
||||
dueDate: "17/03/2026",
|
||||
dateCreated: new Date(Date.now()).toLocaleDateString("en-AU")
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
completed: true,
|
||||
title: "Do laundry and fold clothes",
|
||||
description: "Wash dark and light loads separately, then fold and organize clean clothes.",
|
||||
dueDate: "21/03/2026",
|
||||
dateCreated: new Date(Date.now()).toLocaleDateString("en-AU")
|
||||
}
|
||||
];
|
||||
|
||||
app.get("/api/tasks", async (req, res) => {
|
||||
(async () => {
|
||||
try {
|
||||
res.json(tasks);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Error: ${error}`)
|
||||
res.status(500).json({ message: "Error getting tasks" })
|
||||
}
|
||||
});
|
||||
mongoose.set("autoIndex", false);
|
||||
|
||||
app.post("/api/tasks/todo", async (req, res) => {
|
||||
await mongoose.connect(process.env.MONGO_URI);
|
||||
console.log("✅ MongoDB Connected");
|
||||
|
||||
await Task.syncIndexes();
|
||||
console.log("✅ Indexes created");
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`✅ To Do App listening on port ${port}`);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Startup Error! ${error}`);
|
||||
}
|
||||
})();
|
||||
|
||||
// Task Schema
|
||||
const taskSchema = new mongoose.Schema({
|
||||
title: { type: String, required: true },
|
||||
completed: { type: Boolean, required: true, default: false },
|
||||
description: { type: String, required: true },
|
||||
dueDate: { type: Date, required: true },
|
||||
dateCreated: { type: Date, required: true, default: new Date() }
|
||||
})
|
||||
|
||||
taskSchema.index({ dueDate: 1 })
|
||||
taskSchema.index({ dateCreated: 1 })
|
||||
|
||||
const Task = mongoose.model("Task", taskSchema);
|
||||
|
||||
// this api route gets all the tasks from our database.
|
||||
// if the request included a query string, use that for our sorting.
|
||||
app.get('/api/tasks', async (req, res) => {
|
||||
try {
|
||||
const { title, description, dueDate } = req.body;
|
||||
const { sortBy } = req.query; // destructs the sortBy from the query string. e.g. ?sortBy=dueDate or ?sortBy=dateCreated
|
||||
let sortOption = {}; // create an empty sort object for the database query
|
||||
|
||||
const newTask = {
|
||||
id: tasks.length + 1,
|
||||
completed: false,
|
||||
title, title,
|
||||
description, description,
|
||||
dueDate, dueDate,
|
||||
dateCreated: new Date(Date.now()).toLocaleDateString("en-AU"),
|
||||
};
|
||||
|
||||
tasks.push(newTask);
|
||||
|
||||
res.json(newTask);
|
||||
|
||||
res.status(201).json(newTask);
|
||||
if (sortBy === 'dueDate') {
|
||||
sortOption = { dueDate: 1 }; // if the sortBy query string is dueDate, set the sortOption to dueDate and set the order to ascending (1)
|
||||
} else if (sortBy === 'dateCreated') {
|
||||
sortOption = { dateCreated: 1 }; // if the sortBy query string is dateCreated, set the sortOption to dateCreated and set the order to ascending (1)
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`Error: ${error}`)
|
||||
res.status(500).json({ message: "Error creating task" })
|
||||
|
||||
const tasks = await Task.find({}).sort(sortOption); // fetch all task documents and sort them using sortOption
|
||||
|
||||
if (!tasks) {
|
||||
// return the following if the query failed to return a value
|
||||
return res.status(404).json({ message: "Tasks not found!" });
|
||||
}
|
||||
|
||||
res.json(tasks); // send a json response with the task objects
|
||||
} catch (error) {
|
||||
// if there are any errors, do the following
|
||||
console.error("Error:", error);
|
||||
res.status(500).json({ message: "Error grabbing tasks!" });
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// this api route takes post requests to save a new MongoDB document, aka, our task
|
||||
app.post('/api/tasks/todo', async (req, res) => {
|
||||
try {
|
||||
const { title, description, dueDate } = req.body; //destructures the request body
|
||||
const taskData = { title, description, dueDate }; // creating the object to be used for creating the task
|
||||
const createTask = new Task(taskData); // instantiates a new Task document/model instance using the taskData object values
|
||||
const newTask = await createTask.save(); // this saves the new document to MongoDB using the Task model/schema.
|
||||
|
||||
res.json({ task: newTask, message: "New task created successfully!" }); // if there were no error above, send a response where the body is an JSON object.
|
||||
|
||||
} catch (error) {
|
||||
// if there are any errors, do the following
|
||||
console.error("Error:", error);
|
||||
res.status(500).json({ message: "Error creating the task!" });
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`To Do App listening on port ${port}`);
|
||||
// this api route marks a task as complete using its id.
|
||||
|
||||
app.patch('/api/tasks/complete/:id', async (req, res) => {
|
||||
try {
|
||||
const { completed } = req.body; // expected boolean value coming from the frontend
|
||||
const taskId = req.params.id; // grab the task id from the URL params
|
||||
const completedTask = await Task.findByIdAndUpdate(taskId, { completed }, { new: true }); // update completed status and return updated document
|
||||
|
||||
if (!completedTask) {
|
||||
// return 404 if no task matches the provided id
|
||||
return res.status(404).json({ message: "Task not found!" });
|
||||
|
||||
}
|
||||
// return updated task document and confirmation message
|
||||
res.json({ task: completedTask, message: "Task set to 'Complete'" });
|
||||
|
||||
} catch (error) {
|
||||
// return 500 if database update fails
|
||||
console.error("Error:", error);
|
||||
res.status(500).json({ message: "Error completing the task!" });
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// this api route marks a task as not complete using its id.
|
||||
|
||||
app.patch('/api/tasks/notComplete/:id', async (req, res) => {
|
||||
|
||||
try {
|
||||
const { completed } = req.body; // expected boolean value coming from the frontend
|
||||
const taskId = req.params.id; // grab the task id from the URL params
|
||||
const taskNotComplete = await Task.findByIdAndUpdate(taskId, { completed }, { new: true }); // update completed status and return updated document
|
||||
|
||||
if (!taskNotComplete) {
|
||||
// return 404 if no task matches the provided id
|
||||
return res.status(404).json({ message: "Task not found!" });
|
||||
}
|
||||
// return updated task document and confirmation message
|
||||
res.json({ task: taskNotComplete, message: "Task set to 'Not Complete'" });
|
||||
} catch (error) {
|
||||
// return 500 if database update fails
|
||||
console.error("Error:", error);
|
||||
res.status(500).json({ message: "Error making the task NOT complete!" });
|
||||
}
|
||||
});
|
||||
|
||||
// this api route deletes a task by id.
|
||||
app.delete('/api/tasks/delete/:id', async (req, res) => {
|
||||
try {
|
||||
const taskId = req.params.id; // grab the task id from the URL params
|
||||
const deletedTask = await Task.findByIdAndDelete(taskId); // delete the matching task document
|
||||
|
||||
if (!deletedTask) {
|
||||
// return 404 if no task matches the provided id
|
||||
return res.status(404).json({ message: "Task not found!" });
|
||||
}
|
||||
|
||||
// return deleted task document and confirmation message
|
||||
res.json({ task: deletedTask, message: "Task deleted successfully!" });
|
||||
|
||||
} catch (error) {
|
||||
// return 500 if deletion fails
|
||||
console.error("Error:", error);
|
||||
res.status(500).json({ message: "Error deleting the task!" });
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// this api route updates a task's editable fields by id.
|
||||
|
||||
app.put('/api/tasks/update/:id', async (req, res) => {
|
||||
|
||||
try {
|
||||
const taskId = req.params.id; // grab the task id from the URL params
|
||||
const { title, description, dueDate } = req.body; // extract updated fields from request body
|
||||
const taskData = { title, description, dueDate }; // build the update object
|
||||
const updatedTask = await Task.findByIdAndUpdate(taskId, taskData, { new: true }); // apply update and return updated document
|
||||
|
||||
if (!updatedTask) {
|
||||
// return 404 if no task matches the provided id
|
||||
return res.status(404).json({ message: "Task not found!" });
|
||||
}
|
||||
|
||||
// return updated task document and confirmation message
|
||||
res.json({ task: updatedTask, message: "Task updated successfully!" });
|
||||
|
||||
} catch (error) {
|
||||
// return 500 if update fails
|
||||
console.error('Error:', error);
|
||||
res.status(500).json({ message: "Error updating the task!" });
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
54
backend/node_modules/.package-lock.json
generated
vendored
54
backend/node_modules/.package-lock.json
generated
vendored
@@ -502,6 +502,15 @@
|
||||
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/kareem": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-3.2.0.tgz",
|
||||
"integrity": "sha512-VS8MWZz/cT+SqBCpVfNN4zoVz5VskR3N4+sTmUXme55e9avQHntpwpNq0yjnosISXqwJ3AQVjlbI4Dyzv//JtA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@@ -622,6 +631,45 @@
|
||||
"node": ">=20.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mongoose": {
|
||||
"version": "9.3.3",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.3.3.tgz",
|
||||
"integrity": "sha512-sfv5LOIPWeN5o/281kp4Rx9ZnuXb0g8CtvBTi7trYQs2PYYx8LWXegXxG3ar7VEns1o+d4h9LI/Dtc7dTTyYmA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"kareem": "3.2.0",
|
||||
"mongodb": "~7.1",
|
||||
"mpath": "0.9.0",
|
||||
"mquery": "6.0.0",
|
||||
"ms": "2.1.3",
|
||||
"sift": "17.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mongoose"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"node_modules/mquery": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mquery/-/mquery-6.0.0.tgz",
|
||||
"integrity": "sha512-b2KQNsmgtkscfeDgkYMcWGn9vZI9YoXh802VDEwE6qc50zxBFQ0Oo8ROkawbPAsXCY1/Z1yp0MagqsZStPWJjw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -904,6 +952,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"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==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
|
||||
1
backend/node_modules/kareem/.nyc_output/fa57d6c4-9e78-4624-9229-f77b87a07481.json
generated
vendored
Normal file
1
backend/node_modules/kareem/.nyc_output/fa57d6c4-9e78-4624-9229-f77b87a07481.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1
backend/node_modules/kareem/.nyc_output/processinfo/fa57d6c4-9e78-4624-9229-f77b87a07481.json
generated
vendored
Normal file
1
backend/node_modules/kareem/.nyc_output/processinfo/fa57d6c4-9e78-4624-9229-f77b87a07481.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"parent":null,"pid":2678345,"argv":["/home/v/.nvm/versions/node/v20.18.1/bin/node","/home/v/Desktop/MongoDB/kareem/node_modules/.bin/mocha","./test/examples.test.js","./test/misc.test.js","./test/post.test.js","./test/pre.test.js","./test/wrap.test.js"],"execArgv":[],"cwd":"/home/v/Desktop/MongoDB/kareem","time":1756153005026,"ppid":2678334,"coverageFilename":"/home/v/Desktop/MongoDB/kareem/.nyc_output/fa57d6c4-9e78-4624-9229-f77b87a07481.json","externalId":"","uuid":"fa57d6c4-9e78-4624-9229-f77b87a07481","files":["/home/v/Desktop/MongoDB/kareem/index.js"]}
|
||||
1
backend/node_modules/kareem/.nyc_output/processinfo/index.json
generated
vendored
Normal file
1
backend/node_modules/kareem/.nyc_output/processinfo/index.json
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"processes":{"fa57d6c4-9e78-4624-9229-f77b87a07481":{"parent":null,"children":[]}},"files":{"/home/v/Desktop/MongoDB/kareem/index.js":["fa57d6c4-9e78-4624-9229-f77b87a07481"]},"externalIds":{}}
|
||||
840
backend/node_modules/kareem/CHANGELOG.md
generated
vendored
Normal file
840
backend/node_modules/kareem/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,840 @@
|
||||
# Changelog
|
||||
|
||||
<a name="3.2.0"></a>
|
||||
## 3.2.0 (2026-01-29)
|
||||
|
||||
* feat(exec): add filter option to execPreSync and execPostSync #44
|
||||
|
||||
<a name="3.1.0"></a>
|
||||
## 3.1.0 (2026-01-12)
|
||||
|
||||
* feat(exec): add filter option to allow executing hooks based on a filter function #43
|
||||
|
||||
<a name="3.0.0"></a>
|
||||
## 3.0.0 (2025-11-18)
|
||||
|
||||
* BREAKING CHANGE: make execPre async and drop callback support #39
|
||||
* BREAKING CHANGE: require Node 18
|
||||
* feat: overwriteArguments support #42
|
||||
|
||||
<a name="2.6.0"></a>
|
||||
## 2.6.0 (2024-03-04)
|
||||
|
||||
* feat: add TypeScript types
|
||||
|
||||
<a name="2.5.1"></a>
|
||||
## 2.5.1 (2023-01-06)
|
||||
|
||||
* fix: avoid passing final callback to pre hook, because calling the callback can mess up hook execution #36 Automattic/mongoose#12836
|
||||
|
||||
<a name="2.5.0"></a>
|
||||
## 2.5.0 (2022-12-01)
|
||||
|
||||
* feat: add errorHandler option to `post()` #34
|
||||
|
||||
<a name="2.4.0"></a>
|
||||
## 2.4.0 (2022-06-13)
|
||||
|
||||
* feat: add `overwriteResult()` and `skipWrappedFunction()` for more advanced control flow
|
||||
|
||||
<a name="2.3.4"></a>
|
||||
## 2.3.4 (2022-02-10)
|
||||
|
||||
* perf: various performance improvements #27 #24 #23 #22 #21 #20
|
||||
|
||||
<a name="2.3.3"></a>
|
||||
## 2.3.3 (2021-12-26)
|
||||
|
||||
* fix: handle sync errors in `wrap()`
|
||||
|
||||
<a name="2.3.2"></a>
|
||||
## 2.3.2 (2020-12-08)
|
||||
|
||||
* fix: handle sync errors in pre hooks if there are multiple hooks
|
||||
|
||||
<a name="2.3.0"></a>
|
||||
## 2.3.0 (2018-09-24)
|
||||
|
||||
* chore(release): 2.2.3 ([c8f2695](https://github.com/vkarpov15/kareem/commit/c8f2695))
|
||||
* chore(release): 2.2.4 ([a377a4f](https://github.com/vkarpov15/kareem/commit/a377a4f))
|
||||
* chore(release): 2.2.5 ([5a495e3](https://github.com/vkarpov15/kareem/commit/5a495e3))
|
||||
* fix(filter): copy async pres correctly with `filter()` ([1b1ed8a](https://github.com/vkarpov15/kareem/commit/1b1ed8a)), closes [Automattic/mongoose#3054](https://github.com/Automattic/mongoose/issues/3054)
|
||||
* feat: add filter() function ([1f641f4](https://github.com/vkarpov15/kareem/commit/1f641f4))
|
||||
* feat: support storing options on pre and post hooks ([59220b9](https://github.com/vkarpov15/kareem/commit/59220b9))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.3"></a>
|
||||
## <small>2.2.3 (2018-09-10)</small>
|
||||
|
||||
* chore: release 2.2.3 ([af653a3](https://github.com/vkarpov15/kareem/commit/af653a3))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.2"></a>
|
||||
## <small>2.2.2 (2018-09-10)</small>
|
||||
|
||||
* chore: release 2.2.2 ([3f0144d](https://github.com/vkarpov15/kareem/commit/3f0144d))
|
||||
* fix: allow merge() to not clone ([e628d65](https://github.com/vkarpov15/kareem/commit/e628d65))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.1"></a>
|
||||
## <small>2.2.1 (2018-06-05)</small>
|
||||
|
||||
* chore: release 2.2.1 ([4625a64](https://github.com/vkarpov15/kareem/commit/4625a64))
|
||||
* chore: remove lockfile from git ([7f3e4e6](https://github.com/vkarpov15/kareem/commit/7f3e4e6))
|
||||
* fix: handle numAsync correctly when merging ([fef8e7e](https://github.com/vkarpov15/kareem/commit/fef8e7e))
|
||||
* test: repro issue with not copying numAsync ([952d9db](https://github.com/vkarpov15/kareem/commit/952d9db))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.0"></a>
|
||||
## 2.2.0 (2018-06-05)
|
||||
|
||||
* chore: release 2.2.0 ([ff9ad03](https://github.com/vkarpov15/kareem/commit/ff9ad03))
|
||||
* fix: use maps instead of objects for _pres and _posts so `toString()` doesn't get reported as having ([55df303](https://github.com/vkarpov15/kareem/commit/55df303)), closes [Automattic/mongoose#6538](https://github.com/Automattic/mongoose/issues/6538)
|
||||
|
||||
|
||||
|
||||
<a name="2.1.0"></a>
|
||||
## 2.1.0 (2018-05-16)
|
||||
|
||||
* chore: release 2.1.0 ([ba5f1bc](https://github.com/vkarpov15/kareem/commit/ba5f1bc))
|
||||
* feat: add option to check wrapped function return value for promises ([c9d7dd1](https://github.com/vkarpov15/kareem/commit/c9d7dd1))
|
||||
* refactor: use const in wrap() ([0fc21f9](https://github.com/vkarpov15/kareem/commit/0fc21f9))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.7"></a>
|
||||
## <small>2.0.7 (2018-04-28)</small>
|
||||
|
||||
* chore: release 2.0.7 ([0bf91e6](https://github.com/vkarpov15/kareem/commit/0bf91e6))
|
||||
* feat: add `hasHooks()` ([225f18d](https://github.com/vkarpov15/kareem/commit/225f18d)), closes [Automattic/mongoose#6385](https://github.com/Automattic/mongoose/issues/6385)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.6"></a>
|
||||
## <small>2.0.6 (2018-03-22)</small>
|
||||
|
||||
* chore: release 2.0.6 ([f3d406b](https://github.com/vkarpov15/kareem/commit/f3d406b))
|
||||
* fix(wrap): ensure fast path still wraps function in `nextTick()` for chaining ([7000494](https://github.com/vkarpov15/kareem/commit/7000494)), closes [Automattic/mongoose#6250](https://github.com/Automattic/mongoose/issues/6250) [dsanel/mongoose-delete#36](https://github.com/dsanel/mongoose-delete/issues/36)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.5"></a>
|
||||
## <small>2.0.5 (2018-02-22)</small>
|
||||
|
||||
* chore: release 2.0.5 ([3286612](https://github.com/vkarpov15/kareem/commit/3286612))
|
||||
* perf(createWrapper): don't create wrapper if there are no hooks ([5afc5b9](https://github.com/vkarpov15/kareem/commit/5afc5b9)), closes [Automattic/mongoose#6126](https://github.com/Automattic/mongoose/issues/6126)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.4"></a>
|
||||
## <small>2.0.4 (2018-02-08)</small>
|
||||
|
||||
* chore: release 2.0.4 ([2ab0293](https://github.com/vkarpov15/kareem/commit/2ab0293))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.3"></a>
|
||||
## <small>2.0.3 (2018-02-01)</small>
|
||||
|
||||
* chore: release 2.0.3 ([3c1abe5](https://github.com/vkarpov15/kareem/commit/3c1abe5))
|
||||
* fix: use process.nextTick() re: Automattic/mongoose#6074 ([e5bfe33](https://github.com/vkarpov15/kareem/commit/e5bfe33)), closes [Automattic/mongoose#6074](https://github.com/Automattic/mongoose/issues/6074)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.2"></a>
|
||||
## <small>2.0.2 (2018-01-24)</small>
|
||||
|
||||
* chore: fix license ([a9d755c](https://github.com/vkarpov15/kareem/commit/a9d755c)), closes [#10](https://github.com/vkarpov15/kareem/issues/10)
|
||||
* chore: release 2.0.2 ([fe87ab6](https://github.com/vkarpov15/kareem/commit/fe87ab6))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.1"></a>
|
||||
## <small>2.0.1 (2018-01-09)</small>
|
||||
|
||||
* chore: release 2.0.1 with lockfile bump ([09c44fb](https://github.com/vkarpov15/kareem/commit/09c44fb))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
## 2.0.0 (2018-01-09)
|
||||
|
||||
* chore: bump marked re: security ([cc564a9](https://github.com/vkarpov15/kareem/commit/cc564a9))
|
||||
* chore: release 2.0.0 ([f511d1c](https://github.com/vkarpov15/kareem/commit/f511d1c))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc5"></a>
|
||||
## 2.0.0-rc5 (2017-12-23)
|
||||
|
||||
* chore: fix build on node 4+5 ([6dac5a4](https://github.com/vkarpov15/kareem/commit/6dac5a4))
|
||||
* chore: fix built on node 4 + 5 again ([434ef0a](https://github.com/vkarpov15/kareem/commit/434ef0a))
|
||||
* chore: release 2.0.0-rc5 ([25a32ee](https://github.com/vkarpov15/kareem/commit/25a32ee))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc4"></a>
|
||||
## 2.0.0-rc4 (2017-12-22)
|
||||
|
||||
* chore: release 2.0.0-rc4 ([49fc083](https://github.com/vkarpov15/kareem/commit/49fc083))
|
||||
* BREAKING CHANGE: deduplicate when merging hooks re: Automattic/mongoose#2945 ([d458573](https://github.com/vkarpov15/kareem/commit/d458573)), closes [Automattic/mongoose#2945](https://github.com/Automattic/mongoose/issues/2945)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc3"></a>
|
||||
## 2.0.0-rc3 (2017-12-22)
|
||||
|
||||
* chore: release 2.0.0-rc3 ([adaaa00](https://github.com/vkarpov15/kareem/commit/adaaa00))
|
||||
* feat: support returning promises from middleware functions ([05b4480](https://github.com/vkarpov15/kareem/commit/05b4480)), closes [Automattic/mongoose#3779](https://github.com/Automattic/mongoose/issues/3779)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc2"></a>
|
||||
## 2.0.0-rc2 (2017-12-21)
|
||||
|
||||
* chore: release 2.0.0-rc2 ([76325fa](https://github.com/vkarpov15/kareem/commit/76325fa))
|
||||
* fix: ensure next() and done() run in next tick ([6c20684](https://github.com/vkarpov15/kareem/commit/6c20684))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc1"></a>
|
||||
## 2.0.0-rc1 (2017-12-21)
|
||||
|
||||
* chore: improve test coverage re: Automattic/mongoose#3232 ([7b45cf0](https://github.com/vkarpov15/kareem/commit/7b45cf0)), closes [Automattic/mongoose#3232](https://github.com/Automattic/mongoose/issues/3232)
|
||||
* chore: release 2.0.0-rc1 ([9b83f52](https://github.com/vkarpov15/kareem/commit/9b83f52))
|
||||
* BREAKING CHANGE: report sync exceptions as errors, only allow calling next() and done() once ([674adcc](https://github.com/vkarpov15/kareem/commit/674adcc)), closes [Automattic/mongoose#3483](https://github.com/Automattic/mongoose/issues/3483)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc0"></a>
|
||||
## 2.0.0-rc0 (2017-12-17)
|
||||
|
||||
* chore: release 2.0.0-rc0 ([16b44b5](https://github.com/vkarpov15/kareem/commit/16b44b5))
|
||||
* BREAKING CHANGE: drop support for node < 4 ([9cbb8c7](https://github.com/vkarpov15/kareem/commit/9cbb8c7))
|
||||
* BREAKING CHANGE: remove useLegacyPost and add several new features ([6dd8531](https://github.com/vkarpov15/kareem/commit/6dd8531)), closes [Automattic/mongoose#3232](https://github.com/Automattic/mongoose/issues/3232)
|
||||
|
||||
|
||||
|
||||
<a name="1.5.0"></a>
|
||||
## 1.5.0 (2017-07-20)
|
||||
|
||||
* chore: release 1.5.0 ([9c491a0](https://github.com/vkarpov15/kareem/commit/9c491a0))
|
||||
* fix: improve post error handlers results ([9928dd5](https://github.com/vkarpov15/kareem/commit/9928dd5)), closes [Automattic/mongoose#5466](https://github.com/Automattic/mongoose/issues/5466)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.2"></a>
|
||||
## <small>1.4.2 (2017-07-06)</small>
|
||||
|
||||
* chore: release 1.4.2 ([8d14ac5](https://github.com/vkarpov15/kareem/commit/8d14ac5))
|
||||
* fix: correct args re: Automattic/mongoose#5405 ([3f28ae6](https://github.com/vkarpov15/kareem/commit/3f28ae6)), closes [Automattic/mongoose#5405](https://github.com/Automattic/mongoose/issues/5405)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.1"></a>
|
||||
## <small>1.4.1 (2017-04-25)</small>
|
||||
|
||||
* chore: release 1.4.1 ([5ecf0c2](https://github.com/vkarpov15/kareem/commit/5ecf0c2))
|
||||
* fix: handle numAsyncPres with clone() ([c72e857](https://github.com/vkarpov15/kareem/commit/c72e857)), closes [#8](https://github.com/vkarpov15/kareem/issues/8)
|
||||
* test: repro #8 ([9b4d6b2](https://github.com/vkarpov15/kareem/commit/9b4d6b2)), closes [#8](https://github.com/vkarpov15/kareem/issues/8)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0"></a>
|
||||
## 1.4.0 (2017-04-19)
|
||||
|
||||
* chore: release 1.4.0 ([101c5f5](https://github.com/vkarpov15/kareem/commit/101c5f5))
|
||||
* feat: add merge() function ([285325e](https://github.com/vkarpov15/kareem/commit/285325e))
|
||||
|
||||
|
||||
|
||||
<a name="1.3.0"></a>
|
||||
## 1.3.0 (2017-03-26)
|
||||
|
||||
* chore: release 1.3.0 ([f3a9e50](https://github.com/vkarpov15/kareem/commit/f3a9e50))
|
||||
* feat: pass function args to execPre ([4dd466d](https://github.com/vkarpov15/kareem/commit/4dd466d))
|
||||
|
||||
|
||||
|
||||
<a name="1.2.1"></a>
|
||||
## <small>1.2.1 (2017-02-03)</small>
|
||||
|
||||
* chore: release 1.2.1 ([d97081f](https://github.com/vkarpov15/kareem/commit/d97081f))
|
||||
* fix: filter out _kareemIgnored args for error handlers re: Automattic/mongoose#4925 ([ddc7aeb](https://github.com/vkarpov15/kareem/commit/ddc7aeb)), closes [Automattic/mongoose#4925](https://github.com/Automattic/mongoose/issues/4925)
|
||||
* fix: make error handlers handle errors in pre hooks ([af38033](https://github.com/vkarpov15/kareem/commit/af38033)), closes [Automattic/mongoose#4927](https://github.com/Automattic/mongoose/issues/4927)
|
||||
|
||||
|
||||
|
||||
<a name="1.2.0"></a>
|
||||
## 1.2.0 (2017-01-02)
|
||||
|
||||
* chore: release 1.2.0 ([033225c](https://github.com/vkarpov15/kareem/commit/033225c))
|
||||
* chore: upgrade deps ([f9e9a09](https://github.com/vkarpov15/kareem/commit/f9e9a09))
|
||||
* feat: add _kareemIgnore re: Automattic/mongoose#4836 ([7957771](https://github.com/vkarpov15/kareem/commit/7957771)), closes [Automattic/mongoose#4836](https://github.com/Automattic/mongoose/issues/4836)
|
||||
|
||||
|
||||
|
||||
<a name="1.1.5"></a>
|
||||
## <small>1.1.5 (2016-12-13)</small>
|
||||
|
||||
* chore: release 1.1.5 ([1a9f684](https://github.com/vkarpov15/kareem/commit/1a9f684))
|
||||
* fix: correct field name ([04a0e9d](https://github.com/vkarpov15/kareem/commit/04a0e9d))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.4"></a>
|
||||
## <small>1.1.4 (2016-12-09)</small>
|
||||
|
||||
* chore: release 1.1.4 ([ece401c](https://github.com/vkarpov15/kareem/commit/ece401c))
|
||||
* chore: run tests on node 6 ([e0cb1cb](https://github.com/vkarpov15/kareem/commit/e0cb1cb))
|
||||
* fix: only copy own properties in clone() ([dfe28ce](https://github.com/vkarpov15/kareem/commit/dfe28ce)), closes [#7](https://github.com/vkarpov15/kareem/issues/7)
|
||||
|
||||
|
||||
|
||||
<a name="1.1.3"></a>
|
||||
## <small>1.1.3 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.3 ([87171c8](https://github.com/vkarpov15/kareem/commit/87171c8))
|
||||
* fix: couple more issues with arg processing ([c65f523](https://github.com/vkarpov15/kareem/commit/c65f523))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.2"></a>
|
||||
## <small>1.1.2 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.2 ([8e102b6](https://github.com/vkarpov15/kareem/commit/8e102b6))
|
||||
* fix: add early return ([4feda4e](https://github.com/vkarpov15/kareem/commit/4feda4e))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.1"></a>
|
||||
## <small>1.1.1 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.1 ([8bb3050](https://github.com/vkarpov15/kareem/commit/8bb3050))
|
||||
* fix: skip error handlers if no error ([0eb3a44](https://github.com/vkarpov15/kareem/commit/0eb3a44))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.0"></a>
|
||||
## 1.1.0 (2016-05-11)
|
||||
|
||||
* chore: release 1.1.0 ([85332d9](https://github.com/vkarpov15/kareem/commit/85332d9))
|
||||
* chore: test on node 4 and node 5 ([1faefa1](https://github.com/vkarpov15/kareem/commit/1faefa1))
|
||||
* 100% coverage again ([c9aee4e](https://github.com/vkarpov15/kareem/commit/c9aee4e))
|
||||
* add support for error post hooks ([d378113](https://github.com/vkarpov15/kareem/commit/d378113))
|
||||
* basic setup for sync hooks #4 ([55aa081](https://github.com/vkarpov15/kareem/commit/55aa081)), closes [#4](https://github.com/vkarpov15/kareem/issues/4)
|
||||
* proof of concept for error handlers ([e4a07d9](https://github.com/vkarpov15/kareem/commit/e4a07d9))
|
||||
* refactor out handleWrapError helper ([b19af38](https://github.com/vkarpov15/kareem/commit/b19af38))
|
||||
|
||||
|
||||
|
||||
<a name="1.0.1"></a>
|
||||
## <small>1.0.1 (2015-05-10)</small>
|
||||
|
||||
* Fix #1 ([de60dc6](https://github.com/vkarpov15/kareem/commit/de60dc6)), closes [#1](https://github.com/vkarpov15/kareem/issues/1)
|
||||
* release 1.0.1 ([6971088](https://github.com/vkarpov15/kareem/commit/6971088))
|
||||
* Run tests on iojs in travis ([adcd201](https://github.com/vkarpov15/kareem/commit/adcd201))
|
||||
* support legacy post hook behavior in wrap() ([23fa74c](https://github.com/vkarpov15/kareem/commit/23fa74c))
|
||||
* Use node 0.12 in travis ([834689d](https://github.com/vkarpov15/kareem/commit/834689d))
|
||||
|
||||
|
||||
|
||||
<a name="1.0.0"></a>
|
||||
## 1.0.0 (2015-01-28)
|
||||
|
||||
* Tag 1.0.0 ([4c5a35a](https://github.com/vkarpov15/kareem/commit/4c5a35a))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.8"></a>
|
||||
## <small>0.0.8 (2015-01-27)</small>
|
||||
|
||||
* Add clone function ([688bba7](https://github.com/vkarpov15/kareem/commit/688bba7))
|
||||
* Add jscs for style checking ([5c93149](https://github.com/vkarpov15/kareem/commit/5c93149))
|
||||
* Bump 0.0.8 ([03c0d2f](https://github.com/vkarpov15/kareem/commit/03c0d2f))
|
||||
* Fix jscs config, add gulp rules ([9989abf](https://github.com/vkarpov15/kareem/commit/9989abf))
|
||||
* fix Makefile typo ([1f7e61a](https://github.com/vkarpov15/kareem/commit/1f7e61a))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.7"></a>
|
||||
## <small>0.0.7 (2015-01-04)</small>
|
||||
|
||||
* Bump 0.0.7 ([98ef173](https://github.com/vkarpov15/kareem/commit/98ef173))
|
||||
* fix LearnBoost/mongoose#2553 - use null instead of undefined for err ([9157b48](https://github.com/vkarpov15/kareem/commit/9157b48)), closes [LearnBoost/mongoose#2553](https://github.com/LearnBoost/mongoose/issues/2553)
|
||||
* Regenerate docs ([2331cdf](https://github.com/vkarpov15/kareem/commit/2331cdf))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.6"></a>
|
||||
## <small>0.0.6 (2015-01-01)</small>
|
||||
|
||||
* Update docs and bump 0.0.6 ([92c12a7](https://github.com/vkarpov15/kareem/commit/92c12a7))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.5"></a>
|
||||
## <small>0.0.5 (2015-01-01)</small>
|
||||
|
||||
* Add coverage rule to Makefile ([825a91c](https://github.com/vkarpov15/kareem/commit/825a91c))
|
||||
* Add coveralls to README ([fb52369](https://github.com/vkarpov15/kareem/commit/fb52369))
|
||||
* Add coveralls to travis ([93f6f15](https://github.com/vkarpov15/kareem/commit/93f6f15))
|
||||
* Add createWrapper() function ([ea77741](https://github.com/vkarpov15/kareem/commit/ea77741))
|
||||
* Add istanbul code coverage ([6eceeef](https://github.com/vkarpov15/kareem/commit/6eceeef))
|
||||
* Add some more comments for examples ([c5b0c6f](https://github.com/vkarpov15/kareem/commit/c5b0c6f))
|
||||
* Add travis ([e6dcb06](https://github.com/vkarpov15/kareem/commit/e6dcb06))
|
||||
* Add travis badge to docs ([ad8c9b3](https://github.com/vkarpov15/kareem/commit/ad8c9b3))
|
||||
* Add wrap() tests, 100% coverage ([6945be4](https://github.com/vkarpov15/kareem/commit/6945be4))
|
||||
* Better test coverage for execPost ([d9ad539](https://github.com/vkarpov15/kareem/commit/d9ad539))
|
||||
* Bump 0.0.5 ([69875b1](https://github.com/vkarpov15/kareem/commit/69875b1))
|
||||
* Docs fix ([15b7098](https://github.com/vkarpov15/kareem/commit/15b7098))
|
||||
* Fix silly mistake in docs generation ([50373eb](https://github.com/vkarpov15/kareem/commit/50373eb))
|
||||
* Fix typo in readme ([fec4925](https://github.com/vkarpov15/kareem/commit/fec4925))
|
||||
* Linkify travis badge ([92b25fe](https://github.com/vkarpov15/kareem/commit/92b25fe))
|
||||
* Make travis run coverage ([747157b](https://github.com/vkarpov15/kareem/commit/747157b))
|
||||
* Move travis status badge ([d52e89b](https://github.com/vkarpov15/kareem/commit/d52e89b))
|
||||
* Quick fix for coverage ([50bbddb](https://github.com/vkarpov15/kareem/commit/50bbddb))
|
||||
* Typo fix ([adea794](https://github.com/vkarpov15/kareem/commit/adea794))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.4"></a>
|
||||
## <small>0.0.4 (2014-12-13)</small>
|
||||
|
||||
* Bump 0.0.4, run docs generation ([51a15fe](https://github.com/vkarpov15/kareem/commit/51a15fe))
|
||||
* Use correct post parameters in wrap() ([9bb5da3](https://github.com/vkarpov15/kareem/commit/9bb5da3))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.3"></a>
|
||||
## <small>0.0.3 (2014-12-12)</small>
|
||||
|
||||
* Add npm test script, fix small bug with args not getting passed through post ([49e3e68](https://github.com/vkarpov15/kareem/commit/49e3e68))
|
||||
* Bump 0.0.3 ([65621d8](https://github.com/vkarpov15/kareem/commit/65621d8))
|
||||
* Update readme ([901388b](https://github.com/vkarpov15/kareem/commit/901388b))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.2"></a>
|
||||
## <small>0.0.2 (2014-12-12)</small>
|
||||
|
||||
* Add github repo and bump 0.0.2 ([59db8be](https://github.com/vkarpov15/kareem/commit/59db8be))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.1"></a>
|
||||
## <small>0.0.1 (2014-12-12)</small>
|
||||
|
||||
* Add basic docs ([ad29ea4](https://github.com/vkarpov15/kareem/commit/ad29ea4))
|
||||
* Add pre hooks ([2ffc356](https://github.com/vkarpov15/kareem/commit/2ffc356))
|
||||
* Add wrap function ([68c540c](https://github.com/vkarpov15/kareem/commit/68c540c))
|
||||
* Bump to version 0.0.1 ([a4bfd68](https://github.com/vkarpov15/kareem/commit/a4bfd68))
|
||||
* Initial commit ([4002458](https://github.com/vkarpov15/kareem/commit/4002458))
|
||||
* Initial deposit ([98fc489](https://github.com/vkarpov15/kareem/commit/98fc489))
|
||||
* Post hooks ([395b67c](https://github.com/vkarpov15/kareem/commit/395b67c))
|
||||
* Some basic setup work ([82df75e](https://github.com/vkarpov15/kareem/commit/82df75e))
|
||||
* Support sync pre hooks ([1cc1b9f](https://github.com/vkarpov15/kareem/commit/1cc1b9f))
|
||||
* Update package.json description ([978da18](https://github.com/vkarpov15/kareem/commit/978da18))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.5"></a>
|
||||
## <small>2.2.5 (2018-09-24)</small>
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="2.2.4"></a>
|
||||
## <small>2.2.4 (2018-09-24)</small>
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="2.2.3"></a>
|
||||
## <small>2.2.3 (2018-09-24)</small>
|
||||
|
||||
* fix(filter): copy async pres correctly with `filter()` ([1b1ed8a](https://github.com/vkarpov15/kareem/commit/1b1ed8a)), closes [Automattic/mongoose#3054](https://github.com/Automattic/mongoose/issues/3054)
|
||||
* feat: add filter() function ([1f641f4](https://github.com/vkarpov15/kareem/commit/1f641f4))
|
||||
* feat: support storing options on pre and post hooks ([59220b9](https://github.com/vkarpov15/kareem/commit/59220b9))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.3"></a>
|
||||
## <small>2.2.3 (2018-09-10)</small>
|
||||
|
||||
* chore: release 2.2.3 ([af653a3](https://github.com/vkarpov15/kareem/commit/af653a3))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.2"></a>
|
||||
## <small>2.2.2 (2018-09-10)</small>
|
||||
|
||||
* chore: release 2.2.2 ([3f0144d](https://github.com/vkarpov15/kareem/commit/3f0144d))
|
||||
* fix: allow merge() to not clone ([e628d65](https://github.com/vkarpov15/kareem/commit/e628d65))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.1"></a>
|
||||
## <small>2.2.1 (2018-06-05)</small>
|
||||
|
||||
* chore: release 2.2.1 ([4625a64](https://github.com/vkarpov15/kareem/commit/4625a64))
|
||||
* chore: remove lockfile from git ([7f3e4e6](https://github.com/vkarpov15/kareem/commit/7f3e4e6))
|
||||
* fix: handle numAsync correctly when merging ([fef8e7e](https://github.com/vkarpov15/kareem/commit/fef8e7e))
|
||||
* test: repro issue with not copying numAsync ([952d9db](https://github.com/vkarpov15/kareem/commit/952d9db))
|
||||
|
||||
|
||||
|
||||
<a name="2.2.0"></a>
|
||||
## 2.2.0 (2018-06-05)
|
||||
|
||||
* chore: release 2.2.0 ([ff9ad03](https://github.com/vkarpov15/kareem/commit/ff9ad03))
|
||||
* fix: use maps instead of objects for _pres and _posts so `toString()` doesn't get reported as having ([55df303](https://github.com/vkarpov15/kareem/commit/55df303)), closes [Automattic/mongoose#6538](https://github.com/Automattic/mongoose/issues/6538)
|
||||
|
||||
|
||||
|
||||
<a name="2.1.0"></a>
|
||||
## 2.1.0 (2018-05-16)
|
||||
|
||||
* chore: release 2.1.0 ([ba5f1bc](https://github.com/vkarpov15/kareem/commit/ba5f1bc))
|
||||
* feat: add option to check wrapped function return value for promises ([c9d7dd1](https://github.com/vkarpov15/kareem/commit/c9d7dd1))
|
||||
* refactor: use const in wrap() ([0fc21f9](https://github.com/vkarpov15/kareem/commit/0fc21f9))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.7"></a>
|
||||
## <small>2.0.7 (2018-04-28)</small>
|
||||
|
||||
* chore: release 2.0.7 ([0bf91e6](https://github.com/vkarpov15/kareem/commit/0bf91e6))
|
||||
* feat: add `hasHooks()` ([225f18d](https://github.com/vkarpov15/kareem/commit/225f18d)), closes [Automattic/mongoose#6385](https://github.com/Automattic/mongoose/issues/6385)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.6"></a>
|
||||
## <small>2.0.6 (2018-03-22)</small>
|
||||
|
||||
* chore: release 2.0.6 ([f3d406b](https://github.com/vkarpov15/kareem/commit/f3d406b))
|
||||
* fix(wrap): ensure fast path still wraps function in `nextTick()` for chaining ([7000494](https://github.com/vkarpov15/kareem/commit/7000494)), closes [Automattic/mongoose#6250](https://github.com/Automattic/mongoose/issues/6250) [dsanel/mongoose-delete#36](https://github.com/dsanel/mongoose-delete/issues/36)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.5"></a>
|
||||
## <small>2.0.5 (2018-02-22)</small>
|
||||
|
||||
* chore: release 2.0.5 ([3286612](https://github.com/vkarpov15/kareem/commit/3286612))
|
||||
* perf(createWrapper): don't create wrapper if there are no hooks ([5afc5b9](https://github.com/vkarpov15/kareem/commit/5afc5b9)), closes [Automattic/mongoose#6126](https://github.com/Automattic/mongoose/issues/6126)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.4"></a>
|
||||
## <small>2.0.4 (2018-02-08)</small>
|
||||
|
||||
* chore: release 2.0.4 ([2ab0293](https://github.com/vkarpov15/kareem/commit/2ab0293))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.3"></a>
|
||||
## <small>2.0.3 (2018-02-01)</small>
|
||||
|
||||
* chore: release 2.0.3 ([3c1abe5](https://github.com/vkarpov15/kareem/commit/3c1abe5))
|
||||
* fix: use process.nextTick() re: Automattic/mongoose#6074 ([e5bfe33](https://github.com/vkarpov15/kareem/commit/e5bfe33)), closes [Automattic/mongoose#6074](https://github.com/Automattic/mongoose/issues/6074)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.2"></a>
|
||||
## <small>2.0.2 (2018-01-24)</small>
|
||||
|
||||
* chore: fix license ([a9d755c](https://github.com/vkarpov15/kareem/commit/a9d755c)), closes [#10](https://github.com/vkarpov15/kareem/issues/10)
|
||||
* chore: release 2.0.2 ([fe87ab6](https://github.com/vkarpov15/kareem/commit/fe87ab6))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.1"></a>
|
||||
## <small>2.0.1 (2018-01-09)</small>
|
||||
|
||||
* chore: release 2.0.1 with lockfile bump ([09c44fb](https://github.com/vkarpov15/kareem/commit/09c44fb))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0"></a>
|
||||
## 2.0.0 (2018-01-09)
|
||||
|
||||
* chore: bump marked re: security ([cc564a9](https://github.com/vkarpov15/kareem/commit/cc564a9))
|
||||
* chore: release 2.0.0 ([f511d1c](https://github.com/vkarpov15/kareem/commit/f511d1c))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc5"></a>
|
||||
## 2.0.0-rc5 (2017-12-23)
|
||||
|
||||
* chore: fix build on node 4+5 ([6dac5a4](https://github.com/vkarpov15/kareem/commit/6dac5a4))
|
||||
* chore: fix built on node 4 + 5 again ([434ef0a](https://github.com/vkarpov15/kareem/commit/434ef0a))
|
||||
* chore: release 2.0.0-rc5 ([25a32ee](https://github.com/vkarpov15/kareem/commit/25a32ee))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc4"></a>
|
||||
## 2.0.0-rc4 (2017-12-22)
|
||||
|
||||
* chore: release 2.0.0-rc4 ([49fc083](https://github.com/vkarpov15/kareem/commit/49fc083))
|
||||
* BREAKING CHANGE: deduplicate when merging hooks re: Automattic/mongoose#2945 ([d458573](https://github.com/vkarpov15/kareem/commit/d458573)), closes [Automattic/mongoose#2945](https://github.com/Automattic/mongoose/issues/2945)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc3"></a>
|
||||
## 2.0.0-rc3 (2017-12-22)
|
||||
|
||||
* chore: release 2.0.0-rc3 ([adaaa00](https://github.com/vkarpov15/kareem/commit/adaaa00))
|
||||
* feat: support returning promises from middleware functions ([05b4480](https://github.com/vkarpov15/kareem/commit/05b4480)), closes [Automattic/mongoose#3779](https://github.com/Automattic/mongoose/issues/3779)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc2"></a>
|
||||
## 2.0.0-rc2 (2017-12-21)
|
||||
|
||||
* chore: release 2.0.0-rc2 ([76325fa](https://github.com/vkarpov15/kareem/commit/76325fa))
|
||||
* fix: ensure next() and done() run in next tick ([6c20684](https://github.com/vkarpov15/kareem/commit/6c20684))
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc1"></a>
|
||||
## 2.0.0-rc1 (2017-12-21)
|
||||
|
||||
* chore: improve test coverage re: Automattic/mongoose#3232 ([7b45cf0](https://github.com/vkarpov15/kareem/commit/7b45cf0)), closes [Automattic/mongoose#3232](https://github.com/Automattic/mongoose/issues/3232)
|
||||
* chore: release 2.0.0-rc1 ([9b83f52](https://github.com/vkarpov15/kareem/commit/9b83f52))
|
||||
* BREAKING CHANGE: report sync exceptions as errors, only allow calling next() and done() once ([674adcc](https://github.com/vkarpov15/kareem/commit/674adcc)), closes [Automattic/mongoose#3483](https://github.com/Automattic/mongoose/issues/3483)
|
||||
|
||||
|
||||
|
||||
<a name="2.0.0-rc0"></a>
|
||||
## 2.0.0-rc0 (2017-12-17)
|
||||
|
||||
* chore: release 2.0.0-rc0 ([16b44b5](https://github.com/vkarpov15/kareem/commit/16b44b5))
|
||||
* BREAKING CHANGE: drop support for node < 4 ([9cbb8c7](https://github.com/vkarpov15/kareem/commit/9cbb8c7))
|
||||
* BREAKING CHANGE: remove useLegacyPost and add several new features ([6dd8531](https://github.com/vkarpov15/kareem/commit/6dd8531)), closes [Automattic/mongoose#3232](https://github.com/Automattic/mongoose/issues/3232)
|
||||
|
||||
|
||||
|
||||
<a name="1.5.0"></a>
|
||||
## 1.5.0 (2017-07-20)
|
||||
|
||||
* chore: release 1.5.0 ([9c491a0](https://github.com/vkarpov15/kareem/commit/9c491a0))
|
||||
* fix: improve post error handlers results ([9928dd5](https://github.com/vkarpov15/kareem/commit/9928dd5)), closes [Automattic/mongoose#5466](https://github.com/Automattic/mongoose/issues/5466)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.2"></a>
|
||||
## <small>1.4.2 (2017-07-06)</small>
|
||||
|
||||
* chore: release 1.4.2 ([8d14ac5](https://github.com/vkarpov15/kareem/commit/8d14ac5))
|
||||
* fix: correct args re: Automattic/mongoose#5405 ([3f28ae6](https://github.com/vkarpov15/kareem/commit/3f28ae6)), closes [Automattic/mongoose#5405](https://github.com/Automattic/mongoose/issues/5405)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.1"></a>
|
||||
## <small>1.4.1 (2017-04-25)</small>
|
||||
|
||||
* chore: release 1.4.1 ([5ecf0c2](https://github.com/vkarpov15/kareem/commit/5ecf0c2))
|
||||
* fix: handle numAsyncPres with clone() ([c72e857](https://github.com/vkarpov15/kareem/commit/c72e857)), closes [#8](https://github.com/vkarpov15/kareem/issues/8)
|
||||
* test: repro #8 ([9b4d6b2](https://github.com/vkarpov15/kareem/commit/9b4d6b2)), closes [#8](https://github.com/vkarpov15/kareem/issues/8)
|
||||
|
||||
|
||||
|
||||
<a name="1.4.0"></a>
|
||||
## 1.4.0 (2017-04-19)
|
||||
|
||||
* chore: release 1.4.0 ([101c5f5](https://github.com/vkarpov15/kareem/commit/101c5f5))
|
||||
* feat: add merge() function ([285325e](https://github.com/vkarpov15/kareem/commit/285325e))
|
||||
|
||||
|
||||
|
||||
<a name="1.3.0"></a>
|
||||
## 1.3.0 (2017-03-26)
|
||||
|
||||
* chore: release 1.3.0 ([f3a9e50](https://github.com/vkarpov15/kareem/commit/f3a9e50))
|
||||
* feat: pass function args to execPre ([4dd466d](https://github.com/vkarpov15/kareem/commit/4dd466d))
|
||||
|
||||
|
||||
|
||||
<a name="1.2.1"></a>
|
||||
## <small>1.2.1 (2017-02-03)</small>
|
||||
|
||||
* chore: release 1.2.1 ([d97081f](https://github.com/vkarpov15/kareem/commit/d97081f))
|
||||
* fix: filter out _kareemIgnored args for error handlers re: Automattic/mongoose#4925 ([ddc7aeb](https://github.com/vkarpov15/kareem/commit/ddc7aeb)), closes [Automattic/mongoose#4925](https://github.com/Automattic/mongoose/issues/4925)
|
||||
* fix: make error handlers handle errors in pre hooks ([af38033](https://github.com/vkarpov15/kareem/commit/af38033)), closes [Automattic/mongoose#4927](https://github.com/Automattic/mongoose/issues/4927)
|
||||
|
||||
|
||||
|
||||
<a name="1.2.0"></a>
|
||||
## 1.2.0 (2017-01-02)
|
||||
|
||||
* chore: release 1.2.0 ([033225c](https://github.com/vkarpov15/kareem/commit/033225c))
|
||||
* chore: upgrade deps ([f9e9a09](https://github.com/vkarpov15/kareem/commit/f9e9a09))
|
||||
* feat: add _kareemIgnore re: Automattic/mongoose#4836 ([7957771](https://github.com/vkarpov15/kareem/commit/7957771)), closes [Automattic/mongoose#4836](https://github.com/Automattic/mongoose/issues/4836)
|
||||
|
||||
|
||||
|
||||
<a name="1.1.5"></a>
|
||||
## <small>1.1.5 (2016-12-13)</small>
|
||||
|
||||
* chore: release 1.1.5 ([1a9f684](https://github.com/vkarpov15/kareem/commit/1a9f684))
|
||||
* fix: correct field name ([04a0e9d](https://github.com/vkarpov15/kareem/commit/04a0e9d))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.4"></a>
|
||||
## <small>1.1.4 (2016-12-09)</small>
|
||||
|
||||
* chore: release 1.1.4 ([ece401c](https://github.com/vkarpov15/kareem/commit/ece401c))
|
||||
* chore: run tests on node 6 ([e0cb1cb](https://github.com/vkarpov15/kareem/commit/e0cb1cb))
|
||||
* fix: only copy own properties in clone() ([dfe28ce](https://github.com/vkarpov15/kareem/commit/dfe28ce)), closes [#7](https://github.com/vkarpov15/kareem/issues/7)
|
||||
|
||||
|
||||
|
||||
<a name="1.1.3"></a>
|
||||
## <small>1.1.3 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.3 ([87171c8](https://github.com/vkarpov15/kareem/commit/87171c8))
|
||||
* fix: couple more issues with arg processing ([c65f523](https://github.com/vkarpov15/kareem/commit/c65f523))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.2"></a>
|
||||
## <small>1.1.2 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.2 ([8e102b6](https://github.com/vkarpov15/kareem/commit/8e102b6))
|
||||
* fix: add early return ([4feda4e](https://github.com/vkarpov15/kareem/commit/4feda4e))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.1"></a>
|
||||
## <small>1.1.1 (2016-06-27)</small>
|
||||
|
||||
* chore: release 1.1.1 ([8bb3050](https://github.com/vkarpov15/kareem/commit/8bb3050))
|
||||
* fix: skip error handlers if no error ([0eb3a44](https://github.com/vkarpov15/kareem/commit/0eb3a44))
|
||||
|
||||
|
||||
|
||||
<a name="1.1.0"></a>
|
||||
## 1.1.0 (2016-05-11)
|
||||
|
||||
* chore: release 1.1.0 ([85332d9](https://github.com/vkarpov15/kareem/commit/85332d9))
|
||||
* chore: test on node 4 and node 5 ([1faefa1](https://github.com/vkarpov15/kareem/commit/1faefa1))
|
||||
* 100% coverage again ([c9aee4e](https://github.com/vkarpov15/kareem/commit/c9aee4e))
|
||||
* add support for error post hooks ([d378113](https://github.com/vkarpov15/kareem/commit/d378113))
|
||||
* basic setup for sync hooks #4 ([55aa081](https://github.com/vkarpov15/kareem/commit/55aa081)), closes [#4](https://github.com/vkarpov15/kareem/issues/4)
|
||||
* proof of concept for error handlers ([e4a07d9](https://github.com/vkarpov15/kareem/commit/e4a07d9))
|
||||
* refactor out handleWrapError helper ([b19af38](https://github.com/vkarpov15/kareem/commit/b19af38))
|
||||
|
||||
|
||||
|
||||
<a name="1.0.1"></a>
|
||||
## <small>1.0.1 (2015-05-10)</small>
|
||||
|
||||
* Fix #1 ([de60dc6](https://github.com/vkarpov15/kareem/commit/de60dc6)), closes [#1](https://github.com/vkarpov15/kareem/issues/1)
|
||||
* release 1.0.1 ([6971088](https://github.com/vkarpov15/kareem/commit/6971088))
|
||||
* Run tests on iojs in travis ([adcd201](https://github.com/vkarpov15/kareem/commit/adcd201))
|
||||
* support legacy post hook behavior in wrap() ([23fa74c](https://github.com/vkarpov15/kareem/commit/23fa74c))
|
||||
* Use node 0.12 in travis ([834689d](https://github.com/vkarpov15/kareem/commit/834689d))
|
||||
|
||||
|
||||
|
||||
<a name="1.0.0"></a>
|
||||
## 1.0.0 (2015-01-28)
|
||||
|
||||
* Tag 1.0.0 ([4c5a35a](https://github.com/vkarpov15/kareem/commit/4c5a35a))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.8"></a>
|
||||
## <small>0.0.8 (2015-01-27)</small>
|
||||
|
||||
* Add clone function ([688bba7](https://github.com/vkarpov15/kareem/commit/688bba7))
|
||||
* Add jscs for style checking ([5c93149](https://github.com/vkarpov15/kareem/commit/5c93149))
|
||||
* Bump 0.0.8 ([03c0d2f](https://github.com/vkarpov15/kareem/commit/03c0d2f))
|
||||
* Fix jscs config, add gulp rules ([9989abf](https://github.com/vkarpov15/kareem/commit/9989abf))
|
||||
* fix Makefile typo ([1f7e61a](https://github.com/vkarpov15/kareem/commit/1f7e61a))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.7"></a>
|
||||
## <small>0.0.7 (2015-01-04)</small>
|
||||
|
||||
* Bump 0.0.7 ([98ef173](https://github.com/vkarpov15/kareem/commit/98ef173))
|
||||
* fix LearnBoost/mongoose#2553 - use null instead of undefined for err ([9157b48](https://github.com/vkarpov15/kareem/commit/9157b48)), closes [LearnBoost/mongoose#2553](https://github.com/LearnBoost/mongoose/issues/2553)
|
||||
* Regenerate docs ([2331cdf](https://github.com/vkarpov15/kareem/commit/2331cdf))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.6"></a>
|
||||
## <small>0.0.6 (2015-01-01)</small>
|
||||
|
||||
* Update docs and bump 0.0.6 ([92c12a7](https://github.com/vkarpov15/kareem/commit/92c12a7))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.5"></a>
|
||||
## <small>0.0.5 (2015-01-01)</small>
|
||||
|
||||
* Add coverage rule to Makefile ([825a91c](https://github.com/vkarpov15/kareem/commit/825a91c))
|
||||
* Add coveralls to README ([fb52369](https://github.com/vkarpov15/kareem/commit/fb52369))
|
||||
* Add coveralls to travis ([93f6f15](https://github.com/vkarpov15/kareem/commit/93f6f15))
|
||||
* Add createWrapper() function ([ea77741](https://github.com/vkarpov15/kareem/commit/ea77741))
|
||||
* Add istanbul code coverage ([6eceeef](https://github.com/vkarpov15/kareem/commit/6eceeef))
|
||||
* Add some more comments for examples ([c5b0c6f](https://github.com/vkarpov15/kareem/commit/c5b0c6f))
|
||||
* Add travis ([e6dcb06](https://github.com/vkarpov15/kareem/commit/e6dcb06))
|
||||
* Add travis badge to docs ([ad8c9b3](https://github.com/vkarpov15/kareem/commit/ad8c9b3))
|
||||
* Add wrap() tests, 100% coverage ([6945be4](https://github.com/vkarpov15/kareem/commit/6945be4))
|
||||
* Better test coverage for execPost ([d9ad539](https://github.com/vkarpov15/kareem/commit/d9ad539))
|
||||
* Bump 0.0.5 ([69875b1](https://github.com/vkarpov15/kareem/commit/69875b1))
|
||||
* Docs fix ([15b7098](https://github.com/vkarpov15/kareem/commit/15b7098))
|
||||
* Fix silly mistake in docs generation ([50373eb](https://github.com/vkarpov15/kareem/commit/50373eb))
|
||||
* Fix typo in readme ([fec4925](https://github.com/vkarpov15/kareem/commit/fec4925))
|
||||
* Linkify travis badge ([92b25fe](https://github.com/vkarpov15/kareem/commit/92b25fe))
|
||||
* Make travis run coverage ([747157b](https://github.com/vkarpov15/kareem/commit/747157b))
|
||||
* Move travis status badge ([d52e89b](https://github.com/vkarpov15/kareem/commit/d52e89b))
|
||||
* Quick fix for coverage ([50bbddb](https://github.com/vkarpov15/kareem/commit/50bbddb))
|
||||
* Typo fix ([adea794](https://github.com/vkarpov15/kareem/commit/adea794))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.4"></a>
|
||||
## <small>0.0.4 (2014-12-13)</small>
|
||||
|
||||
* Bump 0.0.4, run docs generation ([51a15fe](https://github.com/vkarpov15/kareem/commit/51a15fe))
|
||||
* Use correct post parameters in wrap() ([9bb5da3](https://github.com/vkarpov15/kareem/commit/9bb5da3))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.3"></a>
|
||||
## <small>0.0.3 (2014-12-12)</small>
|
||||
|
||||
* Add npm test script, fix small bug with args not getting passed through post ([49e3e68](https://github.com/vkarpov15/kareem/commit/49e3e68))
|
||||
* Bump 0.0.3 ([65621d8](https://github.com/vkarpov15/kareem/commit/65621d8))
|
||||
* Update readme ([901388b](https://github.com/vkarpov15/kareem/commit/901388b))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.2"></a>
|
||||
## <small>0.0.2 (2014-12-12)</small>
|
||||
|
||||
* Add github repo and bump 0.0.2 ([59db8be](https://github.com/vkarpov15/kareem/commit/59db8be))
|
||||
|
||||
|
||||
|
||||
<a name="0.0.1"></a>
|
||||
## <small>0.0.1 (2014-12-12)</small>
|
||||
|
||||
* Add basic docs ([ad29ea4](https://github.com/vkarpov15/kareem/commit/ad29ea4))
|
||||
* Add pre hooks ([2ffc356](https://github.com/vkarpov15/kareem/commit/2ffc356))
|
||||
* Add wrap function ([68c540c](https://github.com/vkarpov15/kareem/commit/68c540c))
|
||||
* Bump to version 0.0.1 ([a4bfd68](https://github.com/vkarpov15/kareem/commit/a4bfd68))
|
||||
* Initial commit ([4002458](https://github.com/vkarpov15/kareem/commit/4002458))
|
||||
* Initial deposit ([98fc489](https://github.com/vkarpov15/kareem/commit/98fc489))
|
||||
* Post hooks ([395b67c](https://github.com/vkarpov15/kareem/commit/395b67c))
|
||||
* Some basic setup work ([82df75e](https://github.com/vkarpov15/kareem/commit/82df75e))
|
||||
* Support sync pre hooks ([1cc1b9f](https://github.com/vkarpov15/kareem/commit/1cc1b9f))
|
||||
* Update package.json description ([978da18](https://github.com/vkarpov15/kareem/commit/978da18))
|
||||
202
backend/node_modules/kareem/LICENSE
generated
vendored
Normal file
202
backend/node_modules/kareem/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014-2022 mongoosejs
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
385
backend/node_modules/kareem/README.md
generated
vendored
Normal file
385
backend/node_modules/kareem/README.md
generated
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
# kareem
|
||||
|
||||
[](https://github.com/mongoosejs/kareem/actions/workflows/test.yml)
|
||||
<!--[](https://coveralls.io/r/vkarpov15/kareem)-->
|
||||
|
||||
Re-imagined take on the [hooks](http://npmjs.org/package/hooks) module, meant to offer additional flexibility in allowing you to execute hooks whenever necessary, as opposed to simply wrapping a single function.
|
||||
|
||||
Named for the NBA's 2nd all-time leading scorer Kareem Abdul-Jabbar, known for his mastery of the [hook shot](http://en.wikipedia.org/wiki/Kareem_Abdul-Jabbar#Skyhook)
|
||||
|
||||
<img src="http://upload.wikimedia.org/wikipedia/commons/0/00/Kareem-Abdul-Jabbar_Lipofsky.jpg" width="220">
|
||||
|
||||
<!--DOCS START-->
|
||||
|
||||
# API
|
||||
|
||||
## pre hooks
|
||||
|
||||
Much like [hooks](https://npmjs.org/package/hooks), kareem lets you define
|
||||
pre and post hooks: pre hooks are called before a given function executes.
|
||||
Unlike hooks, kareem stores hooks and other internal state in a separate
|
||||
object, rather than relying on inheritance. Furthermore, kareem exposes
|
||||
an `execPre()` function that allows you to execute your pre hooks when
|
||||
appropriate, giving you more fine-grained control over your function hooks.
|
||||
|
||||
### It runs without any hooks specified
|
||||
|
||||
```javascript
|
||||
await hooks.execPre('cook', null);
|
||||
```
|
||||
|
||||
### It runs basic serial pre hooks
|
||||
|
||||
pre hook functions can return a promise that resolves when finished.
|
||||
|
||||
```javascript
|
||||
let count = 0;
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
++count;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
await hooks.execPre('cook', null);
|
||||
assert.equal(1, count);
|
||||
```
|
||||
|
||||
### It can run multiple pre hooks
|
||||
|
||||
```javascript
|
||||
let count1 = 0;
|
||||
let count2 = 0;
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
++count1;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
++count2;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
await hooks.execPre('cook', null);
|
||||
assert.equal(1, count1);
|
||||
assert.equal(1, count2);
|
||||
```
|
||||
|
||||
### It can run fully synchronous pre hooks
|
||||
|
||||
If your pre hook function takes no parameters, its assumed to be
|
||||
fully synchronous.
|
||||
|
||||
```javascript
|
||||
let count1 = 0;
|
||||
let count2 = 0;
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
++count1;
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
++count2;
|
||||
});
|
||||
|
||||
await hooks.execPre('cook', null);
|
||||
assert.equal(1, count1);
|
||||
assert.equal(1, count2);
|
||||
```
|
||||
|
||||
### It properly attaches context to pre hooks
|
||||
|
||||
Pre save hook functions are bound to the second parameter to `execPre()`
|
||||
|
||||
```javascript
|
||||
hooks.pre('cook', function() {
|
||||
this.bacon = 3;
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
this.eggs = 4;
|
||||
});
|
||||
|
||||
const obj = { bacon: 0, eggs: 0 };
|
||||
|
||||
// In the pre hooks, `this` will refer to `obj`
|
||||
await hooks.execPre('cook', obj);
|
||||
assert.equal(3, obj.bacon);
|
||||
assert.equal(4, obj.eggs);
|
||||
```
|
||||
|
||||
### It supports returning a promise
|
||||
|
||||
You can also return a promise from your pre hooks instead of calling
|
||||
`next()`. When the returned promise resolves, kareem will kick off the
|
||||
next middleware.
|
||||
|
||||
```javascript
|
||||
hooks.pre('cook', function() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
this.bacon = 3;
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
const obj = { bacon: 0 };
|
||||
|
||||
await hooks.execPre('cook', obj);
|
||||
assert.equal(3, obj.bacon);
|
||||
```
|
||||
|
||||
### It supports filtering which hooks to run
|
||||
|
||||
You can pass a `filter` option to `execPre()` to select which hooks
|
||||
to run. The filter function receives each hook object and should return
|
||||
`true` to run the hook or `false` to skip it.
|
||||
|
||||
```javascript
|
||||
const execed = [];
|
||||
|
||||
const fn1 = function() { execed.push('first'); };
|
||||
fn1.skipMe = true;
|
||||
hooks.pre('cook', fn1);
|
||||
|
||||
const fn2 = function() { execed.push('second'); };
|
||||
hooks.pre('cook', fn2);
|
||||
|
||||
// Only runs fn2, skips fn1 because fn1.skipMe is true
|
||||
await hooks.execPre('cook', null, [], {
|
||||
filter: hook => !hook.fn.skipMe
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(execed, ['second']);
|
||||
```
|
||||
|
||||
## post hooks
|
||||
|
||||
### It runs without any hooks specified
|
||||
|
||||
```javascript
|
||||
const [eggs] = await hooks.execPost('cook', null, [1]);
|
||||
assert.equal(eggs, 1);
|
||||
```
|
||||
|
||||
### It executes with parameters passed in
|
||||
|
||||
```javascript
|
||||
hooks.post('cook', function(eggs, bacon, callback) {
|
||||
assert.equal(eggs, 1);
|
||||
assert.equal(bacon, 2);
|
||||
callback();
|
||||
});
|
||||
|
||||
const [eggs, bacon] = await hooks.execPost('cook', null, [1, 2]);
|
||||
assert.equal(eggs, 1);
|
||||
assert.equal(bacon, 2);
|
||||
```
|
||||
|
||||
### It can use synchronous post hooks
|
||||
|
||||
```javascript
|
||||
const execed = {};
|
||||
|
||||
hooks.post('cook', function(eggs, bacon) {
|
||||
execed.first = true;
|
||||
assert.equal(eggs, 1);
|
||||
assert.equal(bacon, 2);
|
||||
});
|
||||
|
||||
hooks.post('cook', function(eggs, bacon, callback) {
|
||||
execed.second = true;
|
||||
assert.equal(eggs, 1);
|
||||
assert.equal(bacon, 2);
|
||||
callback();
|
||||
});
|
||||
|
||||
const [eggs, bacon] = await hooks.execPost('cook', null, [1, 2]);
|
||||
assert.equal(Object.keys(execed).length, 2);
|
||||
assert.ok(execed.first);
|
||||
assert.ok(execed.second);
|
||||
assert.equal(eggs, 1);
|
||||
assert.equal(bacon, 2);
|
||||
```
|
||||
|
||||
### It supports returning a promise
|
||||
|
||||
You can also return a promise from your post hooks instead of calling
|
||||
`next()`. When the returned promise resolves, kareem will kick off the
|
||||
next middleware.
|
||||
|
||||
```javascript
|
||||
hooks.post('cook', function() {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
this.bacon = 3;
|
||||
resolve();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
const obj = { bacon: 0 };
|
||||
|
||||
await hooks.execPost('cook', obj, [obj]);
|
||||
assert.equal(obj.bacon, 3);
|
||||
```
|
||||
|
||||
### It supports filtering which hooks to run
|
||||
|
||||
You can pass a `filter` option to `execPost()` to select which hooks
|
||||
to run. The filter function receives each hook object and should return
|
||||
`true` to run the hook or `false` to skip it.
|
||||
|
||||
```javascript
|
||||
const execed = [];
|
||||
|
||||
const fn1 = function() { execed.push('first'); };
|
||||
fn1.skipMe = true;
|
||||
hooks.post('cook', fn1);
|
||||
|
||||
const fn2 = function() { execed.push('second'); };
|
||||
hooks.post('cook', fn2);
|
||||
|
||||
// Only runs fn2, skips fn1 because fn1.skipMe is true
|
||||
await hooks.execPost('cook', null, [], {
|
||||
filter: hook => !hook.fn.skipMe
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(execed, ['second']);
|
||||
```
|
||||
|
||||
## wrap()
|
||||
|
||||
### It wraps pre and post calls into one call
|
||||
|
||||
```javascript
|
||||
hooks.pre('cook', function() {
|
||||
return new Promise(resolve => {
|
||||
this.bacon = 3;
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, 5);
|
||||
});
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
this.eggs = 4;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
this.waffles = false;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
hooks.post('cook', function(obj) {
|
||||
obj.tofu = 'no';
|
||||
});
|
||||
|
||||
const obj = { bacon: 0, eggs: 0 };
|
||||
|
||||
const args = [obj];
|
||||
|
||||
const result = await hooks.wrap(
|
||||
'cook',
|
||||
function(o) {
|
||||
assert.equal(obj.bacon, 3);
|
||||
assert.equal(obj.eggs, 4);
|
||||
assert.equal(obj.waffles, false);
|
||||
assert.equal(obj.tofu, undefined);
|
||||
return o;
|
||||
},
|
||||
obj,
|
||||
args);
|
||||
|
||||
assert.equal(obj.bacon, 3);
|
||||
assert.equal(obj.eggs, 4);
|
||||
assert.equal(obj.waffles, false);
|
||||
assert.equal(obj.tofu, 'no');
|
||||
assert.equal(result, obj);
|
||||
```
|
||||
|
||||
## createWrapper()
|
||||
|
||||
### It wraps wrap() into a callable function
|
||||
|
||||
```javascript
|
||||
hooks.pre('cook', function() {
|
||||
this.bacon = 3;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
return new Promise(resolve => {
|
||||
this.eggs = 4;
|
||||
setTimeout(function() {
|
||||
resolve();
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
|
||||
hooks.pre('cook', function() {
|
||||
this.waffles = false;
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
hooks.post('cook', function(obj) {
|
||||
obj.tofu = 'no';
|
||||
});
|
||||
|
||||
const obj = { bacon: 0, eggs: 0 };
|
||||
|
||||
const cook = hooks.createWrapper(
|
||||
'cook',
|
||||
function(o) {
|
||||
assert.equal(3, obj.bacon);
|
||||
assert.equal(4, obj.eggs);
|
||||
assert.equal(false, obj.waffles);
|
||||
assert.equal(undefined, obj.tofu);
|
||||
return o;
|
||||
},
|
||||
obj);
|
||||
|
||||
const result = await cook(obj);
|
||||
assert.equal(obj.bacon, 3);
|
||||
assert.equal(obj.eggs, 4);
|
||||
assert.equal(obj.waffles, false);
|
||||
assert.equal(obj.tofu, 'no');
|
||||
|
||||
assert.equal(result, obj);
|
||||
```
|
||||
|
||||
## clone()
|
||||
|
||||
### It clones a Kareem object
|
||||
|
||||
```javascript
|
||||
const k1 = new Kareem();
|
||||
k1.pre('cook', function() {});
|
||||
k1.post('cook', function() {});
|
||||
|
||||
const k2 = k1.clone();
|
||||
assert.deepEqual(Array.from(k2._pres.keys()), ['cook']);
|
||||
assert.deepEqual(Array.from(k2._posts.keys()), ['cook']);
|
||||
```
|
||||
|
||||
## merge()
|
||||
|
||||
### It pulls hooks from another Kareem object
|
||||
|
||||
```javascript
|
||||
const k1 = new Kareem();
|
||||
const test1 = function() {};
|
||||
k1.pre('cook', test1);
|
||||
k1.post('cook', function() {});
|
||||
|
||||
const k2 = new Kareem();
|
||||
const test2 = function() {};
|
||||
k2.pre('cook', test2);
|
||||
const k3 = k2.merge(k1);
|
||||
assert.equal(k3._pres.get('cook').length, 2);
|
||||
assert.equal(k3._pres.get('cook')[0].fn, test2);
|
||||
assert.equal(k3._pres.get('cook')[1].fn, test1);
|
||||
assert.equal(k3._posts.get('cook').length, 1);
|
||||
```
|
||||
5
backend/node_modules/kareem/SECURITY.md
generated
vendored
Normal file
5
backend/node_modules/kareem/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
## Security contact information
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
224
backend/node_modules/kareem/coverage/lcov-report/base.css
generated
vendored
Normal file
224
backend/node_modules/kareem/coverage/lcov-report/base.css
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
body, html {
|
||||
margin:0; padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
font-family: Helvetica Neue, Helvetica, Arial;
|
||||
font-size: 14px;
|
||||
color:#333;
|
||||
}
|
||||
.small { font-size: 12px; }
|
||||
*, *:after, *:before {
|
||||
-webkit-box-sizing:border-box;
|
||||
-moz-box-sizing:border-box;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
h1 { font-size: 20px; margin: 0;}
|
||||
h2 { font-size: 14px; }
|
||||
pre {
|
||||
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-tab-size: 2;
|
||||
-o-tab-size: 2;
|
||||
tab-size: 2;
|
||||
}
|
||||
a { color:#0074D9; text-decoration:none; }
|
||||
a:hover { text-decoration:underline; }
|
||||
.strong { font-weight: bold; }
|
||||
.space-top1 { padding: 10px 0 0 0; }
|
||||
.pad2y { padding: 20px 0; }
|
||||
.pad1y { padding: 10px 0; }
|
||||
.pad2x { padding: 0 20px; }
|
||||
.pad2 { padding: 20px; }
|
||||
.pad1 { padding: 10px; }
|
||||
.space-left2 { padding-left:55px; }
|
||||
.space-right2 { padding-right:20px; }
|
||||
.center { text-align:center; }
|
||||
.clearfix { display:block; }
|
||||
.clearfix:after {
|
||||
content:'';
|
||||
display:block;
|
||||
height:0;
|
||||
clear:both;
|
||||
visibility:hidden;
|
||||
}
|
||||
.fl { float: left; }
|
||||
@media only screen and (max-width:640px) {
|
||||
.col3 { width:100%; max-width:100%; }
|
||||
.hide-mobile { display:none!important; }
|
||||
}
|
||||
|
||||
.quiet {
|
||||
color: #7f7f7f;
|
||||
color: rgba(0,0,0,0.5);
|
||||
}
|
||||
.quiet a { opacity: 0.7; }
|
||||
|
||||
.fraction {
|
||||
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||
font-size: 10px;
|
||||
color: #555;
|
||||
background: #E8E8E8;
|
||||
padding: 4px 5px;
|
||||
border-radius: 3px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.path a:link, div.path a:visited { color: #333; }
|
||||
table.coverage {
|
||||
border-collapse: collapse;
|
||||
margin: 10px 0 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.coverage td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
table.coverage td.line-count {
|
||||
text-align: right;
|
||||
padding: 0 5px 0 20px;
|
||||
}
|
||||
table.coverage td.line-coverage {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
min-width:20px;
|
||||
}
|
||||
|
||||
table.coverage td span.cline-any {
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
width: 100%;
|
||||
}
|
||||
.missing-if-branch {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
padding: 0 4px;
|
||||
background: #333;
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
.skip-if-branch {
|
||||
display: none;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
padding: 0 4px;
|
||||
background: #ccc;
|
||||
color: white;
|
||||
}
|
||||
.missing-if-branch .typ, .skip-if-branch .typ {
|
||||
color: inherit !important;
|
||||
}
|
||||
.coverage-summary {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
||||
.keyline-all { border: 1px solid #ddd; }
|
||||
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
||||
.coverage-summary tbody { border: 1px solid #bbb; }
|
||||
.coverage-summary td { border-right: 1px solid #bbb; }
|
||||
.coverage-summary td:last-child { border-right: none; }
|
||||
.coverage-summary th {
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.coverage-summary th.file { border-right: none !important; }
|
||||
.coverage-summary th.pct { }
|
||||
.coverage-summary th.pic,
|
||||
.coverage-summary th.abs,
|
||||
.coverage-summary td.pct,
|
||||
.coverage-summary td.abs { text-align: right; }
|
||||
.coverage-summary td.file { white-space: nowrap; }
|
||||
.coverage-summary td.pic { min-width: 120px !important; }
|
||||
.coverage-summary tfoot td { }
|
||||
|
||||
.coverage-summary .sorter {
|
||||
height: 10px;
|
||||
width: 7px;
|
||||
display: inline-block;
|
||||
margin-left: 0.5em;
|
||||
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
||||
}
|
||||
.coverage-summary .sorted .sorter {
|
||||
background-position: 0 -20px;
|
||||
}
|
||||
.coverage-summary .sorted-desc .sorter {
|
||||
background-position: 0 -10px;
|
||||
}
|
||||
.status-line { height: 10px; }
|
||||
/* yellow */
|
||||
.cbranch-no { background: yellow !important; color: #111; }
|
||||
/* dark red */
|
||||
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
||||
.low .chart { border:1px solid #C21F39 }
|
||||
.highlighted,
|
||||
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
||||
background: #C21F39 !important;
|
||||
}
|
||||
/* medium red */
|
||||
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
||||
/* light red */
|
||||
.low, .cline-no { background:#FCE1E5 }
|
||||
/* light green */
|
||||
.high, .cline-yes { background:rgb(230,245,208) }
|
||||
/* medium green */
|
||||
.cstat-yes { background:rgb(161,215,106) }
|
||||
/* dark green */
|
||||
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
||||
.high .chart { border:1px solid rgb(77,146,33) }
|
||||
/* dark yellow (gold) */
|
||||
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
||||
.medium .chart { border:1px solid #f9cd0b; }
|
||||
/* light yellow */
|
||||
.medium { background: #fff4c2; }
|
||||
|
||||
.cstat-skip { background: #ddd; color: #111; }
|
||||
.fstat-skip { background: #ddd; color: #111 !important; }
|
||||
.cbranch-skip { background: #ddd !important; color: #111; }
|
||||
|
||||
span.cline-neutral { background: #eaeaea; }
|
||||
|
||||
.coverage-summary td.empty {
|
||||
opacity: .5;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
line-height: 1;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.cover-fill, .cover-empty {
|
||||
display:inline-block;
|
||||
height: 12px;
|
||||
}
|
||||
.chart {
|
||||
line-height: 0;
|
||||
}
|
||||
.cover-empty {
|
||||
background: white;
|
||||
}
|
||||
.cover-full {
|
||||
border-right: none !important;
|
||||
}
|
||||
pre.prettyprint {
|
||||
border: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.com { color: #999 !important; }
|
||||
.ignore-none { color: #999; font-weight: normal; }
|
||||
|
||||
.wrapper {
|
||||
min-height: 100%;
|
||||
height: auto !important;
|
||||
height: 100%;
|
||||
margin: 0 auto -48px;
|
||||
}
|
||||
.footer, .push {
|
||||
height: 48px;
|
||||
}
|
||||
87
backend/node_modules/kareem/coverage/lcov-report/block-navigation.js
generated
vendored
Normal file
87
backend/node_modules/kareem/coverage/lcov-report/block-navigation.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/* eslint-disable */
|
||||
var jumpToCode = (function init() {
|
||||
// Classes of code we would like to highlight in the file view
|
||||
var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
|
||||
|
||||
// Elements to highlight in the file listing view
|
||||
var fileListingElements = ['td.pct.low'];
|
||||
|
||||
// We don't want to select elements that are direct descendants of another match
|
||||
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
|
||||
|
||||
// Selecter that finds elements on the page to which we can jump
|
||||
var selector =
|
||||
fileListingElements.join(', ') +
|
||||
', ' +
|
||||
notSelector +
|
||||
missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
|
||||
|
||||
// The NodeList of matching elements
|
||||
var missingCoverageElements = document.querySelectorAll(selector);
|
||||
|
||||
var currentIndex;
|
||||
|
||||
function toggleClass(index) {
|
||||
missingCoverageElements
|
||||
.item(currentIndex)
|
||||
.classList.remove('highlighted');
|
||||
missingCoverageElements.item(index).classList.add('highlighted');
|
||||
}
|
||||
|
||||
function makeCurrent(index) {
|
||||
toggleClass(index);
|
||||
currentIndex = index;
|
||||
missingCoverageElements.item(index).scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'center'
|
||||
});
|
||||
}
|
||||
|
||||
function goToPrevious() {
|
||||
var nextIndex = 0;
|
||||
if (typeof currentIndex !== 'number' || currentIndex === 0) {
|
||||
nextIndex = missingCoverageElements.length - 1;
|
||||
} else if (missingCoverageElements.length > 1) {
|
||||
nextIndex = currentIndex - 1;
|
||||
}
|
||||
|
||||
makeCurrent(nextIndex);
|
||||
}
|
||||
|
||||
function goToNext() {
|
||||
var nextIndex = 0;
|
||||
|
||||
if (
|
||||
typeof currentIndex === 'number' &&
|
||||
currentIndex < missingCoverageElements.length - 1
|
||||
) {
|
||||
nextIndex = currentIndex + 1;
|
||||
}
|
||||
|
||||
makeCurrent(nextIndex);
|
||||
}
|
||||
|
||||
return function jump(event) {
|
||||
if (
|
||||
document.getElementById('fileSearch') === document.activeElement &&
|
||||
document.activeElement != null
|
||||
) {
|
||||
// if we're currently focused on the search input, we don't want to navigate
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event.which) {
|
||||
case 78: // n
|
||||
case 74: // j
|
||||
goToNext();
|
||||
break;
|
||||
case 66: // b
|
||||
case 75: // k
|
||||
case 80: // p
|
||||
goToPrevious();
|
||||
break;
|
||||
}
|
||||
};
|
||||
})();
|
||||
window.addEventListener('keydown', jumpToCode);
|
||||
BIN
backend/node_modules/kareem/coverage/lcov-report/favicon.png
generated
vendored
Normal file
BIN
backend/node_modules/kareem/coverage/lcov-report/favicon.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
116
backend/node_modules/kareem/coverage/lcov-report/index.html
generated
vendored
Normal file
116
backend/node_modules/kareem/coverage/lcov-report/index.html
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Code coverage report for All files</title>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="prettify.css" />
|
||||
<link rel="stylesheet" href="base.css" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<style type='text/css'>
|
||||
.coverage-summary .sorter {
|
||||
background-image: url(sort-arrow-sprite.png);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class='wrapper'>
|
||||
<div class='pad1'>
|
||||
<h1>All files</h1>
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">96.66% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>232/240</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">90.08% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>109/121</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>30/30</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">96.56% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>225/233</span>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<p class="quiet">
|
||||
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
||||
</p>
|
||||
<template id="filterTemplate">
|
||||
<div class="quiet">
|
||||
Filter:
|
||||
<input type="search" id="fileSearch">
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='status-line high'></div>
|
||||
<div class="pad1">
|
||||
<table class="coverage-summary">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
|
||||
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
|
||||
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
|
||||
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
|
||||
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
|
||||
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
|
||||
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td class="file high" data-value="index.js"><a href="index.js.html">index.js</a></td>
|
||||
<td data-value="96.66" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 96%"></div><div class="cover-empty" style="width: 4%"></div></div>
|
||||
</td>
|
||||
<td data-value="96.66" class="pct high">96.66%</td>
|
||||
<td data-value="240" class="abs high">232/240</td>
|
||||
<td data-value="90.08" class="pct high">90.08%</td>
|
||||
<td data-value="121" class="abs high">109/121</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="30" class="abs high">30/30</td>
|
||||
<td data-value="96.56" class="pct high">96.56%</td>
|
||||
<td data-value="233" class="abs high">225/233</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class='push'></div><!-- for sticky footer -->
|
||||
</div><!-- /wrapper -->
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2025-08-25T20:16:45.952Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
window.onload = function () {
|
||||
prettyPrint();
|
||||
};
|
||||
</script>
|
||||
<script src="sorter.js"></script>
|
||||
<script src="block-navigation.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
1603
backend/node_modules/kareem/coverage/lcov-report/index.js.html
generated
vendored
Normal file
1603
backend/node_modules/kareem/coverage/lcov-report/index.js.html
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
backend/node_modules/kareem/coverage/lcov-report/prettify.css
generated
vendored
Normal file
1
backend/node_modules/kareem/coverage/lcov-report/prettify.css
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
|
||||
2
backend/node_modules/kareem/coverage/lcov-report/prettify.js
generated
vendored
Normal file
2
backend/node_modules/kareem/coverage/lcov-report/prettify.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/node_modules/kareem/coverage/lcov-report/sort-arrow-sprite.png
generated
vendored
Normal file
BIN
backend/node_modules/kareem/coverage/lcov-report/sort-arrow-sprite.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 138 B |
196
backend/node_modules/kareem/coverage/lcov-report/sorter.js
generated
vendored
Normal file
196
backend/node_modules/kareem/coverage/lcov-report/sorter.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
/* eslint-disable */
|
||||
var addSorting = (function() {
|
||||
'use strict';
|
||||
var cols,
|
||||
currentSort = {
|
||||
index: 0,
|
||||
desc: false
|
||||
};
|
||||
|
||||
// returns the summary table element
|
||||
function getTable() {
|
||||
return document.querySelector('.coverage-summary');
|
||||
}
|
||||
// returns the thead element of the summary table
|
||||
function getTableHeader() {
|
||||
return getTable().querySelector('thead tr');
|
||||
}
|
||||
// returns the tbody element of the summary table
|
||||
function getTableBody() {
|
||||
return getTable().querySelector('tbody');
|
||||
}
|
||||
// returns the th element for nth column
|
||||
function getNthColumn(n) {
|
||||
return getTableHeader().querySelectorAll('th')[n];
|
||||
}
|
||||
|
||||
function onFilterInput() {
|
||||
const searchValue = document.getElementById('fileSearch').value;
|
||||
const rows = document.getElementsByTagName('tbody')[0].children;
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i];
|
||||
if (
|
||||
row.textContent
|
||||
.toLowerCase()
|
||||
.includes(searchValue.toLowerCase())
|
||||
) {
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loads the search box
|
||||
function addSearchBox() {
|
||||
var template = document.getElementById('filterTemplate');
|
||||
var templateClone = template.content.cloneNode(true);
|
||||
templateClone.getElementById('fileSearch').oninput = onFilterInput;
|
||||
template.parentElement.appendChild(templateClone);
|
||||
}
|
||||
|
||||
// loads all columns
|
||||
function loadColumns() {
|
||||
var colNodes = getTableHeader().querySelectorAll('th'),
|
||||
colNode,
|
||||
cols = [],
|
||||
col,
|
||||
i;
|
||||
|
||||
for (i = 0; i < colNodes.length; i += 1) {
|
||||
colNode = colNodes[i];
|
||||
col = {
|
||||
key: colNode.getAttribute('data-col'),
|
||||
sortable: !colNode.getAttribute('data-nosort'),
|
||||
type: colNode.getAttribute('data-type') || 'string'
|
||||
};
|
||||
cols.push(col);
|
||||
if (col.sortable) {
|
||||
col.defaultDescSort = col.type === 'number';
|
||||
colNode.innerHTML =
|
||||
colNode.innerHTML + '<span class="sorter"></span>';
|
||||
}
|
||||
}
|
||||
return cols;
|
||||
}
|
||||
// attaches a data attribute to every tr element with an object
|
||||
// of data values keyed by column name
|
||||
function loadRowData(tableRow) {
|
||||
var tableCols = tableRow.querySelectorAll('td'),
|
||||
colNode,
|
||||
col,
|
||||
data = {},
|
||||
i,
|
||||
val;
|
||||
for (i = 0; i < tableCols.length; i += 1) {
|
||||
colNode = tableCols[i];
|
||||
col = cols[i];
|
||||
val = colNode.getAttribute('data-value');
|
||||
if (col.type === 'number') {
|
||||
val = Number(val);
|
||||
}
|
||||
data[col.key] = val;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
// loads all row data
|
||||
function loadData() {
|
||||
var rows = getTableBody().querySelectorAll('tr'),
|
||||
i;
|
||||
|
||||
for (i = 0; i < rows.length; i += 1) {
|
||||
rows[i].data = loadRowData(rows[i]);
|
||||
}
|
||||
}
|
||||
// sorts the table using the data for the ith column
|
||||
function sortByIndex(index, desc) {
|
||||
var key = cols[index].key,
|
||||
sorter = function(a, b) {
|
||||
a = a.data[key];
|
||||
b = b.data[key];
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
},
|
||||
finalSorter = sorter,
|
||||
tableBody = document.querySelector('.coverage-summary tbody'),
|
||||
rowNodes = tableBody.querySelectorAll('tr'),
|
||||
rows = [],
|
||||
i;
|
||||
|
||||
if (desc) {
|
||||
finalSorter = function(a, b) {
|
||||
return -1 * sorter(a, b);
|
||||
};
|
||||
}
|
||||
|
||||
for (i = 0; i < rowNodes.length; i += 1) {
|
||||
rows.push(rowNodes[i]);
|
||||
tableBody.removeChild(rowNodes[i]);
|
||||
}
|
||||
|
||||
rows.sort(finalSorter);
|
||||
|
||||
for (i = 0; i < rows.length; i += 1) {
|
||||
tableBody.appendChild(rows[i]);
|
||||
}
|
||||
}
|
||||
// removes sort indicators for current column being sorted
|
||||
function removeSortIndicators() {
|
||||
var col = getNthColumn(currentSort.index),
|
||||
cls = col.className;
|
||||
|
||||
cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
|
||||
col.className = cls;
|
||||
}
|
||||
// adds sort indicators for current column being sorted
|
||||
function addSortIndicators() {
|
||||
getNthColumn(currentSort.index).className += currentSort.desc
|
||||
? ' sorted-desc'
|
||||
: ' sorted';
|
||||
}
|
||||
// adds event listeners for all sorter widgets
|
||||
function enableUI() {
|
||||
var i,
|
||||
el,
|
||||
ithSorter = function ithSorter(i) {
|
||||
var col = cols[i];
|
||||
|
||||
return function() {
|
||||
var desc = col.defaultDescSort;
|
||||
|
||||
if (currentSort.index === i) {
|
||||
desc = !currentSort.desc;
|
||||
}
|
||||
sortByIndex(i, desc);
|
||||
removeSortIndicators();
|
||||
currentSort.index = i;
|
||||
currentSort.desc = desc;
|
||||
addSortIndicators();
|
||||
};
|
||||
};
|
||||
for (i = 0; i < cols.length; i += 1) {
|
||||
if (cols[i].sortable) {
|
||||
// add the click event handler on the th so users
|
||||
// dont have to click on those tiny arrows
|
||||
el = getNthColumn(i).querySelector('.sorter').parentElement;
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener('click', ithSorter(i));
|
||||
} else {
|
||||
el.attachEvent('onclick', ithSorter(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// adds sorting functionality to the UI
|
||||
return function() {
|
||||
if (!getTable()) {
|
||||
return;
|
||||
}
|
||||
cols = loadColumns();
|
||||
loadData();
|
||||
addSearchBox();
|
||||
addSortIndicators();
|
||||
enableUI();
|
||||
};
|
||||
})();
|
||||
|
||||
window.addEventListener('load', addSorting);
|
||||
423
backend/node_modules/kareem/coverage/lcov.info
generated
vendored
Normal file
423
backend/node_modules/kareem/coverage/lcov.info
generated
vendored
Normal file
@@ -0,0 +1,423 @@
|
||||
TN:
|
||||
SF:index.js
|
||||
FN:6,Kareem
|
||||
FN:11,skipWrappedFunction
|
||||
FN:19,overwriteResult
|
||||
FN:34,execPre
|
||||
FN:49,(anonymous_4)
|
||||
FN:53,(anonymous_5)
|
||||
FN:103,(anonymous_6)
|
||||
FN:120,execPost
|
||||
FN:157,(anonymous_8)
|
||||
FN:161,nextCallback
|
||||
FN:234,(anonymous_10)
|
||||
FN:254,(anonymous_11)
|
||||
FN:256,syncWrapper
|
||||
FN:276,wrap
|
||||
FN:304,(anonymous_14)
|
||||
FN:310,(anonymous_15)
|
||||
FN:324,(anonymous_16)
|
||||
FN:343,(anonymous_17)
|
||||
FN:355,(anonymous_18)
|
||||
FN:361,kareemWrappedFunction
|
||||
FN:376,(anonymous_20)
|
||||
FN:409,(anonymous_21)
|
||||
FN:440,postError
|
||||
FN:453,(anonymous_23)
|
||||
FN:473,(anonymous_24)
|
||||
FN:481,(anonymous_25)
|
||||
FN:481,(anonymous_26)
|
||||
FN:488,(anonymous_27)
|
||||
FN:495,isPromiseLike
|
||||
FN:499,isErrorHandlingMiddleware
|
||||
FNF:30
|
||||
FNH:30
|
||||
FNDA:62,Kareem
|
||||
FNDA:6,skipWrappedFunction
|
||||
FNDA:12,overwriteResult
|
||||
FNDA:27,execPre
|
||||
FNDA:27,(anonymous_4)
|
||||
FNDA:27,(anonymous_5)
|
||||
FNDA:4,(anonymous_6)
|
||||
FNDA:27,execPost
|
||||
FNDA:41,(anonymous_8)
|
||||
FNDA:24,nextCallback
|
||||
FNDA:5,(anonymous_10)
|
||||
FNDA:2,(anonymous_11)
|
||||
FNDA:2,syncWrapper
|
||||
FNDA:17,wrap
|
||||
FNDA:2,(anonymous_14)
|
||||
FNDA:6,(anonymous_15)
|
||||
FNDA:6,(anonymous_16)
|
||||
FNDA:2,(anonymous_17)
|
||||
FNDA:1,(anonymous_18)
|
||||
FNDA:1,kareemWrappedFunction
|
||||
FNDA:51,(anonymous_20)
|
||||
FNDA:60,(anonymous_21)
|
||||
FNDA:1,postError
|
||||
FNDA:4,(anonymous_23)
|
||||
FNDA:1,(anonymous_24)
|
||||
FNDA:1,(anonymous_25)
|
||||
FNDA:1,(anonymous_26)
|
||||
FNDA:1,(anonymous_27)
|
||||
FNDA:61,isPromiseLike
|
||||
FNDA:41,isErrorHandlingMiddleware
|
||||
DA:7,62
|
||||
DA:8,62
|
||||
DA:11,1
|
||||
DA:12,6
|
||||
DA:13,3
|
||||
DA:16,3
|
||||
DA:19,1
|
||||
DA:20,12
|
||||
DA:21,6
|
||||
DA:24,6
|
||||
DA:34,1
|
||||
DA:35,27
|
||||
DA:36,27
|
||||
DA:37,27
|
||||
DA:38,27
|
||||
DA:40,27
|
||||
DA:41,3
|
||||
DA:44,24
|
||||
DA:45,24
|
||||
DA:46,33
|
||||
DA:47,27
|
||||
DA:48,27
|
||||
DA:49,27
|
||||
DA:50,27
|
||||
DA:51,27
|
||||
DA:53,27
|
||||
DA:54,27
|
||||
DA:55,27
|
||||
DA:56,19
|
||||
DA:57,0
|
||||
DA:59,19
|
||||
DA:62,27
|
||||
DA:63,27
|
||||
DA:64,27
|
||||
DA:65,0
|
||||
DA:67,27
|
||||
DA:70,9
|
||||
DA:71,3
|
||||
DA:72,3
|
||||
DA:74,6
|
||||
DA:77,6
|
||||
DA:78,6
|
||||
DA:80,2
|
||||
DA:81,0
|
||||
DA:82,0
|
||||
DA:84,2
|
||||
DA:89,16
|
||||
DA:91,16
|
||||
DA:92,3
|
||||
DA:103,1
|
||||
DA:104,4
|
||||
DA:105,4
|
||||
DA:107,4
|
||||
DA:108,4
|
||||
DA:120,1
|
||||
DA:121,27
|
||||
DA:122,27
|
||||
DA:124,27
|
||||
DA:125,27
|
||||
DA:126,6
|
||||
DA:129,27
|
||||
DA:130,1
|
||||
DA:131,0
|
||||
DA:133,1
|
||||
DA:136,26
|
||||
DA:137,41
|
||||
DA:138,41
|
||||
DA:139,41
|
||||
DA:140,41
|
||||
DA:141,41
|
||||
DA:142,40
|
||||
DA:143,40
|
||||
DA:144,40
|
||||
DA:148,41
|
||||
DA:149,1
|
||||
DA:150,1
|
||||
DA:151,1
|
||||
DA:157,41
|
||||
DA:158,41
|
||||
DA:159,41
|
||||
DA:161,41
|
||||
DA:162,24
|
||||
DA:163,12
|
||||
DA:165,12
|
||||
DA:169,41
|
||||
DA:170,14
|
||||
DA:171,8
|
||||
DA:172,8
|
||||
DA:173,8
|
||||
DA:174,1
|
||||
DA:175,7
|
||||
DA:177,6
|
||||
DA:180,5
|
||||
DA:181,0
|
||||
DA:182,0
|
||||
DA:184,5
|
||||
DA:187,6
|
||||
DA:190,27
|
||||
DA:192,1
|
||||
DA:194,26
|
||||
DA:195,26
|
||||
DA:196,26
|
||||
DA:197,26
|
||||
DA:198,3
|
||||
DA:199,23
|
||||
DA:201,18
|
||||
DA:204,7
|
||||
DA:205,2
|
||||
DA:206,2
|
||||
DA:208,5
|
||||
DA:209,5
|
||||
DA:212,19
|
||||
DA:213,2
|
||||
DA:214,2
|
||||
DA:220,26
|
||||
DA:221,11
|
||||
DA:224,15
|
||||
DA:234,1
|
||||
DA:235,5
|
||||
DA:236,5
|
||||
DA:238,5
|
||||
DA:239,6
|
||||
DA:240,6
|
||||
DA:241,2
|
||||
DA:245,5
|
||||
DA:254,1
|
||||
DA:255,2
|
||||
DA:256,2
|
||||
DA:257,2
|
||||
DA:259,2
|
||||
DA:261,2
|
||||
DA:263,2
|
||||
DA:276,1
|
||||
DA:278,17
|
||||
DA:279,17
|
||||
DA:280,17
|
||||
DA:282,7
|
||||
DA:283,2
|
||||
DA:284,2
|
||||
DA:286,5
|
||||
DA:290,12
|
||||
DA:291,10
|
||||
DA:294,9
|
||||
DA:296,7
|
||||
DA:304,1
|
||||
DA:305,2
|
||||
DA:307,2
|
||||
DA:308,2
|
||||
DA:309,4
|
||||
DA:310,6
|
||||
DA:313,4
|
||||
DA:314,1
|
||||
DA:315,1
|
||||
DA:318,3
|
||||
DA:321,2
|
||||
DA:322,2
|
||||
DA:323,4
|
||||
DA:324,6
|
||||
DA:327,4
|
||||
DA:328,1
|
||||
DA:329,1
|
||||
DA:332,3
|
||||
DA:335,2
|
||||
DA:343,1
|
||||
DA:344,2
|
||||
DA:355,1
|
||||
DA:356,1
|
||||
DA:357,1
|
||||
DA:359,0
|
||||
DA:361,1
|
||||
DA:362,1
|
||||
DA:363,1
|
||||
DA:376,1
|
||||
DA:377,51
|
||||
DA:378,43
|
||||
DA:379,43
|
||||
DA:380,8
|
||||
DA:381,1
|
||||
DA:384,51
|
||||
DA:385,51
|
||||
DA:387,51
|
||||
DA:388,1
|
||||
DA:391,50
|
||||
DA:392,2
|
||||
DA:394,48
|
||||
DA:397,50
|
||||
DA:409,1
|
||||
DA:410,60
|
||||
DA:412,60
|
||||
DA:413,52
|
||||
DA:414,52
|
||||
DA:415,52
|
||||
DA:418,60
|
||||
DA:419,1
|
||||
DA:422,59
|
||||
DA:423,2
|
||||
DA:425,57
|
||||
DA:427,59
|
||||
DA:428,59
|
||||
DA:440,1
|
||||
DA:441,1
|
||||
DA:442,1
|
||||
DA:443,1
|
||||
DA:444,1
|
||||
DA:446,1
|
||||
DA:453,1
|
||||
DA:454,4
|
||||
DA:456,4
|
||||
DA:457,6
|
||||
DA:458,6
|
||||
DA:460,4
|
||||
DA:461,5
|
||||
DA:464,4
|
||||
DA:473,1
|
||||
DA:474,1
|
||||
DA:475,1
|
||||
DA:477,1
|
||||
DA:478,1
|
||||
DA:479,1
|
||||
DA:481,1
|
||||
DA:482,1
|
||||
DA:483,1
|
||||
DA:485,1
|
||||
DA:486,1
|
||||
DA:487,1
|
||||
DA:488,1
|
||||
DA:489,1
|
||||
DA:492,1
|
||||
DA:496,61
|
||||
DA:500,41
|
||||
DA:501,2
|
||||
DA:503,39
|
||||
DA:506,1
|
||||
LF:233
|
||||
LH:225
|
||||
BRDA:12,0,0,3
|
||||
BRDA:12,0,1,3
|
||||
BRDA:20,1,0,6
|
||||
BRDA:20,1,1,6
|
||||
BRDA:35,2,0,27
|
||||
BRDA:35,2,1,3
|
||||
BRDA:40,3,0,3
|
||||
BRDA:40,3,1,24
|
||||
BRDA:46,4,0,27
|
||||
BRDA:46,4,1,6
|
||||
BRDA:53,5,0,9
|
||||
BRDA:53,5,1,18
|
||||
BRDA:56,6,0,0
|
||||
BRDA:56,6,1,19
|
||||
BRDA:56,7,0,19
|
||||
BRDA:56,7,1,19
|
||||
BRDA:64,8,0,0
|
||||
BRDA:64,8,1,27
|
||||
BRDA:70,9,0,3
|
||||
BRDA:70,9,1,6
|
||||
BRDA:80,10,0,0
|
||||
BRDA:80,10,1,2
|
||||
BRDA:91,11,0,3
|
||||
BRDA:91,11,1,13
|
||||
BRDA:104,12,0,4
|
||||
BRDA:104,12,1,1
|
||||
BRDA:108,13,0,4
|
||||
BRDA:108,13,1,2
|
||||
BRDA:121,14,0,27
|
||||
BRDA:121,14,1,1
|
||||
BRDA:125,15,0,6
|
||||
BRDA:125,15,1,21
|
||||
BRDA:125,16,0,27
|
||||
BRDA:125,16,1,10
|
||||
BRDA:129,17,0,1
|
||||
BRDA:129,17,1,26
|
||||
BRDA:130,18,0,0
|
||||
BRDA:130,18,1,1
|
||||
BRDA:142,19,0,40
|
||||
BRDA:142,19,1,0
|
||||
BRDA:142,20,0,40
|
||||
BRDA:142,20,1,37
|
||||
BRDA:148,21,0,1
|
||||
BRDA:148,21,1,40
|
||||
BRDA:162,22,0,12
|
||||
BRDA:162,22,1,12
|
||||
BRDA:169,23,0,14
|
||||
BRDA:169,23,1,27
|
||||
BRDA:170,24,0,8
|
||||
BRDA:170,24,1,6
|
||||
BRDA:173,25,0,1
|
||||
BRDA:173,25,1,7
|
||||
BRDA:175,26,0,6
|
||||
BRDA:175,26,1,1
|
||||
BRDA:180,27,0,0
|
||||
BRDA:180,27,1,5
|
||||
BRDA:190,28,0,1
|
||||
BRDA:190,28,1,26
|
||||
BRDA:197,29,0,3
|
||||
BRDA:197,29,1,23
|
||||
BRDA:199,30,0,18
|
||||
BRDA:199,30,1,5
|
||||
BRDA:204,31,0,2
|
||||
BRDA:204,31,1,5
|
||||
BRDA:212,32,0,2
|
||||
BRDA:212,32,1,17
|
||||
BRDA:220,33,0,11
|
||||
BRDA:220,33,1,15
|
||||
BRDA:235,34,0,5
|
||||
BRDA:235,34,1,1
|
||||
BRDA:239,35,0,6
|
||||
BRDA:239,35,1,2
|
||||
BRDA:240,36,0,2
|
||||
BRDA:240,36,1,4
|
||||
BRDA:282,37,0,2
|
||||
BRDA:282,37,1,5
|
||||
BRDA:290,38,0,10
|
||||
BRDA:290,38,1,2
|
||||
BRDA:313,39,0,1
|
||||
BRDA:313,39,1,3
|
||||
BRDA:327,40,0,1
|
||||
BRDA:327,40,1,3
|
||||
BRDA:344,41,0,2
|
||||
BRDA:344,41,1,1
|
||||
BRDA:357,42,0,0
|
||||
BRDA:357,42,1,1
|
||||
BRDA:362,43,0,1
|
||||
BRDA:362,43,1,0
|
||||
BRDA:377,44,0,43
|
||||
BRDA:377,44,1,8
|
||||
BRDA:380,45,0,1
|
||||
BRDA:380,45,1,7
|
||||
BRDA:384,46,0,51
|
||||
BRDA:384,46,1,35
|
||||
BRDA:387,47,0,1
|
||||
BRDA:387,47,1,50
|
||||
BRDA:391,48,0,2
|
||||
BRDA:391,48,1,48
|
||||
BRDA:410,49,0,60
|
||||
BRDA:410,49,1,40
|
||||
BRDA:412,50,0,52
|
||||
BRDA:412,50,1,8
|
||||
BRDA:418,51,0,1
|
||||
BRDA:418,51,1,59
|
||||
BRDA:422,52,0,2
|
||||
BRDA:422,52,1,57
|
||||
BRDA:441,53,0,1
|
||||
BRDA:441,53,1,0
|
||||
BRDA:474,54,0,1
|
||||
BRDA:474,54,1,0
|
||||
BRDA:475,55,0,1
|
||||
BRDA:475,55,1,0
|
||||
BRDA:478,56,0,1
|
||||
BRDA:478,56,1,0
|
||||
BRDA:486,57,0,1
|
||||
BRDA:486,57,1,1
|
||||
BRDA:496,58,0,61
|
||||
BRDA:496,58,1,5
|
||||
BRDA:496,58,2,5
|
||||
BRDA:500,59,0,2
|
||||
BRDA:500,59,1,39
|
||||
BRF:121
|
||||
BRH:109
|
||||
end_of_record
|
||||
31
backend/node_modules/kareem/index.d.ts
generated
vendored
Normal file
31
backend/node_modules/kareem/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
declare module "kareem" {
|
||||
export default class Kareem {
|
||||
static skipWrappedFunction(): SkipWrappedFunction;
|
||||
static overwriteMiddlewareResult(): OverwriteMiddlewareResult;
|
||||
static overwriteArguments(): OverwriteArguments;
|
||||
|
||||
pre(name: string | RegExp, fn: Function): this;
|
||||
pre(name: string | RegExp, options: Record<string, any>, fn: Function, error?: any, unshift?: boolean): this;
|
||||
post(name: string | RegExp, fn: Function): this;
|
||||
post(name: string | RegExp, options: Record<string, any>, fn: Function, unshift?: boolean): this;
|
||||
|
||||
clone(): Kareem;
|
||||
merge(other: Kareem, clone?: boolean): this;
|
||||
|
||||
createWrapper(name: string, fn: Function, context?: any, options?: Record<string, any>): Function;
|
||||
createWrapperSync(name: string, fn: Function): Function;
|
||||
hasHooks(name: string): boolean;
|
||||
filter(fn: Function): Kareem;
|
||||
|
||||
wrap(name: string, fn: Function, context: any, args: any[], options?: Record<string, any>): Function;
|
||||
|
||||
execPostSync(name: string, context: any, args: any[]): any;
|
||||
execPost(name: string, context: any, args: any[], options?: Record<string, any>, callback?: Function): void;
|
||||
execPreSync(name: string, context: any, args: any[]): any;
|
||||
execPre(name: string, context: any, args: any[], callback?: Function): void;
|
||||
}
|
||||
|
||||
class SkipWrappedFunction {}
|
||||
class OverwriteMiddlewareResult {}
|
||||
class OverwriteArguments {}
|
||||
}
|
||||
539
backend/node_modules/kareem/index.js
generated
vendored
Normal file
539
backend/node_modules/kareem/index.js
generated
vendored
Normal file
@@ -0,0 +1,539 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
*/
|
||||
function Kareem() {
|
||||
this._pres = new Map();
|
||||
this._posts = new Map();
|
||||
}
|
||||
|
||||
Kareem.skipWrappedFunction = function skipWrappedFunction() {
|
||||
if (!(this instanceof Kareem.skipWrappedFunction)) {
|
||||
return new Kareem.skipWrappedFunction(...arguments);
|
||||
}
|
||||
|
||||
this.args = [...arguments];
|
||||
};
|
||||
|
||||
Kareem.overwriteResult = function overwriteResult() {
|
||||
if (!(this instanceof Kareem.overwriteResult)) {
|
||||
return new Kareem.overwriteResult(...arguments);
|
||||
}
|
||||
|
||||
this.args = [...arguments];
|
||||
};
|
||||
|
||||
Kareem.overwriteArguments = function overwriteArguments() {
|
||||
if (!(this instanceof Kareem.overwriteArguments)) {
|
||||
return new Kareem.overwriteArguments(...arguments);
|
||||
}
|
||||
|
||||
this.args = [...arguments];
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute all "pre" hooks for "name"
|
||||
* @param {String} name The hook name to execute
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Array} args arguments passed to the pre hooks
|
||||
* @param {Object} [options] Optional options
|
||||
* @param {Function} [options.filter] Filter function to select which hooks to run
|
||||
* @returns {Array} The potentially modified arguments
|
||||
*/
|
||||
Kareem.prototype.execPre = async function execPre(name, context, args, options) {
|
||||
let pres = this._pres.get(name) || [];
|
||||
if (options?.filter) {
|
||||
pres = pres.filter(options.filter);
|
||||
}
|
||||
const numPres = pres.length;
|
||||
let $args = args;
|
||||
let skipWrappedFunction = null;
|
||||
|
||||
if (!numPres) {
|
||||
return $args;
|
||||
}
|
||||
|
||||
for (const pre of pres) {
|
||||
const args = [];
|
||||
const _args = [null].concat($args);
|
||||
for (let i = 1; i < _args.length; ++i) {
|
||||
if (i === _args.length - 1 && typeof _args[i] === 'function') {
|
||||
continue; // skip callbacks to avoid accidentally calling the callback from a hook
|
||||
}
|
||||
args.push(_args[i]);
|
||||
}
|
||||
|
||||
try {
|
||||
const maybePromiseLike = pre.fn.apply(context, args);
|
||||
if (isPromiseLike(maybePromiseLike)) {
|
||||
const result = await maybePromiseLike;
|
||||
if (result instanceof Kareem.overwriteArguments) {
|
||||
$args = result.args;
|
||||
}
|
||||
} else if (maybePromiseLike instanceof Kareem.overwriteArguments) {
|
||||
$args = maybePromiseLike.args;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Kareem.skipWrappedFunction) {
|
||||
skipWrappedFunction = error;
|
||||
continue;
|
||||
}
|
||||
if (error instanceof Kareem.overwriteArguments) {
|
||||
$args = error.args;
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipWrappedFunction) {
|
||||
throw skipWrappedFunction;
|
||||
}
|
||||
|
||||
return $args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute all "pre" hooks for "name" synchronously
|
||||
* @param {String} name The hook name to execute
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Array} [args] Apply custom arguments to the hook
|
||||
* @param {Object} [options] Optional options
|
||||
* @param {Function} [options.filter] Filter function to select which hooks to run
|
||||
* @returns {Array} The potentially modified arguments
|
||||
*/
|
||||
Kareem.prototype.execPreSync = function(name, context, args, options) {
|
||||
let pres = this._pres.get(name) || [];
|
||||
if (options?.filter) {
|
||||
pres = pres.filter(options.filter);
|
||||
}
|
||||
const numPres = pres.length;
|
||||
let $args = args || [];
|
||||
|
||||
for (let i = 0; i < numPres; ++i) {
|
||||
const result = pres[i].fn.apply(context, $args);
|
||||
if (result instanceof Kareem.overwriteArguments) {
|
||||
$args = result.args;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute all "post" hooks for "name"
|
||||
* @param {String} name The hook name to execute
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Array} args Apply custom arguments to the hook
|
||||
* @param {Object} [options] Optional options
|
||||
* @param {Error} [options.error] Error to pass to error-handling middleware
|
||||
* @param {Function} [options.filter] Filter function to select which hooks to run
|
||||
* @returns {void}
|
||||
*/
|
||||
Kareem.prototype.execPost = async function execPost(name, context, args, options) {
|
||||
let posts = this._posts.get(name) || [];
|
||||
if (options?.filter) {
|
||||
posts = posts.filter(options.filter);
|
||||
}
|
||||
const numPosts = posts.length;
|
||||
|
||||
let firstError = null;
|
||||
if (options && options.error) {
|
||||
firstError = options.error;
|
||||
}
|
||||
|
||||
if (!numPosts) {
|
||||
if (firstError != null) {
|
||||
throw firstError;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
for (const currentPost of posts) {
|
||||
const post = currentPost.fn;
|
||||
let numArgs = 0;
|
||||
const newArgs = [];
|
||||
const argLength = args.length;
|
||||
for (let i = 0; i < argLength; ++i) {
|
||||
if (!args[i] || !args[i]._kareemIgnore) {
|
||||
numArgs += 1;
|
||||
newArgs.push(args[i]);
|
||||
}
|
||||
}
|
||||
// If numCallbackParams set, fill in the rest with null to enforce consistent number of args
|
||||
if (options?.numCallbackParams != null) {
|
||||
numArgs = options.numCallbackParams;
|
||||
for (let i = newArgs.length; i < numArgs; ++i) {
|
||||
newArgs.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
let resolve;
|
||||
let reject;
|
||||
const cbPromise = new Promise((_resolve, _reject) => {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
});
|
||||
newArgs.push(function nextCallback(err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
if (firstError) {
|
||||
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
||||
try {
|
||||
const res = post.apply(context, [firstError].concat(newArgs));
|
||||
if (isPromiseLike(res)) {
|
||||
await res;
|
||||
} else if (post.length === numArgs + 2) {
|
||||
// `numArgs + 2` because we added the error and the callback
|
||||
await cbPromise;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Kareem.overwriteResult) {
|
||||
args = error.args;
|
||||
continue;
|
||||
}
|
||||
firstError = error;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (isErrorHandlingMiddleware(currentPost, numArgs)) {
|
||||
// Skip error handlers if no error
|
||||
continue;
|
||||
} else {
|
||||
let res = null;
|
||||
try {
|
||||
res = post.apply(context, newArgs);
|
||||
if (isPromiseLike(res)) {
|
||||
res = await res;
|
||||
} else if (post.length === numArgs + 1) {
|
||||
// If post function takes a callback, wait for the post function to call the callback
|
||||
res = await cbPromise;
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof Kareem.overwriteResult) {
|
||||
args = error.args;
|
||||
continue;
|
||||
}
|
||||
firstError = error;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res instanceof Kareem.overwriteResult) {
|
||||
args = res.args;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstError != null) {
|
||||
throw firstError;
|
||||
}
|
||||
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute all "post" hooks for "name" synchronously
|
||||
* @param {String} name The hook name to execute
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Array} args Apply custom arguments to the hook
|
||||
* @param {Object} [options] Optional options
|
||||
* @param {Function} [options.filter] Filter function to select which hooks to run
|
||||
* @returns {Array} The used arguments
|
||||
*/
|
||||
Kareem.prototype.execPostSync = function(name, context, args, options) {
|
||||
let posts = this._posts.get(name) || [];
|
||||
if (options?.filter) {
|
||||
posts = posts.filter(options.filter);
|
||||
}
|
||||
const numPosts = posts.length;
|
||||
|
||||
for (let i = 0; i < numPosts; ++i) {
|
||||
const res = posts[i].fn.apply(context, args || []);
|
||||
if (res instanceof Kareem.overwriteResult) {
|
||||
args = res.args;
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a synchronous wrapper for "fn"
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Function} fn The function to wrap
|
||||
* @param {*} context Overwrite the "this" for the hook. If null/undefined, uses the calling context.
|
||||
* @param {Object} [options] Options for the wrapper
|
||||
* @param {Function} [options.getOptions] Function that receives the wrapper arguments and returns options for execPreSync/execPostSync. Can return `{ filter }` for both, or `{ pre: { filter }, post: { filter } }` for separate options.
|
||||
* @returns {Function} The wrapped function
|
||||
*/
|
||||
Kareem.prototype.createWrapperSync = function(name, fn, context, options) {
|
||||
const _this = this;
|
||||
const getOptions = options?.getOptions;
|
||||
return function syncWrapper() {
|
||||
const _context = context || this;
|
||||
const args = Array.from(arguments);
|
||||
const execOptions = typeof getOptions === 'function' ? getOptions(args) : {};
|
||||
const preOptions = execOptions.pre ?? execOptions;
|
||||
const postOptions = execOptions.post ?? execOptions;
|
||||
|
||||
const modifiedArgs = _this.execPreSync(name, _context, args, preOptions);
|
||||
|
||||
const toReturn = fn.apply(_context, modifiedArgs);
|
||||
|
||||
const result = _this.execPostSync(name, _context, [toReturn], postOptions);
|
||||
|
||||
return result[0];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes pre hooks, followed by the wrapped function, followed by post hooks.
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Function} fn The function for the hook
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Array} args Apply custom arguments to the hook
|
||||
* @param {Object} options Additional options for the hook
|
||||
* @returns {void}
|
||||
*/
|
||||
Kareem.prototype.wrap = async function wrap(name, fn, context, args, options) {
|
||||
let ret;
|
||||
let skipWrappedFunction = false;
|
||||
let modifiedArgs = args;
|
||||
try {
|
||||
modifiedArgs = await this.execPre(name, context, args);
|
||||
} catch (error) {
|
||||
if (error instanceof Kareem.skipWrappedFunction) {
|
||||
ret = error.args;
|
||||
skipWrappedFunction = true;
|
||||
} else {
|
||||
await this.execPost(name, context, args, { ...options, error });
|
||||
}
|
||||
}
|
||||
|
||||
if (!skipWrappedFunction) {
|
||||
ret = await fn.apply(context, modifiedArgs);
|
||||
}
|
||||
|
||||
ret = await this.execPost(name, context, [ret], options);
|
||||
|
||||
return ret[0];
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter current instance for something specific and return the filtered clone
|
||||
* @param {Function} fn The filter function
|
||||
* @returns {Kareem} The cloned and filtered instance
|
||||
*/
|
||||
Kareem.prototype.filter = function(fn) {
|
||||
const clone = this.clone();
|
||||
|
||||
const pres = Array.from(clone._pres.keys());
|
||||
for (const name of pres) {
|
||||
const hooks = this._pres.get(name).
|
||||
map(h => Object.assign({}, h, { name: name })).
|
||||
filter(fn);
|
||||
|
||||
if (hooks.length === 0) {
|
||||
clone._pres.delete(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
clone._pres.set(name, hooks);
|
||||
}
|
||||
|
||||
const posts = Array.from(clone._posts.keys());
|
||||
for (const name of posts) {
|
||||
const hooks = this._posts.get(name).
|
||||
map(h => Object.assign({}, h, { name: name })).
|
||||
filter(fn);
|
||||
|
||||
if (hooks.length === 0) {
|
||||
clone._posts.delete(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
clone._posts.set(name, hooks);
|
||||
}
|
||||
|
||||
return clone;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check for a "name" to exist either in pre or post hooks
|
||||
* @param {String} name The name of the hook
|
||||
* @returns {Boolean} "true" if found, "false" otherwise
|
||||
*/
|
||||
Kareem.prototype.hasHooks = function(name) {
|
||||
return this._pres.has(name) || this._posts.has(name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a Wrapper for "fn" on "name" and return the wrapped function
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Function} fn The function to wrap
|
||||
* @param {*} context Overwrite the "this" for the hook
|
||||
* @param {Object} [options]
|
||||
* @returns {Function} The wrapped function
|
||||
*/
|
||||
Kareem.prototype.createWrapper = function(name, fn, context, options) {
|
||||
const _this = this;
|
||||
if (!this.hasHooks(name)) {
|
||||
// Fast path: if there's no hooks for this function, just return the function
|
||||
return fn;
|
||||
}
|
||||
return function kareemWrappedFunction() {
|
||||
const _context = context || this;
|
||||
return _this.wrap(name, fn, _context, Array.from(arguments), options);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a new hook for "pre"
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Object} [options]
|
||||
* @param {Function} fn The function to register for "name"
|
||||
* @param {never} error Unused
|
||||
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
||||
* @returns {Kareem}
|
||||
*/
|
||||
Kareem.prototype.pre = function(name, options, fn, error, unshift) {
|
||||
if (typeof options === 'function') {
|
||||
fn = options;
|
||||
options = {};
|
||||
} else if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
const pres = this._pres.get(name) || [];
|
||||
this._pres.set(name, pres);
|
||||
|
||||
if (typeof fn !== 'function') {
|
||||
throw new Error('pre() requires a function, got "' + typeof fn + '"');
|
||||
}
|
||||
|
||||
if (unshift) {
|
||||
pres.unshift(Object.assign({}, options, { fn: fn }));
|
||||
} else {
|
||||
pres.push(Object.assign({}, options, { fn: fn }));
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a new hook for "post"
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Object} [options]
|
||||
* @param {Boolean} [options.errorHandler] Whether this is an error handler
|
||||
* @param {Function} fn The function to register for "name"
|
||||
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
||||
* @returns {Kareem}
|
||||
*/
|
||||
Kareem.prototype.post = function(name, options, fn, unshift) {
|
||||
const posts = this._posts.get(name) || [];
|
||||
|
||||
if (typeof options === 'function') {
|
||||
unshift = !!fn;
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (typeof fn !== 'function') {
|
||||
throw new Error('post() requires a function, got "' + typeof fn + '"');
|
||||
}
|
||||
|
||||
if (unshift) {
|
||||
posts.unshift(Object.assign({}, options, { fn: fn }));
|
||||
} else {
|
||||
posts.push(Object.assign({}, options, { fn: fn }));
|
||||
}
|
||||
this._posts.set(name, posts);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a new error handler for "name"
|
||||
* @param {String} name The name of the hook
|
||||
* @param {Object} [options]
|
||||
* @param {Function} fn The function to register for "name"
|
||||
* @param {Boolean} [unshift] Wheter to "push" or to "unshift" the new hook
|
||||
* @returns {Kareem}
|
||||
*/
|
||||
|
||||
Kareem.prototype.postError = function postError(name, options, fn, unshift) {
|
||||
if (typeof options === 'function') {
|
||||
unshift = !!fn;
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
return this.post(name, { ...options, errorHandler: true }, fn, unshift);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone the current instance
|
||||
* @returns {Kareem} The cloned instance
|
||||
*/
|
||||
Kareem.prototype.clone = function() {
|
||||
const n = new Kareem();
|
||||
|
||||
for (const key of this._pres.keys()) {
|
||||
const clone = this._pres.get(key).slice();
|
||||
n._pres.set(key, clone);
|
||||
}
|
||||
for (const key of this._posts.keys()) {
|
||||
n._posts.set(key, this._posts.get(key).slice());
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge "other" into self or "clone"
|
||||
* @param {Kareem} other The instance to merge with
|
||||
* @param {Kareem} [clone] The instance to merge onto (if not defined, using "this")
|
||||
* @returns {Kareem} The merged instance
|
||||
*/
|
||||
Kareem.prototype.merge = function(other, clone) {
|
||||
clone = arguments.length === 1 ? true : clone;
|
||||
const ret = clone ? this.clone() : this;
|
||||
|
||||
for (const key of other._pres.keys()) {
|
||||
const sourcePres = ret._pres.get(key) || [];
|
||||
const deduplicated = other._pres.get(key).
|
||||
// Deduplicate based on `fn`
|
||||
filter(p => sourcePres.map(_p => _p.fn).indexOf(p.fn) === -1);
|
||||
const combined = sourcePres.concat(deduplicated);
|
||||
ret._pres.set(key, combined);
|
||||
}
|
||||
for (const key of other._posts.keys()) {
|
||||
const sourcePosts = ret._posts.get(key) || [];
|
||||
const deduplicated = other._posts.get(key).
|
||||
filter(p => sourcePosts.indexOf(p) === -1);
|
||||
ret._posts.set(key, sourcePosts.concat(deduplicated));
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
function isPromiseLike(v) {
|
||||
return (typeof v === 'object' && v !== null && typeof v.then === 'function');
|
||||
}
|
||||
|
||||
function isErrorHandlingMiddleware(post, numArgs) {
|
||||
if (post.errorHandler) {
|
||||
return true;
|
||||
}
|
||||
return post.fn.length === numArgs + 2;
|
||||
}
|
||||
|
||||
module.exports = Kareem;
|
||||
28
backend/node_modules/kareem/package.json
generated
vendored
Normal file
28
backend/node_modules/kareem/package.json
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "kareem",
|
||||
"version": "3.2.0",
|
||||
"description": "Next-generation take on pre/post function hooks",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "mocha ./test/*",
|
||||
"test-coverage": "nyc --reporter lcov mocha ./test/*",
|
||||
"docs": "node ./docs.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/mongoosejs/kareem.git"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acquit": "1.x",
|
||||
"acquit-ignore": "0.2.x",
|
||||
"eslint": "8.20.0",
|
||||
"mocha": "11.x",
|
||||
"nyc": "15.1.0"
|
||||
},
|
||||
"author": "Valeri Karpov <val@karpov.io>",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
}
|
||||
22
backend/node_modules/mongoose/LICENSE.md
generated
vendored
Normal file
22
backend/node_modules/mongoose/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (c) 2010-2013 LearnBoost <dev@learnboost.com>
|
||||
Copyright (c) 2013-2021 Automattic
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
395
backend/node_modules/mongoose/README.md
generated
vendored
Normal file
395
backend/node_modules/mongoose/README.md
generated
vendored
Normal file
@@ -0,0 +1,395 @@
|
||||
# Mongoose
|
||||
|
||||
Mongoose is a [MongoDB](https://www.mongodb.org/) object modeling tool designed to work in an asynchronous environment. Mongoose supports [Node.js](https://nodejs.org/en/) and [Deno](https://deno.land/) (alpha).
|
||||
|
||||
[](https://github.com/Automattic/mongoose)
|
||||
[](http://badge.fury.io/js/mongoose)
|
||||
[](https://deno.land/x/mongoose)
|
||||
[](https://deno.land/x/mongoose)
|
||||
|
||||
[](https://www.npmjs.com/package/mongoose)
|
||||
|
||||
## Documentation
|
||||
|
||||
The official documentation website is [mongoosejs.com](https://mongoosejs.com/).
|
||||
|
||||
Mongoose 9.0.0 was released on November 21, 2025. You can find more details on [backwards breaking changes in 9.0.0 on our docs site](https://mongoosejs.com/docs/migrating_to_9.html).
|
||||
|
||||
## Support
|
||||
|
||||
* [Stack Overflow](http://stackoverflow.com/questions/tagged/mongoose)
|
||||
* [Bug Reports](https://github.com/Automattic/mongoose/issues/)
|
||||
* [Mongoose Slack Channel](http://slack.mongoosejs.io/)
|
||||
* [Help Forum](http://groups.google.com/group/mongoose-orm)
|
||||
* [MongoDB Support](https://www.mongodb.com/docs/manual/support/)
|
||||
|
||||
## Plugins
|
||||
|
||||
Check out the [plugins search site](https://plugins.mongoosejs.io/) to see hundreds of related modules from the community. Next, learn how to write your own plugin from the [docs](https://mongoosejs.com/docs/plugins.html) or [this blog post](http://thecodebarbarian.com/2015/03/06/guide-to-mongoose-plugins).
|
||||
|
||||
## Contributors
|
||||
|
||||
Pull requests are always welcome! Please base pull requests against the `master`
|
||||
branch and follow the [contributing guide](https://github.com/Automattic/mongoose/blob/master/CONTRIBUTING.md).
|
||||
|
||||
If your pull requests makes documentation changes, please do **not**
|
||||
modify any `.html` files. The `.html` files are compiled code, so please make
|
||||
your changes in `docs/*.pug`, `lib/*.js`, or `test/docs/*.js`.
|
||||
|
||||
View all 400+ [contributors](https://github.com/Automattic/mongoose/graphs/contributors).
|
||||
|
||||
## Installation
|
||||
|
||||
First install [Node.js](https://nodejs.org/) and [MongoDB](https://www.mongodb.org/downloads), then install the `mongoose` package using your preferred package manager:
|
||||
|
||||
### Using npm
|
||||
|
||||
```sh
|
||||
npm install mongoose
|
||||
```
|
||||
|
||||
### Using pnpm
|
||||
|
||||
```sh
|
||||
pnpm add mongoose
|
||||
```
|
||||
|
||||
### Using Yarn
|
||||
|
||||
```sh
|
||||
yarn add mongoose
|
||||
```
|
||||
|
||||
### Using Bun
|
||||
|
||||
```sh
|
||||
bun add mongoose
|
||||
```
|
||||
|
||||
Mongoose 6.8.0 also includes alpha support for [Deno](https://deno.land/).
|
||||
|
||||
## Importing
|
||||
|
||||
```javascript
|
||||
// Using Node.js `require()`
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
// Using ES6 imports
|
||||
import mongoose from 'mongoose';
|
||||
```
|
||||
|
||||
Or, using [Deno's `createRequire()` for CommonJS support](https://deno.land/std@0.113.0/node/README.md?source=#commonjs-modules-loading) as follows.
|
||||
|
||||
```javascript
|
||||
import { createRequire } from 'https://deno.land/std@0.177.0/node/module.ts';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
mongoose.connect('mongodb://127.0.0.1:27017/test')
|
||||
.then(() => console.log('Connected!'));
|
||||
```
|
||||
|
||||
You can then run the above script using the following.
|
||||
|
||||
```sh
|
||||
deno run --allow-net --allow-read --allow-sys --allow-env mongoose-test.js
|
||||
```
|
||||
|
||||
## Mongoose for Enterprise
|
||||
|
||||
Available as part of the Tidelift Subscription
|
||||
|
||||
The maintainers of mongoose and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-mongoose?utm_source=npm-mongoose&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
||||
|
||||
## Overview
|
||||
|
||||
### Connecting to MongoDB
|
||||
|
||||
First, we need to define a connection. If your app uses only one database, you should use `mongoose.connect`. If you need to create additional connections, use `mongoose.createConnection`.
|
||||
|
||||
Both `connect` and `createConnection` take a `mongodb://` URI, or the parameters `host, database, port, options`.
|
||||
|
||||
```js
|
||||
await mongoose.connect('mongodb://127.0.0.1/my_database');
|
||||
```
|
||||
|
||||
Once connected, the `open` event is fired on the `Connection` instance. If you're using `mongoose.connect`, the `Connection` is `mongoose.connection`. Otherwise, `mongoose.createConnection` return value is a `Connection`.
|
||||
|
||||
**Note:** *If the local connection fails then try using 127.0.0.1 instead of localhost. Sometimes issues may arise when the local hostname has been changed.*
|
||||
|
||||
**Important!** Mongoose buffers all the commands until it's connected to the database. This means that you don't have to wait until it connects to MongoDB in order to define models, run queries, etc.
|
||||
|
||||
### Defining a Model
|
||||
|
||||
Models are defined through the `Schema` interface.
|
||||
|
||||
```js
|
||||
const Schema = mongoose.Schema;
|
||||
const ObjectId = Schema.ObjectId;
|
||||
|
||||
const BlogPost = new Schema({
|
||||
author: ObjectId,
|
||||
title: String,
|
||||
body: String,
|
||||
date: Date
|
||||
});
|
||||
```
|
||||
|
||||
Aside from defining the structure of your documents and the types of data you're storing, a Schema handles the definition of:
|
||||
|
||||
* [Validators](https://mongoosejs.com/docs/validation.html) (async and sync)
|
||||
* [Defaults](https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-default)
|
||||
* [Getters](https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-get)
|
||||
* [Setters](https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-set)
|
||||
* [Indexes](https://mongoosejs.com/docs/guide.html#indexes)
|
||||
* [Middleware](https://mongoosejs.com/docs/middleware.html)
|
||||
* [Methods](https://mongoosejs.com/docs/guide.html#methods) definition
|
||||
* [Statics](https://mongoosejs.com/docs/guide.html#statics) definition
|
||||
* [Plugins](https://mongoosejs.com/docs/plugins.html)
|
||||
* [pseudo-JOINs](https://mongoosejs.com/docs/populate.html)
|
||||
|
||||
The following example shows some of these features:
|
||||
|
||||
```js
|
||||
const Comment = new Schema({
|
||||
name: { type: String, default: 'hahaha' },
|
||||
age: { type: Number, min: 18, index: true },
|
||||
bio: { type: String, match: /[a-z]/ },
|
||||
date: { type: Date, default: Date.now },
|
||||
buff: Buffer
|
||||
});
|
||||
|
||||
// a setter
|
||||
Comment.path('name').set(function(v) {
|
||||
return capitalize(v);
|
||||
});
|
||||
|
||||
// middleware
|
||||
Comment.pre('save', function(next) {
|
||||
notify(this.get('email'));
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
Take a look at the example in [`examples/schema/schema.js`](https://github.com/Automattic/mongoose/blob/master/examples/schema/schema.js) for an end-to-end example of a typical setup.
|
||||
|
||||
### Accessing a Model
|
||||
|
||||
Once we define a model through `mongoose.model('ModelName', mySchema)`, we can access it through the same function
|
||||
|
||||
```js
|
||||
const MyModel = mongoose.model('ModelName');
|
||||
```
|
||||
|
||||
Or just do it all at once
|
||||
|
||||
```js
|
||||
const MyModel = mongoose.model('ModelName', mySchema);
|
||||
```
|
||||
|
||||
The first argument is the *singular* name of the collection your model is for. **Mongoose automatically looks for the *plural* version of your model name.** For example, if you use
|
||||
|
||||
```js
|
||||
const MyModel = mongoose.model('Ticket', mySchema);
|
||||
```
|
||||
|
||||
Then `MyModel` will use the **tickets** collection, not the **ticket** collection. For more details read the [model docs](https://mongoosejs.com/docs/api/mongoose.html#mongoose_Mongoose-model).
|
||||
|
||||
Once we have our model, we can then instantiate it, and save it:
|
||||
|
||||
```js
|
||||
const instance = new MyModel();
|
||||
instance.my.key = 'hello';
|
||||
await instance.save();
|
||||
```
|
||||
|
||||
Or we can find documents from the same collection
|
||||
|
||||
```js
|
||||
await MyModel.find({});
|
||||
```
|
||||
|
||||
You can also `findOne`, `findById`, `update`, etc.
|
||||
|
||||
```js
|
||||
const instance = await MyModel.findOne({ /* ... */ });
|
||||
console.log(instance.my.key); // 'hello'
|
||||
```
|
||||
|
||||
For more details check out [the docs](https://mongoosejs.com/docs/queries.html).
|
||||
|
||||
**Important!** If you opened a separate connection using `mongoose.createConnection()` but attempt to access the model through `mongoose.model('ModelName')` it will not work as expected since it is not hooked up to an active db connection. In this case access your model through the connection you created:
|
||||
|
||||
```js
|
||||
const conn = mongoose.createConnection('your connection string');
|
||||
const MyModel = conn.model('ModelName', schema);
|
||||
const m = new MyModel();
|
||||
await m.save(); // works
|
||||
```
|
||||
|
||||
vs
|
||||
|
||||
```js
|
||||
const conn = mongoose.createConnection('your connection string');
|
||||
const MyModel = mongoose.model('ModelName', schema);
|
||||
const m = new MyModel();
|
||||
await m.save(); // does not work b/c the default connection object was never connected
|
||||
```
|
||||
|
||||
### Embedded Documents
|
||||
|
||||
In the first example snippet, we defined a key in the Schema that looks like:
|
||||
|
||||
```txt
|
||||
comments: [Comment]
|
||||
```
|
||||
|
||||
Where `Comment` is a `Schema` we created. This means that creating embedded documents is as simple as:
|
||||
|
||||
```js
|
||||
// retrieve my model
|
||||
const BlogPost = mongoose.model('BlogPost');
|
||||
|
||||
// create a blog post
|
||||
const post = new BlogPost();
|
||||
|
||||
// create a comment
|
||||
post.comments.push({ title: 'My comment' });
|
||||
|
||||
await post.save();
|
||||
```
|
||||
|
||||
The same goes for removing them:
|
||||
|
||||
```js
|
||||
const post = await BlogPost.findById(myId);
|
||||
post.comments[0].deleteOne();
|
||||
await post.save();
|
||||
```
|
||||
|
||||
Embedded documents enjoy all the same features as your models. Defaults, validators, middleware.
|
||||
|
||||
### Middleware
|
||||
|
||||
See the [docs](https://mongoosejs.com/docs/middleware.html) page.
|
||||
|
||||
#### Intercepting and mutating method arguments
|
||||
|
||||
You can intercept method arguments via middleware.
|
||||
|
||||
For example, this would allow you to broadcast changes about your Documents every time someone `set`s a path in your Document to a new value:
|
||||
|
||||
```js
|
||||
schema.pre('set', function(next, path, val, typel) {
|
||||
// `this` is the current Document
|
||||
this.emit('set', path, val);
|
||||
|
||||
// Pass control to the next pre
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
Moreover, you can mutate the incoming `method` arguments so that subsequent middleware see different values for those arguments. To do so, just pass the new values to `next`:
|
||||
|
||||
```js
|
||||
schema.pre(method, function firstPre(next, methodArg1, methodArg2) {
|
||||
// Mutate methodArg1
|
||||
next('altered-' + methodArg1.toString(), methodArg2);
|
||||
});
|
||||
|
||||
// pre declaration is chainable
|
||||
schema.pre(method, function secondPre(next, methodArg1, methodArg2) {
|
||||
console.log(methodArg1);
|
||||
// => 'altered-originalValOfMethodArg1'
|
||||
|
||||
console.log(methodArg2);
|
||||
// => 'originalValOfMethodArg2'
|
||||
|
||||
// Passing no arguments to `next` automatically passes along the current argument values
|
||||
// i.e., the following `next()` is equivalent to `next(methodArg1, methodArg2)`
|
||||
// and also equivalent to, with the example method arg
|
||||
// values, `next('altered-originalValOfMethodArg1', 'originalValOfMethodArg2')`
|
||||
next();
|
||||
});
|
||||
```
|
||||
|
||||
#### Schema gotcha
|
||||
|
||||
`type`, when used in a schema has special meaning within Mongoose. If your schema requires using `type` as a nested property you must use object notation:
|
||||
|
||||
```js
|
||||
new Schema({
|
||||
broken: { type: Boolean },
|
||||
asset: {
|
||||
name: String,
|
||||
type: String // uh oh, it broke. asset will be interpreted as String
|
||||
}
|
||||
});
|
||||
|
||||
new Schema({
|
||||
works: { type: Boolean },
|
||||
asset: {
|
||||
name: String,
|
||||
type: { type: String } // works. asset is an object with a type property
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Driver Access
|
||||
|
||||
Mongoose is built on top of the [official MongoDB Node.js driver](https://github.com/mongodb/node-mongodb-native). Each mongoose model keeps a reference to a [native MongoDB driver collection](http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html). The collection object can be accessed using `YourModel.collection`. However, using the collection object directly bypasses all mongoose features, including hooks, validation, etc. The one
|
||||
notable exception that `YourModel.collection` still buffers
|
||||
commands. As such, `YourModel.collection.find()` will **not**
|
||||
return a cursor.
|
||||
|
||||
## API Docs
|
||||
|
||||
[Mongoose API documentation](https://mongoosejs.com/docs/api/mongoose.html), generated using [dox](https://github.com/tj/dox)
|
||||
and [acquit](https://github.com/vkarpov15/acquit).
|
||||
|
||||
## Related Projects
|
||||
|
||||
### MongoDB Runners
|
||||
|
||||
* [run-rs](https://www.npmjs.com/package/run-rs)
|
||||
* [mongodb-memory-server](https://www.npmjs.com/package/mongodb-memory-server)
|
||||
* [mongodb-topology-manager](https://www.npmjs.com/package/mongodb-topology-manager)
|
||||
|
||||
### Unofficial CLIs
|
||||
|
||||
* [mongoosejs-cli](https://www.npmjs.com/package/mongoosejs-cli)
|
||||
|
||||
### Data Seeding
|
||||
|
||||
* [dookie](https://www.npmjs.com/package/dookie)
|
||||
* [seedgoose](https://www.npmjs.com/package/seedgoose)
|
||||
* [mongoose-data-seed](https://www.npmjs.com/package/mongoose-data-seed)
|
||||
|
||||
### Express Session Stores
|
||||
|
||||
* [connect-mongodb-session](https://www.npmjs.com/package/connect-mongodb-session)
|
||||
* [connect-mongo](https://www.npmjs.com/package/connect-mongo)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2010 LearnBoost <dev@learnboost.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
backend/node_modules/mongoose/SECURITY.md
generated
vendored
Normal file
1
backend/node_modules/mongoose/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Please follow the instructions on [Tidelift's security page](https://tidelift.com/docs/security) to report a security issue.
|
||||
198
backend/node_modules/mongoose/eslint.config.mjs
generated
vendored
Normal file
198
backend/node_modules/mongoose/eslint.config.mjs
generated
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
import { defineConfig, globalIgnores } from 'eslint/config';
|
||||
import mochaNoOnly from 'eslint-plugin-mocha-no-only';
|
||||
import globals from 'globals';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import js from '@eslint/js';
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores([
|
||||
'**/tools',
|
||||
'**/dist',
|
||||
'test/files/*',
|
||||
'**/benchmarks',
|
||||
'**/*.min.js',
|
||||
'**/docs/js/native.js',
|
||||
'!**/.*',
|
||||
'**/node_modules',
|
||||
'**/.git',
|
||||
'**/data'
|
||||
]),
|
||||
js.configs.recommended,
|
||||
// general options
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.node,
|
||||
ecmaVersion: 2022, // nodejs 18.0.0,
|
||||
sourceType: 'commonjs'
|
||||
},
|
||||
rules: {
|
||||
'comma-style': 'error',
|
||||
|
||||
indent: ['error', 2, {
|
||||
SwitchCase: 1,
|
||||
VariableDeclarator: 2
|
||||
}],
|
||||
|
||||
'keyword-spacing': 'error',
|
||||
'no-whitespace-before-property': 'error',
|
||||
'no-buffer-constructor': 'warn',
|
||||
'no-console': 'off',
|
||||
'no-constant-condition': 'off',
|
||||
'no-multi-spaces': 'error',
|
||||
'func-call-spacing': 'error',
|
||||
'no-trailing-spaces': 'error',
|
||||
'no-undef': 'error',
|
||||
'no-unneeded-ternary': 'error',
|
||||
'no-const-assign': 'error',
|
||||
'no-useless-rename': 'error',
|
||||
'no-dupe-keys': 'error',
|
||||
'space-in-parens': ['error', 'never'],
|
||||
|
||||
'spaced-comment': ['error', 'always', {
|
||||
block: {
|
||||
markers: ['!'],
|
||||
balanced: true
|
||||
}
|
||||
}],
|
||||
|
||||
'key-spacing': ['error', {
|
||||
beforeColon: false,
|
||||
afterColon: true
|
||||
}],
|
||||
|
||||
'comma-spacing': ['error', {
|
||||
before: false,
|
||||
after: true
|
||||
}],
|
||||
|
||||
'array-bracket-spacing': 1,
|
||||
|
||||
'arrow-spacing': ['error', {
|
||||
before: true,
|
||||
after: true
|
||||
}],
|
||||
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
'comma-dangle': ['error', 'never'],
|
||||
'no-unreachable': 'error',
|
||||
quotes: ['error', 'single'],
|
||||
'quote-props': ['error', 'as-needed'],
|
||||
semi: 'error',
|
||||
'no-extra-semi': 'error',
|
||||
'semi-spacing': 'error',
|
||||
'no-spaced-func': 'error',
|
||||
'no-throw-literal': 'error',
|
||||
'space-before-blocks': 'error',
|
||||
'space-before-function-paren': ['error', 'never'],
|
||||
'space-infix-ops': 'error',
|
||||
'space-unary-ops': 'error',
|
||||
'no-var': 'warn',
|
||||
'prefer-const': 'warn',
|
||||
strict: ['error', 'global'],
|
||||
|
||||
'no-restricted-globals': ['error', {
|
||||
name: 'context',
|
||||
message: 'Don\'t use Mocha\'s global context'
|
||||
}],
|
||||
|
||||
'no-prototype-builtins': 'off',
|
||||
'no-empty': 'off',
|
||||
'eol-last': 'warn',
|
||||
|
||||
'no-multiple-empty-lines': ['warn', {
|
||||
max: 2
|
||||
}]
|
||||
}
|
||||
},
|
||||
// general typescript options
|
||||
{
|
||||
files: ['**/*.{ts,tsx}', '**/*.md/*.ts', '**/*.md/*.typescript'],
|
||||
extends: [
|
||||
tseslint.configs.recommended
|
||||
],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: {
|
||||
allowDefaultProject: [],
|
||||
defaultProject: 'tsconfig.json'
|
||||
}
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/triple-slash-reference': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
|
||||
'spaced-comment': ['error', 'always', {
|
||||
block: {
|
||||
markers: ['!'],
|
||||
balanced: true
|
||||
},
|
||||
|
||||
markers: ['/']
|
||||
}],
|
||||
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/prefer-optional-chain': 'error',
|
||||
'@typescript-eslint/no-dupe-class-members': 'error',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
'@typescript-eslint/space-infix-ops': 'off',
|
||||
'@typescript-eslint/no-require-imports': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'@typescript-eslint/no-wrapper-object-types': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
'@typescript-eslint/no-unsafe-function-type': 'off'
|
||||
}
|
||||
},
|
||||
// type test specific options
|
||||
{
|
||||
files: ['test/types/**/*.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-empty-interface': 'off'
|
||||
}
|
||||
},
|
||||
// test specific options (including type tests)
|
||||
{
|
||||
files: ['test/**/*.js', 'test/**/*.ts'],
|
||||
ignores: ['deno*.mjs'],
|
||||
plugins: {
|
||||
'mocha-no-only': mochaNoOnly
|
||||
},
|
||||
languageOptions: {
|
||||
globals: globals.mocha
|
||||
},
|
||||
rules: {
|
||||
'no-self-assign': 'off',
|
||||
'mocha-no-only/mocha-no-only': ['error']
|
||||
}
|
||||
},
|
||||
// deno specific options
|
||||
{
|
||||
files: ['**/deno*.mjs'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
// "globals" currently has no definition for deno
|
||||
Deno: 'readonly'
|
||||
}
|
||||
}
|
||||
},
|
||||
// general options for module files
|
||||
{
|
||||
files: ['**/*.mjs'],
|
||||
languageOptions: {
|
||||
sourceType: 'module'
|
||||
}
|
||||
},
|
||||
// doc script specific options
|
||||
{
|
||||
files: ['**/docs/js/**/*.js'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])),
|
||||
...globals.browser }
|
||||
}
|
||||
}
|
||||
]);
|
||||
64
backend/node_modules/mongoose/index.js
generated
vendored
Normal file
64
backend/node_modules/mongoose/index.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Export lib/mongoose
|
||||
*
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const mongoose = require('./lib/');
|
||||
|
||||
module.exports = mongoose;
|
||||
module.exports.default = mongoose;
|
||||
module.exports.mongoose = mongoose;
|
||||
|
||||
// Re-export for ESM support
|
||||
module.exports.cast = mongoose.cast;
|
||||
module.exports.STATES = mongoose.STATES;
|
||||
module.exports.setDriver = mongoose.setDriver;
|
||||
module.exports.set = mongoose.set;
|
||||
module.exports.get = mongoose.get;
|
||||
module.exports.createConnection = mongoose.createConnection;
|
||||
module.exports.connect = mongoose.connect;
|
||||
module.exports.disconnect = mongoose.disconnect;
|
||||
module.exports.startSession = mongoose.startSession;
|
||||
module.exports.pluralize = mongoose.pluralize;
|
||||
module.exports.model = mongoose.model;
|
||||
module.exports.deleteModel = mongoose.deleteModel;
|
||||
module.exports.modelNames = mongoose.modelNames;
|
||||
module.exports.plugin = mongoose.plugin;
|
||||
module.exports.connections = mongoose.connections;
|
||||
module.exports.version = mongoose.version;
|
||||
module.exports.Aggregate = mongoose.Aggregate;
|
||||
module.exports.Mongoose = mongoose.Mongoose;
|
||||
module.exports.Schema = mongoose.Schema;
|
||||
module.exports.SchemaType = mongoose.SchemaType;
|
||||
module.exports.SchemaTypes = mongoose.SchemaTypes;
|
||||
module.exports.VirtualType = mongoose.VirtualType;
|
||||
module.exports.Types = mongoose.Types;
|
||||
module.exports.Query = mongoose.Query;
|
||||
module.exports.Model = mongoose.Model;
|
||||
module.exports.Document = mongoose.Document;
|
||||
module.exports.ObjectId = mongoose.ObjectId;
|
||||
module.exports.isValidObjectId = mongoose.isValidObjectId;
|
||||
module.exports.isObjectIdOrHexString = mongoose.isObjectIdOrHexString;
|
||||
module.exports.syncIndexes = mongoose.syncIndexes;
|
||||
module.exports.Decimal128 = mongoose.Decimal128;
|
||||
module.exports.Mixed = mongoose.Mixed;
|
||||
module.exports.Date = mongoose.Date;
|
||||
module.exports.Number = mongoose.Number;
|
||||
module.exports.Error = mongoose.Error;
|
||||
module.exports.MongooseError = mongoose.MongooseError;
|
||||
module.exports.now = mongoose.now;
|
||||
module.exports.CastError = mongoose.CastError;
|
||||
module.exports.SchemaTypeOptions = mongoose.SchemaTypeOptions;
|
||||
module.exports.mongo = mongoose.mongo;
|
||||
module.exports.mquery = mongoose.mquery;
|
||||
module.exports.sanitizeFilter = mongoose.sanitizeFilter;
|
||||
module.exports.trusted = mongoose.trusted;
|
||||
module.exports.skipMiddlewareFunction = mongoose.skipMiddlewareFunction;
|
||||
module.exports.overwriteMiddlewareResult = mongoose.overwriteMiddlewareResult;
|
||||
|
||||
// The following properties are not exported using ESM because `setDriver()` can mutate these
|
||||
// module.exports.connection = mongoose.connection;
|
||||
// module.exports.Collection = mongoose.Collection;
|
||||
// module.exports.Connection = mongoose.Connection;
|
||||
1226
backend/node_modules/mongoose/lib/aggregate.js
generated
vendored
Normal file
1226
backend/node_modules/mongoose/lib/aggregate.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
436
backend/node_modules/mongoose/lib/cast.js
generated
vendored
Normal file
436
backend/node_modules/mongoose/lib/cast.js
generated
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const CastError = require('./error/cast');
|
||||
const StrictModeError = require('./error/strict');
|
||||
const Types = require('./schema/index');
|
||||
const cast$expr = require('./helpers/query/cast$expr');
|
||||
const castString = require('./cast/string');
|
||||
const castTextSearch = require('./schema/operators/text');
|
||||
const get = require('./helpers/get');
|
||||
const getSchemaDiscriminatorByValue = require('./helpers/discriminator/getSchemaDiscriminatorByValue');
|
||||
const isOperator = require('./helpers/query/isOperator');
|
||||
const util = require('util');
|
||||
const isObject = require('./helpers/isObject');
|
||||
const isMongooseObject = require('./helpers/isMongooseObject');
|
||||
const utils = require('./utils');
|
||||
|
||||
const ALLOWED_GEOWITHIN_GEOJSON_TYPES = ['Polygon', 'MultiPolygon'];
|
||||
|
||||
/**
|
||||
* Handles internal casting for query filters.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {object} obj Object to cast
|
||||
* @param {object} [options] the query options
|
||||
* @param {boolean|"throw"} [options.strict] Whether to enable all strict options
|
||||
* @param {boolean|"throw"} [options.strictQuery] Enable strict Queries
|
||||
* @param {boolean} [options.sanitizeFilter] avoid adding implicit query selectors ($in)
|
||||
* @param {boolean} [options.upsert]
|
||||
* @param {Query} [context] passed to setters
|
||||
* @api private
|
||||
*/
|
||||
module.exports = function cast(schema, obj, options, context) {
|
||||
if (Array.isArray(obj)) {
|
||||
throw new Error('Query filter must be an object, got an array ' + util.inspect(obj));
|
||||
}
|
||||
|
||||
if (obj == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (schema?.discriminators != null && obj[schema.options.discriminatorKey] != null) {
|
||||
schema = getSchemaDiscriminatorByValue(schema, obj[schema.options.discriminatorKey]) || schema;
|
||||
}
|
||||
|
||||
const paths = Object.keys(obj);
|
||||
let i = paths.length;
|
||||
let _keys;
|
||||
let any$conditionals;
|
||||
let schematype;
|
||||
let nested;
|
||||
let path;
|
||||
let type;
|
||||
let val;
|
||||
|
||||
options = options || {};
|
||||
|
||||
while (i--) {
|
||||
path = paths[i];
|
||||
val = obj[path];
|
||||
|
||||
if (path === '$or' || path === '$nor' || path === '$and') {
|
||||
if (!Array.isArray(val)) {
|
||||
throw new CastError('Array', val, path);
|
||||
}
|
||||
for (let k = val.length - 1; k >= 0; k--) {
|
||||
if (val[k] == null || typeof val[k] !== 'object') {
|
||||
throw new CastError('Object', val[k], path + '.' + k);
|
||||
}
|
||||
const beforeCastKeysLength = Object.keys(val[k]).length;
|
||||
const discriminatorValue = val[k][schema.options.discriminatorKey];
|
||||
if (discriminatorValue == null) {
|
||||
val[k] = cast(schema, val[k], options, context);
|
||||
} else {
|
||||
const discriminatorSchema = getSchemaDiscriminatorByValue(context.schema, discriminatorValue);
|
||||
val[k] = cast(discriminatorSchema ? discriminatorSchema : schema, val[k], options, context);
|
||||
}
|
||||
|
||||
if (utils.hasOwnKeys(val[k]) === false && beforeCastKeysLength !== 0) {
|
||||
val.splice(k, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// delete empty: {$or: []} -> {}
|
||||
if (val.length === 0) {
|
||||
delete obj[path];
|
||||
}
|
||||
} else if (path === '$where') {
|
||||
type = typeof val;
|
||||
|
||||
if (type !== 'string' && type !== 'function') {
|
||||
throw new Error('Must have a string or function for $where');
|
||||
}
|
||||
|
||||
if (type === 'function') {
|
||||
obj[path] = val.toString();
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (path === '$expr') {
|
||||
val = cast$expr(val, schema);
|
||||
continue;
|
||||
} else if (path === '$elemMatch') {
|
||||
val = cast(schema, val, options, context);
|
||||
} else if (path === '$text') {
|
||||
val = castTextSearch(val, path);
|
||||
} else if (path === '$comment' && !Object.hasOwn(schema.paths, '$comment')) {
|
||||
val = castString(val, path);
|
||||
obj[path] = val;
|
||||
} else {
|
||||
if (!schema) {
|
||||
// no casting for Mixed types
|
||||
continue;
|
||||
}
|
||||
|
||||
schematype = schema.path(path);
|
||||
|
||||
// Check for embedded discriminator paths
|
||||
if (!schematype) {
|
||||
const split = path.split('.');
|
||||
let j = split.length;
|
||||
while (j--) {
|
||||
const pathFirstHalf = split.slice(0, j).join('.');
|
||||
const pathLastHalf = split.slice(j).join('.');
|
||||
const _schematype = schema.path(pathFirstHalf);
|
||||
const discriminatorKey = _schematype?.schema?.options?.discriminatorKey;
|
||||
|
||||
// gh-6027: if we haven't found the schematype but this path is
|
||||
// underneath an embedded discriminator and the embedded discriminator
|
||||
// key is in the query, use the embedded discriminator schema
|
||||
if (_schematype?.schema?.discriminators != null &&
|
||||
discriminatorKey != null &&
|
||||
pathLastHalf !== discriminatorKey) {
|
||||
const discriminatorVal = get(obj, pathFirstHalf + '.' + discriminatorKey);
|
||||
const discriminators = _schematype.schema.discriminators;
|
||||
if (typeof discriminatorVal === 'string' && discriminators[discriminatorVal] != null) {
|
||||
|
||||
schematype = discriminators[discriminatorVal].path(pathLastHalf);
|
||||
} else if (discriminatorVal != null &&
|
||||
Object.keys(discriminatorVal).length === 1 &&
|
||||
Array.isArray(discriminatorVal.$in) &&
|
||||
discriminatorVal.$in.length === 1 &&
|
||||
typeof discriminatorVal.$in[0] === 'string' &&
|
||||
discriminators[discriminatorVal.$in[0]] != null) {
|
||||
schematype = discriminators[discriminatorVal.$in[0]].path(pathLastHalf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!schematype) {
|
||||
// Handle potential embedded array queries
|
||||
const split = path.split('.');
|
||||
let j = split.length;
|
||||
let pathFirstHalf;
|
||||
let pathLastHalf;
|
||||
let remainingConds;
|
||||
|
||||
// Find the part of the var path that is a path of the Schema
|
||||
while (j--) {
|
||||
pathFirstHalf = split.slice(0, j).join('.');
|
||||
schematype = schema.path(pathFirstHalf);
|
||||
if (schematype) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If a substring of the input path resolves to an actual real path...
|
||||
if (schematype) {
|
||||
// Apply the casting; similar code for $elemMatch in schema/array.js
|
||||
if (schematype.schema) {
|
||||
remainingConds = {};
|
||||
pathLastHalf = split.slice(j).join('.');
|
||||
remainingConds[pathLastHalf] = val;
|
||||
|
||||
const ret = cast(schematype.schema, remainingConds, options, context)[pathLastHalf];
|
||||
if (ret === void 0) {
|
||||
delete obj[path];
|
||||
} else {
|
||||
obj[path] = ret;
|
||||
}
|
||||
} else {
|
||||
obj[path] = val;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isObject(val)) {
|
||||
// handle geo schemas that use object notation
|
||||
// { loc: { long: Number, lat: Number }
|
||||
|
||||
let geo = '';
|
||||
if (val.$near) {
|
||||
geo = '$near';
|
||||
} else if (val.$nearSphere) {
|
||||
geo = '$nearSphere';
|
||||
} else if (val.$within) {
|
||||
geo = '$within';
|
||||
} else if (val.$geoIntersects) {
|
||||
geo = '$geoIntersects';
|
||||
} else if (val.$geoWithin) {
|
||||
geo = '$geoWithin';
|
||||
}
|
||||
|
||||
if (geo) {
|
||||
const numbertype = new Types.Number('__QueryCasting__', null, null, schema);
|
||||
let value = val[geo];
|
||||
|
||||
if (val.$maxDistance != null) {
|
||||
val.$maxDistance = numbertype.castForQuery(
|
||||
null,
|
||||
val.$maxDistance,
|
||||
context
|
||||
);
|
||||
}
|
||||
if (val.$minDistance != null) {
|
||||
val.$minDistance = numbertype.castForQuery(
|
||||
null,
|
||||
val.$minDistance,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
if (geo === '$within') {
|
||||
const withinType = value.$center
|
||||
|| value.$centerSphere
|
||||
|| value.$box
|
||||
|| value.$polygon;
|
||||
|
||||
if (!withinType) {
|
||||
throw new Error('Bad $within parameter: ' + JSON.stringify(val));
|
||||
}
|
||||
|
||||
value = withinType;
|
||||
} else if (geo === '$near' &&
|
||||
typeof value.type === 'string' && Array.isArray(value.coordinates)) {
|
||||
// geojson; cast the coordinates
|
||||
value = value.coordinates;
|
||||
} else if ((geo === '$near' || geo === '$nearSphere' || geo === '$geoIntersects') &&
|
||||
value.$geometry && typeof value.$geometry.type === 'string' &&
|
||||
Array.isArray(value.$geometry.coordinates)) {
|
||||
if (value.$maxDistance != null) {
|
||||
value.$maxDistance = numbertype.castForQuery(
|
||||
null,
|
||||
value.$maxDistance,
|
||||
context
|
||||
);
|
||||
}
|
||||
if (value.$minDistance != null) {
|
||||
value.$minDistance = numbertype.castForQuery(
|
||||
null,
|
||||
value.$minDistance,
|
||||
context
|
||||
);
|
||||
}
|
||||
if (isMongooseObject(value.$geometry)) {
|
||||
value.$geometry = value.$geometry.toObject({
|
||||
transform: false,
|
||||
virtuals: false
|
||||
});
|
||||
}
|
||||
value = value.$geometry.coordinates;
|
||||
} else if (geo === '$geoWithin') {
|
||||
if (value.$geometry) {
|
||||
if (isMongooseObject(value.$geometry)) {
|
||||
value.$geometry = value.$geometry.toObject({ virtuals: false });
|
||||
}
|
||||
const geoWithinType = value.$geometry.type;
|
||||
if (ALLOWED_GEOWITHIN_GEOJSON_TYPES.indexOf(geoWithinType) === -1) {
|
||||
throw new Error('Invalid geoJSON type for $geoWithin "' +
|
||||
geoWithinType + '", must be "Polygon" or "MultiPolygon"');
|
||||
}
|
||||
value = value.$geometry.coordinates;
|
||||
} else {
|
||||
value = value.$box || value.$polygon || value.$center ||
|
||||
value.$centerSphere;
|
||||
if (isMongooseObject(value)) {
|
||||
value = value.toObject({ virtuals: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cast(value, numbertype, context);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (schema.nested[path]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const strict = 'strict' in options ? options.strict : schema.options.strict;
|
||||
const strictQuery = getStrictQuery(options, schema._userProvidedOptions, schema.options, context);
|
||||
if (options.upsert && strict) {
|
||||
if (strict === 'throw') {
|
||||
throw new StrictModeError(path);
|
||||
}
|
||||
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
|
||||
'schema, strict mode is `true`, and upsert is `true`.');
|
||||
} if (strictQuery === 'throw') {
|
||||
throw new StrictModeError(path, 'Path "' + path + '" is not in ' +
|
||||
'schema and strictQuery is \'throw\'.');
|
||||
} else if (strictQuery) {
|
||||
delete obj[path];
|
||||
}
|
||||
} else if (val == null) {
|
||||
continue;
|
||||
} else if (utils.isPOJO(val)) {
|
||||
any$conditionals = Object.keys(val).some(isOperator);
|
||||
|
||||
if (!any$conditionals) {
|
||||
obj[path] = schematype.castForQuery(
|
||||
null,
|
||||
val,
|
||||
context
|
||||
);
|
||||
} else {
|
||||
const ks = Object.keys(val);
|
||||
let $cond;
|
||||
let k = ks.length;
|
||||
|
||||
while (k--) {
|
||||
$cond = ks[k];
|
||||
nested = val[$cond];
|
||||
if ($cond === '$elemMatch') {
|
||||
if (nested && schematype?.schema != null) {
|
||||
cast(schematype.schema, nested, options, context);
|
||||
} else if (nested && schematype?.$isMongooseArray) {
|
||||
if (utils.isPOJO(nested) && nested.$not != null) {
|
||||
cast(schema, nested, options, context);
|
||||
} else {
|
||||
val[$cond] = schematype.castForQuery(
|
||||
$cond,
|
||||
nested,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if ($cond === '$not') {
|
||||
if (nested && schematype) {
|
||||
_keys = Object.keys(nested);
|
||||
if (_keys.length && isOperator(_keys[0])) {
|
||||
for (const key in nested) {
|
||||
nested[key] = schematype.castForQuery(
|
||||
key,
|
||||
nested[key],
|
||||
context
|
||||
);
|
||||
}
|
||||
} else {
|
||||
val[$cond] = schematype.castForQuery(
|
||||
$cond,
|
||||
nested,
|
||||
context
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
val[$cond] = schematype.castForQuery(
|
||||
$cond,
|
||||
nested,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else if (Array.isArray(val) && ['Buffer', 'Array'].indexOf(schematype.instance) === -1 && !options.sanitizeFilter) {
|
||||
const casted = [];
|
||||
const valuesArray = val;
|
||||
|
||||
for (const _val of valuesArray) {
|
||||
casted.push(schematype.castForQuery(
|
||||
null,
|
||||
_val,
|
||||
context
|
||||
));
|
||||
}
|
||||
|
||||
obj[path] = { $in: casted };
|
||||
} else {
|
||||
obj[path] = schematype.castForQuery(
|
||||
null,
|
||||
val,
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
function _cast(val, numbertype, context) {
|
||||
if (Array.isArray(val)) {
|
||||
val.forEach(function(item, i) {
|
||||
if (Array.isArray(item) || isObject(item)) {
|
||||
return _cast(item, numbertype, context);
|
||||
}
|
||||
val[i] = numbertype.castForQuery(null, item, context);
|
||||
});
|
||||
} else {
|
||||
const nearKeys = Object.keys(val);
|
||||
let nearLen = nearKeys.length;
|
||||
while (nearLen--) {
|
||||
const nkey = nearKeys[nearLen];
|
||||
const item = val[nkey];
|
||||
if (Array.isArray(item) || isObject(item)) {
|
||||
_cast(item, numbertype, context);
|
||||
val[nkey] = item;
|
||||
} else {
|
||||
val[nkey] = numbertype.castForQuery({ val: item, context: context });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getStrictQuery(queryOptions, schemaUserProvidedOptions, schemaOptions, context) {
|
||||
if ('strictQuery' in queryOptions) {
|
||||
return queryOptions.strictQuery;
|
||||
}
|
||||
if ('strictQuery' in schemaUserProvidedOptions) {
|
||||
return schemaUserProvidedOptions.strictQuery;
|
||||
}
|
||||
const mongooseOptions = context?.mongooseCollection?.conn?.base?.options;
|
||||
if (mongooseOptions) {
|
||||
if ('strictQuery' in mongooseOptions) {
|
||||
return mongooseOptions.strictQuery;
|
||||
}
|
||||
}
|
||||
return schemaOptions.strictQuery;
|
||||
}
|
||||
46
backend/node_modules/mongoose/lib/cast/bigint.js
generated
vendored
Normal file
46
backend/node_modules/mongoose/lib/cast/bigint.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
const { Long } = require('mongodb/lib/bson');
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a BigInt, or throw an `Error` if the value
|
||||
* cannot be casted. `null` and `undefined` are considered valid.
|
||||
*
|
||||
* @param {any} value
|
||||
* @return {bigint|null|undefined}
|
||||
* @throws {Error} if `value` is not one of the allowed values
|
||||
* @api private
|
||||
*/
|
||||
|
||||
const MAX_BIGINT = 9223372036854775807n;
|
||||
const MIN_BIGINT = -9223372036854775808n;
|
||||
const ERROR_MESSAGE = `Mongoose only supports BigInts between ${MIN_BIGINT} and ${MAX_BIGINT} because MongoDB does not support arbitrary precision integers`;
|
||||
|
||||
module.exports = function castBigInt(val) {
|
||||
if (val == null) {
|
||||
return val;
|
||||
}
|
||||
if (val === '') {
|
||||
return null;
|
||||
}
|
||||
if (typeof val === 'bigint') {
|
||||
if (val > MAX_BIGINT || val < MIN_BIGINT) {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val instanceof Long) {
|
||||
return val.toBigInt();
|
||||
}
|
||||
|
||||
if (typeof val === 'string' || typeof val === 'number') {
|
||||
val = BigInt(val);
|
||||
if (val > MAX_BIGINT || val < MIN_BIGINT) {
|
||||
throw new Error(ERROR_MESSAGE);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
throw new Error(`Cannot convert value to BigInt: "${val}"`);
|
||||
};
|
||||
32
backend/node_modules/mongoose/lib/cast/boolean.js
generated
vendored
Normal file
32
backend/node_modules/mongoose/lib/cast/boolean.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const CastError = require('../error/cast');
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a boolean, or throw a `CastError` if the value
|
||||
* cannot be casted. `null` and `undefined` are considered valid.
|
||||
*
|
||||
* @param {any} value
|
||||
* @param {string} [path] optional the path to set on the CastError
|
||||
* @return {boolean|null|undefined}
|
||||
* @throws {CastError} if `value` is not one of the allowed values
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castBoolean(value, path) {
|
||||
if (module.exports.convertToTrue.has(value)) {
|
||||
return true;
|
||||
}
|
||||
if (module.exports.convertToFalse.has(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new CastError('boolean', value, path);
|
||||
};
|
||||
|
||||
module.exports.convertToTrue = new Set([true, 'true', 1, '1', 'yes']);
|
||||
module.exports.convertToFalse = new Set([false, 'false', 0, '0', 'no']);
|
||||
41
backend/node_modules/mongoose/lib/cast/date.js
generated
vendored
Normal file
41
backend/node_modules/mongoose/lib/cast/date.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
module.exports = function castDate(value) {
|
||||
// Support empty string because of empty form values. Originally introduced
|
||||
// in https://github.com/Automattic/mongoose/commit/efc72a1898fc3c33a319d915b8c5463a22938dfe
|
||||
if (value == null || value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value instanceof Date) {
|
||||
assert.ok(!isNaN(value.valueOf()));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
let date;
|
||||
|
||||
assert.ok(typeof value !== 'boolean');
|
||||
|
||||
if (value instanceof Number || typeof value === 'number') {
|
||||
date = new Date(value);
|
||||
} else if (typeof value === 'string' && !isNaN(Number(value)) && (Number(value) >= 275761 || Number(value) < -271820)) {
|
||||
// string representation of milliseconds take this path
|
||||
date = new Date(Number(value));
|
||||
} else if (typeof value.valueOf === 'function') {
|
||||
// support for moment.js. This is also the path strings will take because
|
||||
// strings have a `valueOf()`
|
||||
date = new Date(value.valueOf());
|
||||
} else {
|
||||
// fallback
|
||||
date = new Date(value);
|
||||
}
|
||||
|
||||
if (!isNaN(date.valueOf())) {
|
||||
return date;
|
||||
}
|
||||
|
||||
assert.ok(false);
|
||||
};
|
||||
39
backend/node_modules/mongoose/lib/cast/decimal128.js
generated
vendored
Normal file
39
backend/node_modules/mongoose/lib/cast/decimal128.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
const Decimal128Type = require('../types/decimal128');
|
||||
const assert = require('assert');
|
||||
|
||||
module.exports = function castDecimal128(value) {
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'object' && typeof value.$numberDecimal === 'string') {
|
||||
return Decimal128Type.fromString(value.$numberDecimal);
|
||||
}
|
||||
|
||||
if (value instanceof Decimal128Type) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return Decimal128Type.fromString(value);
|
||||
}
|
||||
|
||||
if (typeof Buffer === 'function' && Buffer.isBuffer(value)) {
|
||||
return new Decimal128Type(value);
|
||||
}
|
||||
if (typeof Uint8Array === 'function' && value instanceof Uint8Array) {
|
||||
return new Decimal128Type(value);
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return Decimal128Type.fromString(String(value));
|
||||
}
|
||||
|
||||
if (typeof value.valueOf === 'function' && typeof value.valueOf() === 'string') {
|
||||
return Decimal128Type.fromString(value.valueOf());
|
||||
}
|
||||
|
||||
assert.ok(false);
|
||||
};
|
||||
50
backend/node_modules/mongoose/lib/cast/double.js
generated
vendored
Normal file
50
backend/node_modules/mongoose/lib/cast/double.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const BSON = require('mongodb/lib/bson');
|
||||
const isBsonType = require('../helpers/isBsonType');
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a IEEE 754-2008 floating point, or throw an `Error` if the value
|
||||
* cannot be casted. `null`, `undefined`, and `NaN` are considered valid inputs.
|
||||
*
|
||||
* @param {any} value
|
||||
* @return {number}
|
||||
* @throws {Error} if `value` does not represent a IEEE 754-2008 floating point. If casting from a string, see [BSON Double.fromString API documentation](https://mongodb.github.io/node-mongodb-native/Next/classes/BSON.Double.html#fromString)
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castDouble(val) {
|
||||
if (val == null || val === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
let coercedVal;
|
||||
if (isBsonType(val, 'Long')) {
|
||||
coercedVal = val.toNumber();
|
||||
} else if (typeof val === 'string') {
|
||||
try {
|
||||
coercedVal = BSON.Double.fromString(val);
|
||||
return coercedVal;
|
||||
} catch {
|
||||
assert.ok(false);
|
||||
}
|
||||
} else if (typeof val === 'object') {
|
||||
const tempVal = val.valueOf() ?? val.toString();
|
||||
// ex: { a: 'im an object, valueOf: () => 'helloworld' } // throw an error
|
||||
if (typeof tempVal === 'string') {
|
||||
try {
|
||||
coercedVal = BSON.Double.fromString(tempVal);
|
||||
return coercedVal;
|
||||
} catch {
|
||||
assert.ok(false);
|
||||
}
|
||||
} else {
|
||||
coercedVal = Number(tempVal);
|
||||
}
|
||||
} else {
|
||||
coercedVal = Number(val);
|
||||
}
|
||||
|
||||
return new BSON.Double(coercedVal);
|
||||
};
|
||||
36
backend/node_modules/mongoose/lib/cast/int32.js
generated
vendored
Normal file
36
backend/node_modules/mongoose/lib/cast/int32.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
const isBsonType = require('../helpers/isBsonType');
|
||||
const assert = require('assert');
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a Int32, or throw an `Error` if the value
|
||||
* cannot be casted. `null` and `undefined` are considered valid.
|
||||
*
|
||||
* @param {any} value
|
||||
* @return {number}
|
||||
* @throws {Error} if `value` does not represent an integer, or is outside the bounds of an 32-bit integer.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castInt32(val) {
|
||||
if (val == null) {
|
||||
return val;
|
||||
}
|
||||
if (val === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const coercedVal = isBsonType(val, 'Long') ? val.toNumber() : Number(val);
|
||||
|
||||
const INT32_MAX = 0x7FFFFFFF;
|
||||
const INT32_MIN = -0x80000000;
|
||||
|
||||
if (coercedVal === (coercedVal | 0) &&
|
||||
coercedVal >= INT32_MIN &&
|
||||
coercedVal <= INT32_MAX
|
||||
) {
|
||||
return coercedVal;
|
||||
}
|
||||
assert.ok(false);
|
||||
};
|
||||
42
backend/node_modules/mongoose/lib/cast/number.js
generated
vendored
Normal file
42
backend/node_modules/mongoose/lib/cast/number.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a number, or throw an `Error` if the value
|
||||
* cannot be casted. `null` and `undefined` are considered valid.
|
||||
*
|
||||
* @param {any} value
|
||||
* @return {number}
|
||||
* @throws {Error} if `value` is not one of the allowed values
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castNumber(val) {
|
||||
if (val == null) {
|
||||
return val;
|
||||
}
|
||||
if (val === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof val === 'string' || typeof val === 'boolean') {
|
||||
val = Number(val);
|
||||
}
|
||||
|
||||
if (isNaN(val)) {
|
||||
throw new Error('Cast to Number failed: value is not a valid number');
|
||||
}
|
||||
if (val instanceof Number) {
|
||||
return val.valueOf();
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
return val;
|
||||
}
|
||||
if (!Array.isArray(val) && typeof val.valueOf === 'function') {
|
||||
return Number(val.valueOf());
|
||||
}
|
||||
if (val.toString && !Array.isArray(val) && val.toString() == Number(val)) {
|
||||
return Number(val);
|
||||
}
|
||||
|
||||
throw new Error('Cast to Number failed: value is not a valid number');
|
||||
};
|
||||
29
backend/node_modules/mongoose/lib/cast/objectid.js
generated
vendored
Normal file
29
backend/node_modules/mongoose/lib/cast/objectid.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const isBsonType = require('../helpers/isBsonType');
|
||||
const ObjectId = require('../types/objectid');
|
||||
|
||||
module.exports = function castObjectId(value) {
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (isBsonType(value, 'ObjectId')) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value._id) {
|
||||
if (isBsonType(value._id, 'ObjectId')) {
|
||||
return value._id;
|
||||
}
|
||||
if (value._id.toString instanceof Function) {
|
||||
return new ObjectId(value._id.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (value.toString instanceof Function) {
|
||||
return new ObjectId(value.toString());
|
||||
}
|
||||
|
||||
return new ObjectId(value);
|
||||
};
|
||||
37
backend/node_modules/mongoose/lib/cast/string.js
generated
vendored
Normal file
37
backend/node_modules/mongoose/lib/cast/string.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict';
|
||||
|
||||
const CastError = require('../error/cast');
|
||||
|
||||
/**
|
||||
* Given a value, cast it to a string, or throw a `CastError` if the value
|
||||
* cannot be casted. `null` and `undefined` are considered valid.
|
||||
*
|
||||
* @param {any} value
|
||||
* @param {string} [path] optional the path to set on the CastError
|
||||
* @return {string|null|undefined}
|
||||
* @throws {CastError}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function castString(value, path) {
|
||||
// If null or undefined
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// handle documents being passed
|
||||
if (typeof value?._id === 'string') {
|
||||
return value._id;
|
||||
}
|
||||
|
||||
// Re: gh-647 and gh-3030, we're ok with casting using `toString()`
|
||||
// **unless** its the default Object.toString, because "[object Object]"
|
||||
// doesn't really qualify as useful data
|
||||
if (value.toString &&
|
||||
value.toString !== Object.prototype.toString &&
|
||||
!Array.isArray(value)) {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
throw new CastError('string', value, path);
|
||||
};
|
||||
35
backend/node_modules/mongoose/lib/cast/uuid.js
generated
vendored
Normal file
35
backend/node_modules/mongoose/lib/cast/uuid.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
const UUID = require('mongodb/lib/bson').UUID;
|
||||
|
||||
const UUID_FORMAT = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
|
||||
|
||||
module.exports = function castUUID(value) {
|
||||
if (value == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value instanceof UUID) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
if (UUID_FORMAT.test(value)) {
|
||||
return new UUID(value);
|
||||
} else {
|
||||
throw new Error(`"${value}" is not a valid UUID string`);
|
||||
}
|
||||
}
|
||||
|
||||
// Re: gh-647 and gh-3030, we're ok with casting using `toString()`
|
||||
// **unless** its the default Object.toString, because "[object Object]"
|
||||
// doesn't really qualify as useful data
|
||||
if (value.toString && value.toString !== Object.prototype.toString) {
|
||||
if (UUID_FORMAT.test(value.toString())) {
|
||||
return new UUID(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`"${value}" cannot be casted to a UUID`);
|
||||
};
|
||||
|
||||
module.exports.UUID_FORMAT = UUID_FORMAT;
|
||||
321
backend/node_modules/mongoose/lib/collection.js
generated
vendored
Normal file
321
backend/node_modules/mongoose/lib/collection.js
generated
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const STATES = require('./connectionState');
|
||||
const immediate = require('./helpers/immediate');
|
||||
|
||||
/**
|
||||
* Abstract Collection constructor
|
||||
*
|
||||
* This is the base class that drivers inherit from and implement.
|
||||
*
|
||||
* @param {string} name name of the collection
|
||||
* @param {Connection} conn A MongooseConnection instance
|
||||
* @param {object} [opts] optional collection options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Collection(name, conn, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
|
||||
this.opts = opts;
|
||||
this.name = name;
|
||||
this.collectionName = name;
|
||||
this.conn = conn;
|
||||
this.queue = [];
|
||||
this.buffer = !conn?._hasOpened;
|
||||
this.emitter = new EventEmitter();
|
||||
|
||||
if (STATES.connected === this.conn.readyState) {
|
||||
this.onOpen();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection name
|
||||
*
|
||||
* @api public
|
||||
* @property name
|
||||
*/
|
||||
|
||||
Collection.prototype.name;
|
||||
|
||||
/**
|
||||
* The collection name
|
||||
*
|
||||
* @api public
|
||||
* @property collectionName
|
||||
*/
|
||||
|
||||
Collection.prototype.collectionName;
|
||||
|
||||
/**
|
||||
* The Connection instance
|
||||
*
|
||||
* @api public
|
||||
* @property conn
|
||||
*/
|
||||
|
||||
Collection.prototype.conn;
|
||||
|
||||
/**
|
||||
* Called when the database connects
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onOpen = function() {
|
||||
this.buffer = false;
|
||||
immediate(() => this.doQueue());
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the database disconnects
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onClose = function() {};
|
||||
|
||||
/**
|
||||
* Queues a method for later execution when its
|
||||
* database connection opens.
|
||||
*
|
||||
* @param {string} name name of the method to queue
|
||||
* @param {Array} args arguments to pass to the method when executed
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.addQueue = function(name, args) {
|
||||
this.queue.push([name, args]);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a queued method
|
||||
*
|
||||
* @param {string} name name of the method to queue
|
||||
* @param {Array} args arguments to pass to the method when executed
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.removeQueue = function(name, args) {
|
||||
const index = this.queue.findIndex(v => v[0] === name && v[1] === args);
|
||||
if (index === -1) {
|
||||
return false;
|
||||
}
|
||||
this.queue.splice(index, 1);
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes all queued methods and clears the queue.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.doQueue = function() {
|
||||
for (const method of this.queue) {
|
||||
if (typeof method[0] === 'function') {
|
||||
method[0].apply(this, method[1]);
|
||||
} else {
|
||||
this[method[0]].apply(this, method[1]);
|
||||
}
|
||||
}
|
||||
this.queue = [];
|
||||
const _this = this;
|
||||
immediate(function() {
|
||||
_this.emitter.emit('queue');
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.ensureIndex = function() {
|
||||
throw new Error('Collection#ensureIndex unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.createIndex = function() {
|
||||
throw new Error('Collection#createIndex unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findAndModify = function() {
|
||||
throw new Error('Collection#findAndModify unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOneAndUpdate = function() {
|
||||
throw new Error('Collection#findOneAndUpdate unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOneAndDelete = function() {
|
||||
throw new Error('Collection#findOneAndDelete unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOneAndReplace = function() {
|
||||
throw new Error('Collection#findOneAndReplace unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOne = function() {
|
||||
throw new Error('Collection#findOne unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.find = function() {
|
||||
throw new Error('Collection#find unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.insert = function() {
|
||||
throw new Error('Collection#insert unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.insertOne = function() {
|
||||
throw new Error('Collection#insertOne unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.insertMany = function() {
|
||||
throw new Error('Collection#insertMany unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.save = function() {
|
||||
throw new Error('Collection#save unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.updateOne = function() {
|
||||
throw new Error('Collection#updateOne unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.updateMany = function() {
|
||||
throw new Error('Collection#updateMany unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.deleteOne = function() {
|
||||
throw new Error('Collection#deleteOne unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.deleteMany = function() {
|
||||
throw new Error('Collection#deleteMany unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.getIndexes = function() {
|
||||
throw new Error('Collection#getIndexes unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.watch = function() {
|
||||
throw new Error('Collection#watch unimplemented by driver');
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
Collection.prototype._shouldBufferCommands = function _shouldBufferCommands() {
|
||||
const opts = this.opts;
|
||||
|
||||
if (opts.bufferCommands != null) {
|
||||
return opts.bufferCommands;
|
||||
}
|
||||
if (opts?.schemaUserProvidedOptions?.bufferCommands != null) {
|
||||
return opts.schemaUserProvidedOptions.bufferCommands;
|
||||
}
|
||||
|
||||
return this.conn._shouldBufferCommands();
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
Collection.prototype._getBufferTimeoutMS = function _getBufferTimeoutMS() {
|
||||
const conn = this.conn;
|
||||
const opts = this.opts;
|
||||
|
||||
if (opts.bufferTimeoutMS != null) {
|
||||
return opts.bufferTimeoutMS;
|
||||
}
|
||||
if (opts?.schemaUserProvidedOptions?.bufferTimeoutMS != null) {
|
||||
return opts.schemaUserProvidedOptions.bufferTimeoutMS;
|
||||
}
|
||||
return conn._getBufferTimeoutMS();
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Collection;
|
||||
1841
backend/node_modules/mongoose/lib/connection.js
generated
vendored
Normal file
1841
backend/node_modules/mongoose/lib/connection.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
26
backend/node_modules/mongoose/lib/connectionState.js
generated
vendored
Normal file
26
backend/node_modules/mongoose/lib/connectionState.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
/*!
|
||||
* Connection states
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const STATES = module.exports = exports = Object.create(null);
|
||||
|
||||
const disconnected = 'disconnected';
|
||||
const connected = 'connected';
|
||||
const connecting = 'connecting';
|
||||
const disconnecting = 'disconnecting';
|
||||
const uninitialized = 'uninitialized';
|
||||
|
||||
STATES[0] = disconnected;
|
||||
STATES[1] = connected;
|
||||
STATES[2] = connecting;
|
||||
STATES[3] = disconnecting;
|
||||
STATES[99] = uninitialized;
|
||||
|
||||
STATES[disconnected] = 0;
|
||||
STATES[connected] = 1;
|
||||
STATES[connecting] = 2;
|
||||
STATES[disconnecting] = 3;
|
||||
STATES[uninitialized] = 99;
|
||||
73
backend/node_modules/mongoose/lib/constants.js
generated
vendored
Normal file
73
backend/node_modules/mongoose/lib/constants.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const queryOperations = Object.freeze([
|
||||
// Read
|
||||
'countDocuments',
|
||||
'distinct',
|
||||
'estimatedDocumentCount',
|
||||
'find',
|
||||
'findOne',
|
||||
// Update
|
||||
'findOneAndReplace',
|
||||
'findOneAndUpdate',
|
||||
'replaceOne',
|
||||
'updateMany',
|
||||
'updateOne',
|
||||
// Delete
|
||||
'deleteMany',
|
||||
'deleteOne',
|
||||
'findOneAndDelete'
|
||||
]);
|
||||
|
||||
exports.queryOperations = queryOperations;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const queryMiddlewareFunctions = queryOperations.concat([
|
||||
'validate'
|
||||
]);
|
||||
|
||||
exports.queryMiddlewareFunctions = queryMiddlewareFunctions;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const aggregateMiddlewareFunctions = [
|
||||
'aggregate'
|
||||
];
|
||||
|
||||
exports.aggregateMiddlewareFunctions = aggregateMiddlewareFunctions;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const modelMiddlewareFunctions = [
|
||||
'bulkWrite',
|
||||
'createCollection',
|
||||
'insertMany'
|
||||
];
|
||||
|
||||
exports.modelMiddlewareFunctions = modelMiddlewareFunctions;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const documentMiddlewareFunctions = [
|
||||
'validate',
|
||||
'save',
|
||||
'remove',
|
||||
'updateOne',
|
||||
'deleteOne',
|
||||
'init'
|
||||
];
|
||||
|
||||
exports.documentMiddlewareFunctions = documentMiddlewareFunctions;
|
||||
466
backend/node_modules/mongoose/lib/cursor/aggregationCursor.js
generated
vendored
Normal file
466
backend/node_modules/mongoose/lib/cursor/aggregationCursor.js
generated
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('../error/mongooseError');
|
||||
const Readable = require('stream').Readable;
|
||||
const eachAsync = require('../helpers/cursor/eachAsync');
|
||||
const immediate = require('../helpers/immediate');
|
||||
const kareem = require('kareem');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* An AggregationCursor is a concurrency primitive for processing aggregation
|
||||
* results one document at a time. It is analogous to QueryCursor.
|
||||
*
|
||||
* An AggregationCursor fulfills the Node.js streams3 API,
|
||||
* in addition to several other mechanisms for loading documents from MongoDB
|
||||
* one at a time.
|
||||
*
|
||||
* Creating an AggregationCursor executes the model's pre aggregate hooks,
|
||||
* but **not** the model's post aggregate hooks.
|
||||
*
|
||||
* Unless you're an advanced user, do **not** instantiate this class directly.
|
||||
* Use [`Aggregate#cursor()`](https://mongoosejs.com/docs/api/aggregate.html#Aggregate.prototype.cursor()) instead.
|
||||
*
|
||||
* @param {Aggregate} agg
|
||||
* @inherits Readable https://nodejs.org/api/stream.html#class-streamreadable
|
||||
* @event `cursor`: Emitted when the cursor is created
|
||||
* @event `error`: Emitted when an error occurred
|
||||
* @event `data`: Emitted when the stream is flowing and the next doc is ready
|
||||
* @event `end`: Emitted when the stream is exhausted
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function AggregationCursor(agg) {
|
||||
// set autoDestroy=true because on node 12 it's by default false
|
||||
// gh-10902 need autoDestroy to destroy correctly and emit 'close' event
|
||||
Readable.call(this, { autoDestroy: true, objectMode: true });
|
||||
|
||||
this.cursor = null;
|
||||
this.agg = agg;
|
||||
this._transforms = [];
|
||||
const connection = agg._connection;
|
||||
const model = agg._model;
|
||||
delete agg.options.cursor.useMongooseAggCursor;
|
||||
this._mongooseOptions = {};
|
||||
|
||||
if (connection) {
|
||||
this.cursor = connection.db.aggregate(agg._pipeline, agg.options || {});
|
||||
setImmediate(() => this.emit('cursor', this.cursor));
|
||||
} else {
|
||||
_init(model, this, agg);
|
||||
}
|
||||
}
|
||||
|
||||
util.inherits(AggregationCursor, Readable);
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _init(model, c, agg) {
|
||||
if (!model.collection.buffer) {
|
||||
model.hooks.execPre('aggregate', agg).then(() => onPreComplete(null), err => onPreComplete(err));
|
||||
} else {
|
||||
model.collection.emitter.once('queue', function() {
|
||||
model.hooks.execPre('aggregate', agg).then(() => onPreComplete(null), err => onPreComplete(err));
|
||||
});
|
||||
}
|
||||
|
||||
function onPreComplete(err) {
|
||||
if (err != null) {
|
||||
_handlePreHookError(c, err);
|
||||
return;
|
||||
}
|
||||
if (typeof agg.options?.cursor?.transform === 'function') {
|
||||
c._transforms.push(agg.options.cursor.transform);
|
||||
}
|
||||
|
||||
c.cursor = model.collection.aggregate(agg._pipeline, agg.options || {});
|
||||
c.emit('cursor', c.cursor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles error emitted from pre middleware. In particular, checks for `skipWrappedFunction`, which allows skipping
|
||||
* the actual aggregation and overwriting the function's return value. Because aggregation cursors don't return a value,
|
||||
* we need to make sure the user doesn't accidentally set a value in skipWrappedFunction.
|
||||
*
|
||||
* @param {QueryCursor} queryCursor
|
||||
* @param {Error} err
|
||||
* @returns
|
||||
*/
|
||||
|
||||
function _handlePreHookError(queryCursor, err) {
|
||||
if (err instanceof kareem.skipWrappedFunction) {
|
||||
const resultValue = err.args[0];
|
||||
if (resultValue != null && (!Array.isArray(resultValue) || resultValue.length)) {
|
||||
const err = new MongooseError(
|
||||
'Cannot `skipMiddlewareFunction()` with a value when using ' +
|
||||
'`.aggregate().cursor()`, value must be nullish or empty array, got "' +
|
||||
util.inspect(resultValue) +
|
||||
'".'
|
||||
);
|
||||
queryCursor._markError(err);
|
||||
queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
|
||||
return;
|
||||
}
|
||||
queryCursor.emit('cursor', null);
|
||||
return;
|
||||
}
|
||||
queryCursor._markError(err);
|
||||
queryCursor.listeners('error').length > 0 && queryCursor.emit('error', err);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Necessary to satisfy the Readable API
|
||||
* @method _read
|
||||
* @memberOf AggregationCursor
|
||||
* @instance
|
||||
* @api private
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype._read = function() {
|
||||
const _this = this;
|
||||
_next(this, function(error, doc) {
|
||||
if (error) {
|
||||
return _this.emit('error', error);
|
||||
}
|
||||
if (!doc) {
|
||||
_this.push(null);
|
||||
_this.cursor.close(function(error) {
|
||||
if (error) {
|
||||
return _this.emit('error', error);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
_this.push(doc);
|
||||
});
|
||||
};
|
||||
|
||||
if (Symbol.asyncIterator != null) {
|
||||
const msg = 'Mongoose does not support using async iterators with an ' +
|
||||
'existing aggregation cursor. See https://bit.ly/mongoose-async-iterate-aggregation';
|
||||
|
||||
AggregationCursor.prototype[Symbol.asyncIterator] = function() {
|
||||
throw new MongooseError(msg);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a transform function which subsequently maps documents retrieved
|
||||
* via the streams interface or `.next()`
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Map documents returned by `data` events
|
||||
* Thing.
|
||||
* find({ name: /^hello/ }).
|
||||
* cursor().
|
||||
* map(function (doc) {
|
||||
* doc.foo = "bar";
|
||||
* return doc;
|
||||
* })
|
||||
* on('data', function(doc) { console.log(doc.foo); });
|
||||
*
|
||||
* // Or map documents returned by `.next()`
|
||||
* const cursor = Thing.find({ name: /^hello/ }).
|
||||
* cursor().
|
||||
* map(function (doc) {
|
||||
* doc.foo = "bar";
|
||||
* return doc;
|
||||
* });
|
||||
* cursor.next(function(error, doc) {
|
||||
* console.log(doc.foo);
|
||||
* });
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {AggregationCursor}
|
||||
* @memberOf AggregationCursor
|
||||
* @api public
|
||||
* @method map
|
||||
*/
|
||||
|
||||
Object.defineProperty(AggregationCursor.prototype, 'map', {
|
||||
value: function(fn) {
|
||||
this._transforms.push(fn);
|
||||
return this;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Marks this cursor as errored
|
||||
* @method _markError
|
||||
* @instance
|
||||
* @memberOf AggregationCursor
|
||||
* @api private
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype._markError = function(error) {
|
||||
this._error = error;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this cursor as closed. Will stop streaming and subsequent calls to
|
||||
* `next()` will error.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method close
|
||||
* @emits "close"
|
||||
* @see AggregationCursor.close https://mongodb.github.io/node-mongodb-native/7.0/classes/AggregationCursor.html#close
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype.close = async function close() {
|
||||
if (typeof arguments[0] === 'function') {
|
||||
throw new MongooseError('AggregationCursor.prototype.close() no longer accepts a callback');
|
||||
}
|
||||
try {
|
||||
await this.cursor.close();
|
||||
} catch (error) {
|
||||
this.listeners('error').length > 0 && this.emit('error', error);
|
||||
throw error;
|
||||
}
|
||||
this.emit('close');
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this cursor as destroyed. Will stop streaming and subsequent calls to
|
||||
* `next()` will error.
|
||||
*
|
||||
* @return {this}
|
||||
* @api private
|
||||
* @method _destroy
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype._destroy = function _destroy(_err, callback) {
|
||||
let waitForCursor = null;
|
||||
if (!this.cursor) {
|
||||
waitForCursor = new Promise((resolve) => {
|
||||
this.once('cursor', resolve);
|
||||
});
|
||||
} else {
|
||||
waitForCursor = Promise.resolve();
|
||||
}
|
||||
|
||||
waitForCursor
|
||||
.then(() => this.cursor.close())
|
||||
.then(() => {
|
||||
this._closed = true;
|
||||
callback();
|
||||
})
|
||||
.catch(error => {
|
||||
callback(error);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the next document from this cursor. Will return `null` when there are
|
||||
* no documents left.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method next
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype.next = async function next() {
|
||||
if (typeof arguments[0] === 'function') {
|
||||
throw new MongooseError('AggregationCursor.prototype.next() no longer accepts a callback');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
_next(this, (err, res) => {
|
||||
if (err != null) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute `fn` for every document in the cursor. If `fn` returns a promise,
|
||||
* will wait for the promise to resolve before iterating on to the next one.
|
||||
* Returns a promise that resolves when done.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @param {object} [options]
|
||||
* @param {number} [options.parallel] the number of promises to execute in parallel. Defaults to 1.
|
||||
* @param {number} [options.batchSize=null] if set, Mongoose will call `fn` with an array of at most `batchSize` documents, instead of a single document
|
||||
* @param {boolean} [options.continueOnError=false] if true, `eachAsync()` iterates through all docs even if `fn` throws an error. If false, `eachAsync()` throws an error immediately if the given function `fn()` throws an error.
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method eachAsync
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype.eachAsync = function(fn, opts) {
|
||||
if (typeof arguments[2] === 'function') {
|
||||
throw new MongooseError('AggregationCursor.prototype.eachAsync() no longer accepts a callback');
|
||||
}
|
||||
const _this = this;
|
||||
if (typeof opts === 'function') {
|
||||
opts = {};
|
||||
}
|
||||
opts = opts || {};
|
||||
|
||||
return eachAsync(function(cb) { return _next(_this, cb); }, fn, opts);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js)
|
||||
* You do not need to call this function explicitly, the JavaScript runtime
|
||||
* will call it for you.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Async iterator without explicitly calling `cursor()`. Mongoose still
|
||||
* // creates an AggregationCursor instance internally.
|
||||
* const agg = Model.aggregate([{ $match: { age: { $gte: 25 } } }]);
|
||||
* for await (const doc of agg) {
|
||||
* console.log(doc.name);
|
||||
* }
|
||||
*
|
||||
* // You can also use an AggregationCursor instance for async iteration
|
||||
* const cursor = Model.aggregate([{ $match: { age: { $gte: 25 } } }]).cursor();
|
||||
* for await (const doc of cursor) {
|
||||
* console.log(doc.name);
|
||||
* }
|
||||
*
|
||||
* Node.js 10.x supports async iterators natively without any flags. You can
|
||||
* enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
|
||||
*
|
||||
* **Note:** This function is not set if `Symbol.asyncIterator` is undefined. If
|
||||
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
||||
* support async iterators.
|
||||
*
|
||||
* @method [Symbol.asyncIterator]
|
||||
* @memberOf AggregationCursor
|
||||
* @instance
|
||||
* @api public
|
||||
*/
|
||||
|
||||
if (Symbol.asyncIterator != null) {
|
||||
AggregationCursor.prototype[Symbol.asyncIterator] = function() {
|
||||
return this.transformNull()._transformForAsyncIterator();
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype._transformForAsyncIterator = function() {
|
||||
if (this._transforms.indexOf(_transformForAsyncIterator) === -1) {
|
||||
this.map(_transformForAsyncIterator);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype.transformNull = function(val) {
|
||||
if (arguments.length === 0) {
|
||||
val = true;
|
||||
}
|
||||
this._mongooseOptions.transformNull = val;
|
||||
return this;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _transformForAsyncIterator(doc) {
|
||||
return doc == null ? { done: true } : { value: doc, done: false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a [cursor flag](https://mongodb.github.io/node-mongodb-native/7.0/classes/AggregationCursor.html#addCursorFlag).
|
||||
* Useful for setting the `noCursorTimeout` and `tailable` flags.
|
||||
*
|
||||
* @param {'tailable'|'oplogReplay'|'noCursorTimeout'|'awaitData'|'partial'} flag
|
||||
* @param {boolean} value
|
||||
* @return {AggregationCursor} this
|
||||
* @api public
|
||||
* @method addCursorFlag
|
||||
*/
|
||||
|
||||
AggregationCursor.prototype.addCursorFlag = function(flag, value) {
|
||||
const _this = this;
|
||||
_waitForCursor(this, function() {
|
||||
_this.cursor.addCursorFlag(flag, value);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _waitForCursor(ctx, cb) {
|
||||
if (ctx.cursor) {
|
||||
return cb();
|
||||
}
|
||||
ctx.once('cursor', function() {
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next doc from the underlying cursor and mongooseify it
|
||||
* (populate, etc.)
|
||||
* @param {any} ctx
|
||||
* @param {Function} cb
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function _next(ctx, cb) {
|
||||
let callback = cb;
|
||||
if (ctx._transforms.length) {
|
||||
callback = function(err, doc) {
|
||||
if (err || (doc === null && !ctx._mongooseOptions.transformNull)) {
|
||||
return cb(err, doc);
|
||||
}
|
||||
cb(err, ctx._transforms.reduce(function(doc, fn) {
|
||||
return fn(doc);
|
||||
}, doc));
|
||||
};
|
||||
}
|
||||
|
||||
if (ctx._error) {
|
||||
return immediate(function() {
|
||||
callback(ctx._error);
|
||||
});
|
||||
}
|
||||
|
||||
if (ctx.cursor) {
|
||||
return ctx.cursor.next().then(
|
||||
doc => {
|
||||
if (!doc) {
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
callback(null, doc);
|
||||
},
|
||||
err => callback(err)
|
||||
);
|
||||
} else {
|
||||
ctx.once('error', cb);
|
||||
ctx.once('cursor', function() {
|
||||
_next(ctx, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AggregationCursor;
|
||||
218
backend/node_modules/mongoose/lib/cursor/changeStream.js
generated
vendored
Normal file
218
backend/node_modules/mongoose/lib/cursor/changeStream.js
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const MongooseError = require('../error/mongooseError');
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const driverChangeStreamEvents = ['close', 'change', 'end', 'error', 'resumeTokenChanged'];
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
class ChangeStream extends EventEmitter {
|
||||
constructor(changeStreamPromise, pipeline, options) {
|
||||
super();
|
||||
|
||||
this.driverChangeStream = null;
|
||||
this.closed = false;
|
||||
this.bindedEvents = false;
|
||||
this.pipeline = pipeline;
|
||||
this.options = options;
|
||||
this.errored = false;
|
||||
|
||||
if (options?.hydrate && !options.model) {
|
||||
throw new Error(
|
||||
'Cannot create change stream with `hydrate: true` ' +
|
||||
'unless calling `Model.watch()`'
|
||||
);
|
||||
}
|
||||
|
||||
this.$driverChangeStreamPromise = changeStreamPromise.then(
|
||||
driverChangeStream => {
|
||||
this.driverChangeStream = driverChangeStream;
|
||||
// Use setImmediate so the stream pump (_read) has a chance to run and
|
||||
// the driver cursor initializes before 'ready' resolves. Without this,
|
||||
// changes emitted immediately after 'ready' can be missed because the
|
||||
// underlying cursor hasn't sent its initial aggregate to MongoDB yet.
|
||||
setImmediate(() => this.emit('ready'));
|
||||
return this;
|
||||
},
|
||||
err => {
|
||||
this.errored = true;
|
||||
this.emit('error', err);
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
_bindEvents() {
|
||||
if (this.bindedEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.bindedEvents = true;
|
||||
|
||||
if (this.driverChangeStream == null) {
|
||||
this.$driverChangeStreamPromise.then(
|
||||
() => {
|
||||
this.driverChangeStream.on('close', () => {
|
||||
this.closed = true;
|
||||
});
|
||||
|
||||
driverChangeStreamEvents.forEach(ev => {
|
||||
this.driverChangeStream.on(ev, data => {
|
||||
if (data?.fullDocument != null && this.options?.hydrate) {
|
||||
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
||||
}
|
||||
this.emit(ev, data);
|
||||
});
|
||||
});
|
||||
},
|
||||
() => {} // No need to register events if opening change stream failed
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.driverChangeStream.on('close', () => {
|
||||
this.closed = true;
|
||||
});
|
||||
|
||||
driverChangeStreamEvents.forEach(ev => {
|
||||
this.driverChangeStream.on(ev, data => {
|
||||
if (data?.fullDocument != null && this.options?.hydrate) {
|
||||
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
||||
}
|
||||
this.emit(ev, data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hasNext(cb) {
|
||||
if (this.errored) {
|
||||
throw new MongooseError('Cannot call hasNext() on errored ChangeStream');
|
||||
}
|
||||
|
||||
if (this.driverChangeStream != null) {
|
||||
return this.driverChangeStream.hasNext(cb);
|
||||
}
|
||||
|
||||
return this.$driverChangeStreamPromise.then(
|
||||
() => this.driverChangeStream.hasNext(cb),
|
||||
err => {
|
||||
if (cb != null) {
|
||||
return cb(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
next(cb) {
|
||||
if (this.errored) {
|
||||
throw new MongooseError('Cannot call next() on errored ChangeStream');
|
||||
}
|
||||
if (this.options?.hydrate) {
|
||||
if (cb != null) {
|
||||
const originalCb = cb;
|
||||
cb = (err, data) => {
|
||||
if (err != null) {
|
||||
return originalCb(err);
|
||||
}
|
||||
if (data.fullDocument != null) {
|
||||
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
||||
}
|
||||
return originalCb(null, data);
|
||||
};
|
||||
}
|
||||
|
||||
let maybePromise;
|
||||
if (this.driverChangeStream != null) {
|
||||
maybePromise = this.driverChangeStream.next(cb);
|
||||
} else {
|
||||
maybePromise = this.$driverChangeStreamPromise.then(
|
||||
() => this.driverChangeStream.next(cb),
|
||||
err => {
|
||||
if (cb != null) {
|
||||
return cb(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
if (typeof maybePromise?.then === 'function') {
|
||||
maybePromise = maybePromise.then(data => {
|
||||
if (data.fullDocument != null) {
|
||||
data.fullDocument = this.options.model.hydrate(data.fullDocument);
|
||||
}
|
||||
return data;
|
||||
});
|
||||
}
|
||||
return maybePromise;
|
||||
}
|
||||
|
||||
if (this.driverChangeStream != null) {
|
||||
return this.driverChangeStream.next(cb);
|
||||
}
|
||||
|
||||
return this.$driverChangeStreamPromise.then(
|
||||
() => this.driverChangeStream.next(cb),
|
||||
err => {
|
||||
if (cb != null) {
|
||||
return cb(err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
addListener(event, handler) {
|
||||
if (this.errored) {
|
||||
throw new MongooseError('Cannot call addListener() on errored ChangeStream');
|
||||
}
|
||||
this._bindEvents();
|
||||
return super.addListener(event, handler);
|
||||
}
|
||||
|
||||
on(event, handler) {
|
||||
if (this.errored) {
|
||||
throw new MongooseError('Cannot call on() on errored ChangeStream');
|
||||
}
|
||||
this._bindEvents();
|
||||
return super.on(event, handler);
|
||||
}
|
||||
|
||||
once(event, handler) {
|
||||
if (this.errored) {
|
||||
throw new MongooseError('Cannot call once() on errored ChangeStream');
|
||||
}
|
||||
this._bindEvents();
|
||||
return super.once(event, handler);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.closed = true;
|
||||
if (this.driverChangeStream) {
|
||||
return this.driverChangeStream.close();
|
||||
} else {
|
||||
return this.$driverChangeStreamPromise.then(
|
||||
() => this.driverChangeStream.close(),
|
||||
() => {} // No need to close if opening the change stream failed
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = ChangeStream;
|
||||
625
backend/node_modules/mongoose/lib/cursor/queryCursor.js
generated
vendored
Normal file
625
backend/node_modules/mongoose/lib/cursor/queryCursor.js
generated
vendored
Normal file
@@ -0,0 +1,625 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('../error/mongooseError');
|
||||
const Readable = require('stream').Readable;
|
||||
const eachAsync = require('../helpers/cursor/eachAsync');
|
||||
const helpers = require('../queryHelpers');
|
||||
const kareem = require('kareem');
|
||||
const immediate = require('../helpers/immediate');
|
||||
const { once } = require('events');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* A QueryCursor is a concurrency primitive for processing query results
|
||||
* one document at a time. A QueryCursor fulfills the Node.js streams3 API,
|
||||
* in addition to several other mechanisms for loading documents from MongoDB
|
||||
* one at a time.
|
||||
*
|
||||
* QueryCursors execute the model's pre `find` hooks before loading any documents
|
||||
* from MongoDB, and the model's post `find` hooks after loading each document.
|
||||
*
|
||||
* Unless you're an advanced user, do **not** instantiate this class directly.
|
||||
* Use [`Query#cursor()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.cursor()) instead.
|
||||
*
|
||||
* @param {Query} query
|
||||
* @param {object} options query options passed to `.find()`
|
||||
* @inherits Readable https://nodejs.org/api/stream.html#class-streamreadable
|
||||
* @event `cursor`: Emitted when the cursor is created
|
||||
* @event `error`: Emitted when an error occurred
|
||||
* @event `data`: Emitted when the stream is flowing and the next doc is ready
|
||||
* @event `end`: Emitted when the stream is exhausted
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function QueryCursor(query) {
|
||||
// set autoDestroy=true because on node 12 it's by default false
|
||||
// gh-10902 need autoDestroy to destroy correctly and emit 'close' event
|
||||
Readable.call(this, { autoDestroy: true, objectMode: true });
|
||||
|
||||
this.cursor = null;
|
||||
this.skipped = false;
|
||||
this.query = query;
|
||||
this._closed = false;
|
||||
const model = query.model;
|
||||
this._mongooseOptions = {};
|
||||
this._transforms = [];
|
||||
this.model = model;
|
||||
this.options = {};
|
||||
|
||||
const onPreComplete = (err) => {
|
||||
if (err != null) {
|
||||
if (err instanceof kareem.skipWrappedFunction) {
|
||||
const resultValue = err.args[0];
|
||||
if (resultValue != null && (!Array.isArray(resultValue) || resultValue.length)) {
|
||||
const err = new MongooseError(
|
||||
'Cannot `skipMiddlewareFunction()` with a value when using ' +
|
||||
'`.find().cursor()`, value must be nullish or empty array, got "' +
|
||||
util.inspect(resultValue) +
|
||||
'".'
|
||||
);
|
||||
this._markError(err);
|
||||
this.listeners('error').length > 0 && this.emit('error', err);
|
||||
return;
|
||||
}
|
||||
this.skipped = true;
|
||||
this.emit('cursor', null);
|
||||
return;
|
||||
}
|
||||
this._markError(err);
|
||||
this.listeners('error').length > 0 && this.emit('error', err);
|
||||
return;
|
||||
}
|
||||
Object.assign(this.options, query._optionsForExec());
|
||||
this._transforms = this._transforms.concat(query._transforms.slice());
|
||||
if (this.options.transform) {
|
||||
this._transforms.push(this.options.transform);
|
||||
}
|
||||
// Re: gh-8039, you need to set the `cursor.batchSize` option, top-level
|
||||
// `batchSize` option doesn't work.
|
||||
if (this.options.batchSize) {
|
||||
// Max out the number of documents we'll populate in parallel at 5000.
|
||||
this.options._populateBatchSize = Math.min(this.options.batchSize, 5000);
|
||||
}
|
||||
if (query._mongooseOptions._asyncIterator) {
|
||||
this._mongooseOptions._asyncIterator = true;
|
||||
}
|
||||
|
||||
if (model.collection._shouldBufferCommands() && model.collection.buffer) {
|
||||
model.collection.queue.push([
|
||||
() => _getRawCursor(query, this)
|
||||
]);
|
||||
} else {
|
||||
_getRawCursor(query, this);
|
||||
}
|
||||
};
|
||||
|
||||
model.hooks.execPre('find', query).then(() => onPreComplete(null), err => onPreComplete(err));
|
||||
}
|
||||
|
||||
util.inherits(QueryCursor, Readable);
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _getRawCursor(query, queryCursor) {
|
||||
try {
|
||||
const cursor = query.model.collection.find(query._conditions, queryCursor.options);
|
||||
queryCursor.cursor = cursor;
|
||||
queryCursor.emit('cursor', cursor);
|
||||
} catch (err) {
|
||||
queryCursor._markError(err);
|
||||
queryCursor.listeners('error').length > 0 && queryCursor.emit('error', queryCursor._error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Necessary to satisfy the Readable API
|
||||
* @method _read
|
||||
* @memberOf QueryCursor
|
||||
* @instance
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryCursor.prototype._read = function() {
|
||||
_next(this, (error, doc) => {
|
||||
if (error) {
|
||||
return this.emit('error', error);
|
||||
}
|
||||
if (!doc) {
|
||||
this.push(null);
|
||||
this.cursor.close((error) => {
|
||||
if (error) {
|
||||
return this.emit('error', error);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.push(doc);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the underlying cursor from the MongoDB Node driver that this cursor uses.
|
||||
*
|
||||
* @method getDriverCursor
|
||||
* @memberOf QueryCursor
|
||||
* @returns {Cursor} MongoDB Node driver cursor instance
|
||||
* @instance
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.getDriverCursor = async function getDriverCursor() {
|
||||
if (this.cursor) {
|
||||
return this.cursor;
|
||||
}
|
||||
|
||||
await once(this, 'cursor');
|
||||
return this.cursor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers a transform function which subsequently maps documents retrieved
|
||||
* via the streams interface or `.next()`
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Map documents returned by `data` events
|
||||
* Thing.
|
||||
* find({ name: /^hello/ }).
|
||||
* cursor().
|
||||
* map(function (doc) {
|
||||
* doc.foo = "bar";
|
||||
* return doc;
|
||||
* })
|
||||
* on('data', function(doc) { console.log(doc.foo); });
|
||||
*
|
||||
* // Or map documents returned by `.next()`
|
||||
* const cursor = Thing.find({ name: /^hello/ }).
|
||||
* cursor().
|
||||
* map(function (doc) {
|
||||
* doc.foo = "bar";
|
||||
* return doc;
|
||||
* });
|
||||
* cursor.next(function(error, doc) {
|
||||
* console.log(doc.foo);
|
||||
* });
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {QueryCursor}
|
||||
* @memberOf QueryCursor
|
||||
* @api public
|
||||
* @method map
|
||||
*/
|
||||
|
||||
Object.defineProperty(QueryCursor.prototype, 'map', {
|
||||
value: function(fn) {
|
||||
this._transforms.push(fn);
|
||||
return this;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
writable: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Marks this cursor as errored
|
||||
* @method _markError
|
||||
* @memberOf QueryCursor
|
||||
* @instance
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryCursor.prototype._markError = function(error) {
|
||||
this._error = error;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this cursor as closed. Will stop streaming and subsequent calls to
|
||||
* `next()` will error.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method close
|
||||
* @emits close
|
||||
* @see AggregationCursor.close https://mongodb.github.io/node-mongodb-native/7.0/classes/AggregationCursor.html#close
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.close = async function close() {
|
||||
if (typeof arguments[0] === 'function') {
|
||||
throw new MongooseError('QueryCursor.prototype.close() no longer accepts a callback');
|
||||
}
|
||||
try {
|
||||
await this.cursor.close();
|
||||
this._closed = true;
|
||||
this.emit('close');
|
||||
} catch (error) {
|
||||
this.listeners('error').length > 0 && this.emit('error', error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this cursor as destroyed. Will stop streaming and subsequent calls to
|
||||
* `next()` will error.
|
||||
*
|
||||
* @return {this}
|
||||
* @api private
|
||||
* @method _destroy
|
||||
*/
|
||||
|
||||
QueryCursor.prototype._destroy = function _destroy(_err, callback) {
|
||||
let waitForCursor = null;
|
||||
if (!this.cursor) {
|
||||
waitForCursor = new Promise((resolve) => {
|
||||
this.once('cursor', resolve);
|
||||
});
|
||||
} else {
|
||||
waitForCursor = Promise.resolve();
|
||||
}
|
||||
|
||||
waitForCursor
|
||||
.then(() => {
|
||||
this.cursor.close();
|
||||
})
|
||||
.then(() => {
|
||||
this._closed = true;
|
||||
callback();
|
||||
})
|
||||
.catch(error => {
|
||||
callback(error);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewind this cursor to its uninitialized state. Any options that are present on the cursor will
|
||||
* remain in effect. Iterating this cursor will cause new queries to be sent to the server, even
|
||||
* if the resultant data has already been retrieved by this cursor.
|
||||
*
|
||||
* @return {AggregationCursor} this
|
||||
* @api public
|
||||
* @method rewind
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.rewind = function() {
|
||||
_waitForCursor(this, () => {
|
||||
this.cursor.rewind();
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the next document from this cursor. Will return `null` when there are
|
||||
* no documents left.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method next
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.next = async function next() {
|
||||
if (typeof arguments[0] === 'function') {
|
||||
throw new MongooseError('QueryCursor.prototype.next() no longer accepts a callback');
|
||||
}
|
||||
if (this._closed) {
|
||||
throw new MongooseError('Cannot call `next()` on a closed cursor');
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
_next(this, function(error, doc) {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
resolve(doc);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute `fn` for every document in the cursor. If `fn` returns a promise,
|
||||
* will wait for the promise to resolve before iterating on to the next one.
|
||||
* Returns a promise that resolves when done.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Iterate over documents asynchronously
|
||||
* Thing.
|
||||
* find({ name: /^hello/ }).
|
||||
* cursor().
|
||||
* eachAsync(async function (doc, i) {
|
||||
* doc.foo = doc.bar + i;
|
||||
* await doc.save();
|
||||
* })
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @param {object} [options]
|
||||
* @param {number} [options.parallel] the number of promises to execute in parallel. Defaults to 1.
|
||||
* @param {number} [options.batchSize] if set, will call `fn()` with arrays of documents with length at most `batchSize`
|
||||
* @param {boolean} [options.continueOnError=false] if true, `eachAsync()` iterates through all docs even if `fn` throws an error. If false, `eachAsync()` throws an error immediately if the given function `fn()` throws an error.
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method eachAsync
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.eachAsync = function(fn, opts) {
|
||||
if (typeof arguments[2] === 'function') {
|
||||
throw new MongooseError('QueryCursor.prototype.eachAsync() no longer accepts a callback');
|
||||
}
|
||||
if (typeof opts === 'function') {
|
||||
opts = {};
|
||||
}
|
||||
opts = opts || {};
|
||||
|
||||
return eachAsync((cb) => _next(this, cb), fn, opts);
|
||||
};
|
||||
|
||||
/**
|
||||
* The `options` passed in to the `QueryCursor` constructor.
|
||||
*
|
||||
* @api public
|
||||
* @property options
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.options;
|
||||
|
||||
/**
|
||||
* Adds a [cursor flag](https://mongodb.github.io/node-mongodb-native/7.0/classes/FindCursor.html#addCursorFlag).
|
||||
* Useful for setting the `noCursorTimeout` and `tailable` flags.
|
||||
*
|
||||
* @param {'tailable'|'oplogReplay'|'noCursorTimeout'|'awaitData'|'partial'} flag
|
||||
* @param {boolean} value
|
||||
* @return {AggregationCursor} this
|
||||
* @api public
|
||||
* @method addCursorFlag
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.addCursorFlag = function(flag, value) {
|
||||
_waitForCursor(this, () => {
|
||||
this.cursor.addCursorFlag(flag, value);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an asyncIterator for use with [`for/await/of` loops](https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js).
|
||||
* You do not need to call this function explicitly, the JavaScript runtime
|
||||
* will call it for you.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Works without using `cursor()`
|
||||
* for await (const doc of Model.find([{ $sort: { name: 1 } }])) {
|
||||
* console.log(doc.name);
|
||||
* }
|
||||
*
|
||||
* // Can also use `cursor()`
|
||||
* for await (const doc of Model.find([{ $sort: { name: 1 } }]).cursor()) {
|
||||
* console.log(doc.name);
|
||||
* }
|
||||
*
|
||||
* Node.js 10.x supports async iterators natively without any flags. You can
|
||||
* enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
|
||||
*
|
||||
* **Note:** This function is not if `Symbol.asyncIterator` is undefined. If
|
||||
* `Symbol.asyncIterator` is undefined, that means your Node.js version does not
|
||||
* support async iterators.
|
||||
*
|
||||
* @method [Symbol.asyncIterator]
|
||||
* @memberOf QueryCursor
|
||||
* @instance
|
||||
* @api public
|
||||
*/
|
||||
|
||||
if (Symbol.asyncIterator != null) {
|
||||
QueryCursor.prototype[Symbol.asyncIterator] = function queryCursorAsyncIterator() {
|
||||
// Set so QueryCursor knows it should transform results for async iterators into `{ value, done }` syntax
|
||||
this._mongooseOptions._asyncIterator = true;
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next doc from the underlying cursor and mongooseify it
|
||||
* (populate, etc.)
|
||||
* @param {any} ctx
|
||||
* @param {Function} cb
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function _next(ctx, cb) {
|
||||
let callback = cb;
|
||||
|
||||
// Create a custom callback to handle transforms, async iterator, and transformNull
|
||||
callback = function(err, doc) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
// Handle null documents - if asyncIterator, we need to return `done: true`, otherwise just
|
||||
// skip. In either case, avoid transforms.
|
||||
if (doc === null) {
|
||||
if (ctx._mongooseOptions._asyncIterator) {
|
||||
return cb(null, { done: true });
|
||||
} else {
|
||||
return cb(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply transforms
|
||||
if (ctx._transforms.length && doc !== null) {
|
||||
doc = ctx._transforms.reduce(function(doc, fn) {
|
||||
return fn.call(ctx, doc);
|
||||
}, doc);
|
||||
}
|
||||
|
||||
// This option is set in `Symbol.asyncIterator` code paths.
|
||||
// For async iterator, we need to convert to {value, done} format
|
||||
if (ctx._mongooseOptions._asyncIterator) {
|
||||
return cb(null, { value: doc, done: false });
|
||||
}
|
||||
|
||||
return cb(null, doc);
|
||||
};
|
||||
|
||||
if (ctx._error) {
|
||||
return immediate(function() {
|
||||
callback(ctx._error);
|
||||
});
|
||||
}
|
||||
if (ctx.skipped) {
|
||||
return immediate(() => callback(null, null));
|
||||
}
|
||||
|
||||
if (ctx.cursor) {
|
||||
if (ctx.query._mongooseOptions.populate && !ctx._pop) {
|
||||
ctx._pop = helpers.preparePopulationOptionsMQ(ctx.query,
|
||||
ctx.query._mongooseOptions);
|
||||
ctx._pop.__noPromise = true;
|
||||
}
|
||||
if (ctx.query._mongooseOptions.populate && ctx.options._populateBatchSize > 1) {
|
||||
if (ctx._batchDocs && ctx._batchDocs.length) {
|
||||
// Return a cached populated doc
|
||||
return _nextDoc(ctx, ctx._batchDocs.shift(), ctx._pop, callback);
|
||||
} else if (ctx._batchExhausted) {
|
||||
// Internal cursor reported no more docs. Act the same here
|
||||
return callback(null, null);
|
||||
} else {
|
||||
// Request as many docs as batchSize, to populate them also in batch
|
||||
ctx._batchDocs = [];
|
||||
ctx.cursor.next().then(
|
||||
res => { _onNext.call({ ctx, callback }, null, res); },
|
||||
err => { _onNext.call({ ctx, callback }, err); }
|
||||
);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return ctx.cursor.next().then(
|
||||
doc => {
|
||||
if (!doc) {
|
||||
callback(null, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctx.query._mongooseOptions.populate) {
|
||||
return _nextDoc(ctx, doc, null, callback);
|
||||
}
|
||||
|
||||
_nextDoc(ctx, doc, ctx._pop, (err, doc) => {
|
||||
if (err != null) {
|
||||
return callback(err);
|
||||
}
|
||||
ctx.query.model.populate(doc, ctx._pop).then(
|
||||
doc => callback(null, doc),
|
||||
err => callback(err)
|
||||
);
|
||||
});
|
||||
},
|
||||
error => {
|
||||
callback(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
ctx.once('error', cb);
|
||||
|
||||
ctx.once('cursor', function(cursor) {
|
||||
ctx.removeListener('error', cb);
|
||||
if (cursor == null) {
|
||||
if (ctx.skipped) {
|
||||
return cb(null, null);
|
||||
}
|
||||
return;
|
||||
}
|
||||
_next(ctx, cb);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _onNext(error, doc) {
|
||||
if (error) {
|
||||
return this.callback(error);
|
||||
}
|
||||
if (!doc) {
|
||||
this.ctx._batchExhausted = true;
|
||||
return _populateBatch.call(this);
|
||||
}
|
||||
|
||||
this.ctx._batchDocs.push(doc);
|
||||
|
||||
if (this.ctx._batchDocs.length < this.ctx.options._populateBatchSize) {
|
||||
// If both `batchSize` and `_populateBatchSize` are huge, calling `next()` repeatedly may
|
||||
// cause a stack overflow. So make sure we clear the stack.
|
||||
immediate(() => this.ctx.cursor.next().then(
|
||||
res => { _onNext.call(this, null, res); },
|
||||
err => { _onNext.call(this, err); }
|
||||
));
|
||||
} else {
|
||||
_populateBatch.call(this);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _populateBatch() {
|
||||
if (!this.ctx._batchDocs.length) {
|
||||
return this.callback(null, null);
|
||||
}
|
||||
this.ctx.query.model.populate(this.ctx._batchDocs, this.ctx._pop).then(
|
||||
() => {
|
||||
_nextDoc(this.ctx, this.ctx._batchDocs.shift(), this.ctx._pop, this.callback);
|
||||
},
|
||||
err => {
|
||||
this.callback(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _nextDoc(ctx, doc, pop, callback) {
|
||||
if (ctx.query._mongooseOptions.lean) {
|
||||
return ctx.model.hooks.execPost('find', ctx.query, [[doc]]).then(() => callback(null, doc), err => callback(err));
|
||||
}
|
||||
|
||||
const { model, _fields, _userProvidedFields, options } = ctx.query;
|
||||
helpers.createModelAndInit(model, doc, _fields, _userProvidedFields, options, pop, (err, doc) => {
|
||||
if (err != null) {
|
||||
return callback(err);
|
||||
}
|
||||
if (options.session != null) {
|
||||
doc.$session(options.session);
|
||||
}
|
||||
ctx.model.hooks.execPost('find', ctx.query, [[doc]]).then(() => callback(null, doc), err => callback(err));
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _waitForCursor(ctx, cb) {
|
||||
if (ctx.cursor) {
|
||||
return cb();
|
||||
}
|
||||
ctx.once('cursor', function(cursor) {
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = QueryCursor;
|
||||
5599
backend/node_modules/mongoose/lib/document.js
generated
vendored
Normal file
5599
backend/node_modules/mongoose/lib/document.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
15
backend/node_modules/mongoose/lib/driver.js
generated
vendored
Normal file
15
backend/node_modules/mongoose/lib/driver.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
let driver = null;
|
||||
|
||||
module.exports.get = function() {
|
||||
return driver;
|
||||
};
|
||||
|
||||
module.exports.set = function(v) {
|
||||
driver = v;
|
||||
};
|
||||
4
backend/node_modules/mongoose/lib/drivers/SPEC.md
generated
vendored
Normal file
4
backend/node_modules/mongoose/lib/drivers/SPEC.md
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
# Driver Spec
|
||||
|
||||
TODO
|
||||
5
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/bulkWriteResult.js
generated
vendored
Normal file
5
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/bulkWriteResult.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const BulkWriteResult = require('mongodb/lib/bulk/common').BulkWriteResult;
|
||||
|
||||
module.exports = BulkWriteResult;
|
||||
393
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
Normal file
393
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
Normal file
@@ -0,0 +1,393 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseCollection = require('../../collection');
|
||||
const MongooseError = require('../../error/mongooseError');
|
||||
const Collection = require('mongodb').Collection;
|
||||
const ObjectId = require('../../types/objectid');
|
||||
const getConstructorName = require('../../helpers/getConstructorName');
|
||||
const internalToObjectOptions = require('../../options').internalToObjectOptions;
|
||||
const stream = require('stream');
|
||||
const util = require('util');
|
||||
|
||||
const formatToObjectOptions = Object.freeze({ ...internalToObjectOptions, copyTrustedSymbol: false });
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
|
||||
*
|
||||
* All methods methods from the [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver are copied and wrapped in queue management.
|
||||
*
|
||||
* @inherits Collection https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function NativeCollection(name, conn, options) {
|
||||
this.collection = null;
|
||||
this.Promise = options.Promise || Promise;
|
||||
this.modelName = options.modelName;
|
||||
delete options.modelName;
|
||||
this._closed = false;
|
||||
MongooseCollection.apply(this, arguments);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from abstract Collection.
|
||||
*/
|
||||
|
||||
Object.setPrototypeOf(NativeCollection.prototype, MongooseCollection.prototype);
|
||||
|
||||
/**
|
||||
* Called when the connection opens.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onOpen = function() {
|
||||
this.collection = this.conn.db.collection(this.name);
|
||||
MongooseCollection.prototype.onOpen.call(this);
|
||||
return this.collection;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the connection closes
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onClose = function(force) {
|
||||
MongooseCollection.prototype.onClose.call(this, force);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to get the collection, in case `this.collection` isn't set yet.
|
||||
* May happen if `bufferCommands` is false and created the model when
|
||||
* Mongoose was disconnected.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype._getCollection = function _getCollection() {
|
||||
if (this.collection) {
|
||||
return this.collection;
|
||||
}
|
||||
if (this.conn.db != null) {
|
||||
this.collection = this.conn.db.collection(this.name);
|
||||
return this.collection;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Copy the collection methods and make them subject to queues
|
||||
* @param {number|string} I
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function iter(i) {
|
||||
NativeCollection.prototype[i] = function() {
|
||||
const collection = this._getCollection();
|
||||
const args = Array.from(arguments);
|
||||
const _this = this;
|
||||
const globalDebug = _this?.conn?.base?.options?.debug;
|
||||
const connectionDebug = _this?.conn?.options?.debug;
|
||||
const debug = connectionDebug == null ? globalDebug : connectionDebug;
|
||||
const opId = new ObjectId();
|
||||
|
||||
// If user force closed, queueing will hang forever. See #5664
|
||||
if (this.conn.$wasForceClosed) {
|
||||
const error = new MongooseError('Connection was force closed');
|
||||
if (args.length > 0 &&
|
||||
typeof args[args.length - 1] === 'function') {
|
||||
args[args.length - 1](error);
|
||||
return;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
let timeout = null;
|
||||
let waitForBufferPromise = null;
|
||||
if (this._shouldBufferCommands() && this.buffer) {
|
||||
this.conn.emit('buffer', {
|
||||
_id: opId,
|
||||
modelName: _this.modelName,
|
||||
collectionName: _this.name,
|
||||
method: i,
|
||||
args: args
|
||||
});
|
||||
|
||||
const bufferTimeoutMS = this._getBufferTimeoutMS();
|
||||
waitForBufferPromise = new Promise((resolve, reject) => {
|
||||
this.addQueue(resolve);
|
||||
|
||||
timeout = setTimeout(() => {
|
||||
const removed = this.removeQueue(resolve);
|
||||
if (removed) {
|
||||
const message = 'Operation `' + this.name + '.' + i + '()` buffering timed out after ' +
|
||||
bufferTimeoutMS + 'ms';
|
||||
const err = new MongooseError(message);
|
||||
this.conn.emit('buffer-end', { _id: opId, modelName: _this.modelName, collectionName: _this.name, method: i, error: err });
|
||||
reject(err);
|
||||
}
|
||||
}, bufferTimeoutMS);
|
||||
});
|
||||
|
||||
return waitForBufferPromise.then(() => {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
return this[i].apply(this, args);
|
||||
});
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
if (typeof debug === 'function') {
|
||||
let argsToAdd = null;
|
||||
if (typeof args[args.length - 1] == 'function') {
|
||||
argsToAdd = args.slice(0, args.length - 1);
|
||||
} else {
|
||||
argsToAdd = args;
|
||||
}
|
||||
debug.apply(_this,
|
||||
[_this.name, i].concat(argsToAdd));
|
||||
} else if (debug instanceof stream.Writable) {
|
||||
this.$printToStream(_this.name, i, args, debug);
|
||||
} else {
|
||||
const color = debug.color == null ? true : debug.color;
|
||||
const shell = debug.shell == null ? false : debug.shell;
|
||||
this.$print(_this.name, i, args, color, shell);
|
||||
}
|
||||
}
|
||||
|
||||
this.conn.emit('operation-start', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, params: args });
|
||||
|
||||
try {
|
||||
if (collection == null) {
|
||||
const message = 'Cannot call `' + this.name + '.' + i + '()` before initial connection ' +
|
||||
'is complete if `bufferCommands = false`. Make sure you `await mongoose.connect()` if ' +
|
||||
'you have `bufferCommands = false`.';
|
||||
throw new MongooseError(message);
|
||||
}
|
||||
|
||||
const ret = collection[i].apply(collection, args);
|
||||
if (typeof ret?.then === 'function') {
|
||||
return ret.then(
|
||||
result => {
|
||||
if (timeout != null) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result });
|
||||
return result;
|
||||
},
|
||||
error => {
|
||||
if (timeout != null) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error });
|
||||
throw error;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, result: ret });
|
||||
if (timeout != null) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
return ret;
|
||||
} catch (error) {
|
||||
if (timeout != null) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for (const key of Object.getOwnPropertyNames(Collection.prototype)) {
|
||||
// Janky hack to work around gh-3005 until we can get rid of the mongoose
|
||||
// collection abstraction
|
||||
const descriptor = Object.getOwnPropertyDescriptor(Collection.prototype, key);
|
||||
// Skip properties with getters because they may throw errors (gh-8528)
|
||||
if (descriptor.get !== undefined) {
|
||||
continue;
|
||||
}
|
||||
if (typeof Collection.prototype[key] !== 'function') {
|
||||
continue;
|
||||
}
|
||||
|
||||
iter(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug print helper
|
||||
*
|
||||
* @api public
|
||||
* @method $print
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.$print = function(name, i, args, color, shell) {
|
||||
const moduleName = color ? '\x1B[0;36mMongoose:\x1B[0m ' : 'Mongoose: ';
|
||||
const functionCall = [name, i].join('.');
|
||||
const _args = [];
|
||||
for (let j = args.length - 1; j >= 0; --j) {
|
||||
if (this.$format(args[j]) || _args.length) {
|
||||
_args.unshift(this.$format(args[j], color, shell));
|
||||
}
|
||||
}
|
||||
const params = '(' + _args.join(', ') + ')';
|
||||
|
||||
console.info(moduleName + functionCall + params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Debug print helper
|
||||
*
|
||||
* @api public
|
||||
* @method $print
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.$printToStream = function(name, i, args, stream) {
|
||||
const functionCall = [name, i].join('.');
|
||||
const _args = [];
|
||||
for (let j = args.length - 1; j >= 0; --j) {
|
||||
if (this.$format(args[j]) || _args.length) {
|
||||
_args.unshift(this.$format(args[j]));
|
||||
}
|
||||
}
|
||||
const params = '(' + _args.join(', ') + ')';
|
||||
|
||||
stream.write(functionCall + params, 'utf8');
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for debug print args
|
||||
*
|
||||
* @api public
|
||||
* @method $format
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.$format = function(arg, color, shell) {
|
||||
const type = typeof arg;
|
||||
if (type === 'function' || type === 'undefined') return '';
|
||||
return format(arg, false, color, shell);
|
||||
};
|
||||
|
||||
/**
|
||||
* Debug print helper
|
||||
* @param {any} representation
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function inspectable(representation) {
|
||||
const ret = {
|
||||
inspect: function() { return representation; }
|
||||
};
|
||||
if (util.inspect.custom) {
|
||||
ret[util.inspect.custom] = ret.inspect;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
function map(o) {
|
||||
return format(o, true);
|
||||
}
|
||||
function formatObjectId(x, key) {
|
||||
x[key] = inspectable('ObjectId("' + x[key].toHexString() + '")');
|
||||
}
|
||||
function formatDate(x, key, shell) {
|
||||
if (shell) {
|
||||
x[key] = inspectable('ISODate("' + x[key].toUTCString() + '")');
|
||||
} else {
|
||||
x[key] = inspectable('new Date("' + x[key].toUTCString() + '")');
|
||||
}
|
||||
}
|
||||
function format(obj, sub, color, shell) {
|
||||
if (typeof obj?.toBSON === 'function') {
|
||||
obj = obj.toBSON();
|
||||
}
|
||||
if (obj == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const clone = require('../../helpers/clone');
|
||||
// `sub` indicates `format()` was called recursively, so skip cloning because we already
|
||||
// did a deep clone on the top-level object.
|
||||
let x = sub ? obj : clone(obj, formatToObjectOptions);
|
||||
const constructorName = getConstructorName(x);
|
||||
|
||||
if (constructorName === 'Binary') {
|
||||
x = 'BinData(' + x.sub_type + ', "' + x.toString('base64') + '")';
|
||||
} else if (constructorName === 'ObjectId') {
|
||||
x = inspectable('ObjectId("' + x.toHexString() + '")');
|
||||
} else if (constructorName === 'Date') {
|
||||
x = inspectable('new Date("' + x.toUTCString() + '")');
|
||||
} else if (constructorName === 'Object') {
|
||||
const keys = Object.keys(x);
|
||||
const numKeys = keys.length;
|
||||
let key;
|
||||
for (let i = 0; i < numKeys; ++i) {
|
||||
key = keys[i];
|
||||
if (x[key]) {
|
||||
let error;
|
||||
if (typeof x[key].toBSON === 'function') {
|
||||
try {
|
||||
// `session.toBSON()` throws an error. This means we throw errors
|
||||
// in debug mode when using transactions, see gh-6712. As a
|
||||
// workaround, catch `toBSON()` errors, try to serialize without
|
||||
// `toBSON()`, and rethrow if serialization still fails.
|
||||
x[key] = x[key].toBSON();
|
||||
} catch (_error) {
|
||||
error = _error;
|
||||
}
|
||||
}
|
||||
const _constructorName = getConstructorName(x[key]);
|
||||
if (_constructorName === 'Binary') {
|
||||
x[key] = 'BinData(' + x[key].sub_type + ', "' +
|
||||
x[key].buffer.toString('base64') + '")';
|
||||
} else if (_constructorName === 'Object') {
|
||||
x[key] = format(x[key], true);
|
||||
} else if (_constructorName === 'ObjectId') {
|
||||
formatObjectId(x, key);
|
||||
} else if (_constructorName === 'Date') {
|
||||
formatDate(x, key, shell);
|
||||
} else if (_constructorName === 'ClientSession') {
|
||||
x[key] = inspectable('ClientSession("' +
|
||||
(x[key]?.id?.id?.buffer || '').toString('hex') + '")');
|
||||
} else if (Array.isArray(x[key])) {
|
||||
x[key] = x[key].map(map);
|
||||
} else if (error != null) {
|
||||
// If there was an error with `toBSON()` and the object wasn't
|
||||
// already converted to a string representation, rethrow it.
|
||||
// Open to better ideas on how to handle this.
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sub) {
|
||||
return x;
|
||||
}
|
||||
|
||||
return util.
|
||||
inspect(x, false, 10, color).
|
||||
replace(/\n/g, '').
|
||||
replace(/\s{2,}/g, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information about this collections indexes.
|
||||
*
|
||||
* @method getIndexes
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.getIndexes = NativeCollection.prototype.indexInformation;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = NativeCollection;
|
||||
506
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
Normal file
506
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
Normal file
@@ -0,0 +1,506 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseConnection = require('../../connection');
|
||||
const MongooseError = require('../../error/index');
|
||||
const STATES = require('../../connectionState');
|
||||
const mongodb = require('mongodb');
|
||||
const pkg = require('../../../package.json');
|
||||
const processConnectionOptions = require('../../helpers/processConnectionOptions');
|
||||
const setTimeout = require('../../helpers/timers').setTimeout;
|
||||
const utils = require('../../utils');
|
||||
const Schema = require('../../schema');
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation.
|
||||
*
|
||||
* @inherits Connection
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function NativeConnection() {
|
||||
MongooseConnection.apply(this, arguments);
|
||||
this._listening = false;
|
||||
// Tracks the last time (as unix timestamp) the connection received a
|
||||
// serverHeartbeatSucceeded or serverHeartbeatFailed event from the underlying MongoClient.
|
||||
// If we haven't received one in a while (like due to a frozen AWS Lambda container) then
|
||||
// `readyState` is likely stale.
|
||||
this._lastHeartbeatAt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the possible connection states.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeConnection.STATES = STATES;
|
||||
|
||||
/*!
|
||||
* Inherits from Connection.
|
||||
*/
|
||||
|
||||
Object.setPrototypeOf(NativeConnection.prototype, MongooseConnection.prototype);
|
||||
|
||||
/**
|
||||
* Switches to a different database using the same connection pool.
|
||||
*
|
||||
* Returns a new connection object, with the new db. If you set the `useCache`
|
||||
* option, `useDb()` will cache connections by `name`.
|
||||
*
|
||||
* **Note:** Calling `close()` on a `useDb()` connection will close the base connection as well.
|
||||
*
|
||||
* @param {string} name The database name
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.useCache=false] If true, cache results so calling `useDb()` multiple times with the same name only creates 1 connection object.
|
||||
* @return {Connection} New Connection Object
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.useDb = function(name, options) {
|
||||
// Return immediately if cached
|
||||
options = options || {};
|
||||
if (options.useCache && this.relatedDbs[name]) {
|
||||
return this.relatedDbs[name];
|
||||
}
|
||||
|
||||
// we have to manually copy all of the attributes...
|
||||
const newConn = new this.constructor();
|
||||
newConn.name = name;
|
||||
newConn.base = this.base;
|
||||
newConn.collections = {};
|
||||
newConn.models = {};
|
||||
newConn.replica = this.replica;
|
||||
newConn.config = Object.assign({}, this.config, newConn.config);
|
||||
newConn.name = this.name;
|
||||
newConn.options = this.options;
|
||||
newConn._readyState = this._readyState;
|
||||
newConn._closeCalled = this._closeCalled;
|
||||
newConn._hasOpened = this._hasOpened;
|
||||
newConn._listening = false;
|
||||
newConn._parent = this;
|
||||
|
||||
newConn.host = this.host;
|
||||
newConn.port = this.port;
|
||||
newConn.user = this.user;
|
||||
newConn.pass = this.pass;
|
||||
|
||||
// First, when we create another db object, we are not guaranteed to have a
|
||||
// db object to work with. So, in the case where we have a db object and it
|
||||
// is connected, we can just proceed with setting everything up. However, if
|
||||
// we do not have a db or the state is not connected, then we need to wait on
|
||||
// the 'open' event of the connection before doing the rest of the setup
|
||||
// the 'connected' event is the first time we'll have access to the db object
|
||||
|
||||
const _this = this;
|
||||
|
||||
newConn.client = _this.client;
|
||||
|
||||
if (this.db && this._readyState === STATES.connected) {
|
||||
wireup();
|
||||
} else {
|
||||
this._queue.push({ fn: wireup });
|
||||
}
|
||||
|
||||
function wireup() {
|
||||
newConn.client = _this.client;
|
||||
newConn.db = _this.client.db(name);
|
||||
newConn._lastHeartbeatAt = _this._lastHeartbeatAt;
|
||||
newConn.onOpen();
|
||||
}
|
||||
|
||||
newConn.name = name;
|
||||
|
||||
// push onto the otherDbs stack, this is used when state changes
|
||||
this.otherDbs.push(newConn);
|
||||
newConn.otherDbs.push(this);
|
||||
|
||||
// push onto the relatedDbs cache, this is used when state changes
|
||||
if (options?.useCache) {
|
||||
this.relatedDbs[newConn.name] = newConn;
|
||||
newConn.relatedDbs = this.relatedDbs;
|
||||
}
|
||||
|
||||
return newConn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs a [db-level aggregate()](https://www.mongodb.com/docs/manual/reference/method/db.aggregate/) on this connection's underlying `db`
|
||||
*
|
||||
* @param {Array} pipeline
|
||||
* @param {object} [options]
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.aggregate = function aggregate(pipeline, options) {
|
||||
return new this.base.Aggregate(null, this).append(pipeline).option(options ?? {});
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the database connection with the given name created with `useDb()`.
|
||||
*
|
||||
* Throws an error if the database connection was not found.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* // Connect to `initialdb` first
|
||||
* const conn = await mongoose.createConnection('mongodb://127.0.0.1:27017/initialdb').asPromise();
|
||||
*
|
||||
* // Creates an un-cached connection to `mydb`
|
||||
* const db = conn.useDb('mydb');
|
||||
*
|
||||
* // Closes `db`, and removes `db` from `conn.relatedDbs` and `conn.otherDbs`
|
||||
* await conn.removeDb('mydb');
|
||||
*
|
||||
* @method removeDb
|
||||
* @memberOf Connection
|
||||
* @param {string} name The database name
|
||||
* @return {Connection} this
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.removeDb = function removeDb(name) {
|
||||
const dbs = this.otherDbs.filter(db => db.name === name);
|
||||
if (!dbs.length) {
|
||||
throw new MongooseError(`No connections to database "${name}" found`);
|
||||
}
|
||||
|
||||
for (const db of dbs) {
|
||||
db._closeCalled = true;
|
||||
db._destroyCalled = true;
|
||||
db._readyState = STATES.disconnected;
|
||||
db.$wasForceClosed = true;
|
||||
}
|
||||
delete this.relatedDbs[name];
|
||||
this.otherDbs = this.otherDbs.filter(db => db.name !== name);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the connection
|
||||
*
|
||||
* @param {boolean} [force]
|
||||
* @return {Connection} this
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doClose = async function doClose(force) {
|
||||
if (this.client == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
let skipCloseClient = false;
|
||||
if (force != null && typeof force === 'object') {
|
||||
skipCloseClient = force.skipCloseClient;
|
||||
force = force.force;
|
||||
}
|
||||
|
||||
if (skipCloseClient) {
|
||||
return this;
|
||||
}
|
||||
|
||||
await this.client.close(force);
|
||||
// Defer because the driver will wait at least 1ms before finishing closing
|
||||
// the pool, see https://github.com/mongodb-js/mongodb-core/blob/a8f8e4ce41936babc3b9112bf42d609779f03b39/lib/connection/pool.js#L1026-L1030.
|
||||
// If there's queued operations, you may still get some background work
|
||||
// after the callback is called.
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of `listDatabases()` for MongoDB driver
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.listDatabases = async function listDatabases() {
|
||||
await this._waitForConnect();
|
||||
|
||||
return await this.db.admin().listDatabases();
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.createClient = async function createClient(uri, options) {
|
||||
if (typeof uri !== 'string') {
|
||||
throw new MongooseError('The `uri` parameter to `openUri()` must be a ' +
|
||||
`string, got "${typeof uri}". Make sure the first parameter to ` +
|
||||
'`mongoose.connect()` or `mongoose.createConnection()` is a string.');
|
||||
}
|
||||
|
||||
if (this._destroyCalled) {
|
||||
throw new MongooseError(
|
||||
'Connection has been closed and destroyed, and cannot be used for re-opening the connection. ' +
|
||||
'Please create a new connection with `mongoose.createConnection()` or `mongoose.connect()`.'
|
||||
);
|
||||
}
|
||||
|
||||
if (this.readyState === STATES.connecting || this.readyState === STATES.connected) {
|
||||
if (this._connectionString !== uri) {
|
||||
throw new MongooseError('Can\'t call `openUri()` on an active connection with ' +
|
||||
'different connection strings. Make sure you aren\'t calling `mongoose.connect()` ' +
|
||||
'multiple times. See: https://mongoosejs.com/docs/connections.html#multiple_connections');
|
||||
}
|
||||
}
|
||||
|
||||
options = processConnectionOptions(uri, options);
|
||||
|
||||
if (options) {
|
||||
|
||||
const autoIndex = options.config?.autoIndex ?? options.autoIndex;
|
||||
if (autoIndex != null) {
|
||||
this.config.autoIndex = autoIndex !== false;
|
||||
delete options.config;
|
||||
delete options.autoIndex;
|
||||
}
|
||||
|
||||
if ('autoCreate' in options) {
|
||||
this.config.autoCreate = !!options.autoCreate;
|
||||
delete options.autoCreate;
|
||||
}
|
||||
|
||||
if ('sanitizeFilter' in options) {
|
||||
this.config.sanitizeFilter = options.sanitizeFilter;
|
||||
delete options.sanitizeFilter;
|
||||
}
|
||||
|
||||
if ('autoSearchIndex' in options) {
|
||||
this.config.autoSearchIndex = options.autoSearchIndex;
|
||||
delete options.autoSearchIndex;
|
||||
}
|
||||
|
||||
if ('bufferTimeoutMS' in options) {
|
||||
this.config.bufferTimeoutMS = options.bufferTimeoutMS;
|
||||
delete options.bufferTimeoutMS;
|
||||
}
|
||||
|
||||
// Backwards compat
|
||||
if (options.user || options.pass) {
|
||||
options.auth = options.auth || {};
|
||||
options.auth.username = options.user;
|
||||
options.auth.password = options.pass;
|
||||
|
||||
this.user = options.user;
|
||||
this.pass = options.pass;
|
||||
}
|
||||
delete options.user;
|
||||
delete options.pass;
|
||||
|
||||
if (options.bufferCommands != null) {
|
||||
this.config.bufferCommands = options.bufferCommands;
|
||||
delete options.bufferCommands;
|
||||
}
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
this._connectionOptions = options;
|
||||
const dbName = options.dbName;
|
||||
if (dbName != null) {
|
||||
this.$dbName = dbName;
|
||||
}
|
||||
delete options.dbName;
|
||||
|
||||
if (!utils.hasUserDefinedProperty(options, 'driverInfo')) {
|
||||
options.driverInfo = {
|
||||
name: 'Mongoose',
|
||||
version: pkg.version
|
||||
};
|
||||
}
|
||||
|
||||
const { schemaMap, encryptedFieldsMap } = this._buildEncryptionSchemas();
|
||||
|
||||
if ((utils.hasOwnKeys(schemaMap) || utils.hasOwnKeys(encryptedFieldsMap)) && !options.autoEncryption) {
|
||||
throw new Error('Must provide `autoEncryption` when connecting with encrypted schemas.');
|
||||
}
|
||||
|
||||
if (utils.hasOwnKeys(schemaMap)) {
|
||||
options.autoEncryption.schemaMap = schemaMap;
|
||||
}
|
||||
|
||||
if (utils.hasOwnKeys(encryptedFieldsMap)) {
|
||||
options.autoEncryption.encryptedFieldsMap = encryptedFieldsMap;
|
||||
}
|
||||
|
||||
this.readyState = STATES.connecting;
|
||||
this._connectionString = uri;
|
||||
|
||||
let client;
|
||||
try {
|
||||
client = new mongodb.MongoClient(uri, options);
|
||||
} catch (error) {
|
||||
this.readyState = STATES.disconnected;
|
||||
throw error;
|
||||
}
|
||||
this.client = client;
|
||||
|
||||
client.setMaxListeners(0);
|
||||
await client.connect();
|
||||
|
||||
_setClient(this, client, options, dbName);
|
||||
|
||||
for (const db of this.otherDbs) {
|
||||
_setClient(db, client, {}, db.name);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a connection, which may or may not have encrypted models, build
|
||||
* a schemaMap and/or an encryptedFieldsMap for the connection, combining all models
|
||||
* into a single schemaMap and encryptedFields map.
|
||||
*
|
||||
* @returns {object} the generated schemaMap and encryptedFieldsMap
|
||||
*/
|
||||
NativeConnection.prototype._buildEncryptionSchemas = function() {
|
||||
const qeMappings = {};
|
||||
const csfleMappings = {};
|
||||
|
||||
const encryptedModels = Object.values(this.models).filter(model => model.schema._hasEncryptedFields());
|
||||
|
||||
// If discriminators are configured for the collection, there might be multiple models
|
||||
// pointing to the same namespace. For this scenario, we merge all the schemas for each namespace
|
||||
// into a single schema and then generate a schemaMap/encryptedFieldsMap for the combined schema.
|
||||
for (const model of encryptedModels) {
|
||||
const { schema, collection: { collectionName } } = model;
|
||||
const namespace = `${this.$dbName}.${collectionName}`;
|
||||
const mappings = schema.encryptionType() === 'csfle' ? csfleMappings : qeMappings;
|
||||
|
||||
mappings[namespace] ??= new Schema({}, { encryptionType: schema.encryptionType() });
|
||||
|
||||
const isNonRootDiscriminator = schema.discriminatorMapping && !schema.discriminatorMapping.isRoot;
|
||||
if (isNonRootDiscriminator) {
|
||||
const rootSchema = schema._baseSchema;
|
||||
schema.eachPath((pathname) => {
|
||||
if (rootSchema.path(pathname)) return;
|
||||
if (!mappings[namespace]._hasEncryptedField(pathname)) return;
|
||||
|
||||
throw new Error(`Cannot have duplicate keys in discriminators with encryption. key=${pathname}`);
|
||||
});
|
||||
}
|
||||
|
||||
mappings[namespace].add(schema);
|
||||
}
|
||||
|
||||
const schemaMap = Object.fromEntries(Object.entries(csfleMappings).map(
|
||||
([namespace, schema]) => ([namespace, schema._buildSchemaMap()])
|
||||
));
|
||||
|
||||
const encryptedFieldsMap = Object.fromEntries(Object.entries(qeMappings).map(
|
||||
([namespace, schema]) => ([namespace, schema._buildEncryptedFields()])
|
||||
));
|
||||
|
||||
return {
|
||||
schemaMap, encryptedFieldsMap
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.setClient = function setClient(client) {
|
||||
if (!(client instanceof mongodb.MongoClient)) {
|
||||
throw new MongooseError('Must call `setClient()` with an instance of MongoClient');
|
||||
}
|
||||
if (this.readyState !== STATES.disconnected) {
|
||||
throw new MongooseError('Cannot call `setClient()` on a connection that is already connected.');
|
||||
}
|
||||
if (client.topology == null) {
|
||||
throw new MongooseError('Cannot call `setClient()` with a MongoClient that you have not called `connect()` on yet.');
|
||||
}
|
||||
|
||||
this._connectionString = client.s.url;
|
||||
_setClient(this, client, {}, client.s.options.dbName);
|
||||
|
||||
for (const model of Object.values(this.models)) {
|
||||
// Errors handled internally, so safe to ignore error
|
||||
model.init().catch(function $modelInitNoop() {});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _setClient(conn, client, options, dbName) {
|
||||
const db = dbName != null ? client.db(dbName) : client.db();
|
||||
conn.db = db;
|
||||
conn.client = client;
|
||||
conn.host = client?.s?.options?.hosts?.[0]?.host;
|
||||
conn.port = client?.s?.options?.hosts?.[0]?.port;
|
||||
conn.name = dbName != null ? dbName : db.databaseName;
|
||||
conn._closeCalled = client._closeCalled;
|
||||
|
||||
const _handleReconnect = () => {
|
||||
// If we aren't disconnected, we assume this reconnect is due to a
|
||||
// socket timeout. If there's no activity on a socket for
|
||||
// `socketTimeoutMS`, the driver will attempt to reconnect and emit
|
||||
// this event.
|
||||
if (conn.readyState !== STATES.connected) {
|
||||
conn.readyState = STATES.connected;
|
||||
conn.emit('reconnect');
|
||||
conn.emit('reconnected');
|
||||
conn.onOpen();
|
||||
}
|
||||
};
|
||||
|
||||
const type = client?.topology?.description?.type || '';
|
||||
|
||||
if (type === 'Single') {
|
||||
client.on('serverDescriptionChanged', ev => {
|
||||
const newDescription = ev.newDescription;
|
||||
if (newDescription.type === 'Unknown') {
|
||||
conn.readyState = STATES.disconnected;
|
||||
} else {
|
||||
_handleReconnect();
|
||||
}
|
||||
});
|
||||
} else if (type.startsWith('ReplicaSet')) {
|
||||
client.on('topologyDescriptionChanged', ev => {
|
||||
// Emit disconnected if we've lost connectivity to the primary
|
||||
const description = ev.newDescription;
|
||||
if (conn.readyState === STATES.connected && description.type !== 'ReplicaSetWithPrimary') {
|
||||
// Implicitly emits 'disconnected'
|
||||
conn.readyState = STATES.disconnected;
|
||||
} else if (conn.readyState === STATES.disconnected && description.type === 'ReplicaSetWithPrimary') {
|
||||
_handleReconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
conn._lastHeartbeatAt = null;
|
||||
|
||||
client.on('serverHeartbeatSucceeded', () => {
|
||||
conn._lastHeartbeatAt = Date.now();
|
||||
for (const otherDb of conn.otherDbs) {
|
||||
otherDb._lastHeartbeatAt = conn._lastHeartbeatAt;
|
||||
}
|
||||
});
|
||||
|
||||
if (options.monitorCommands) {
|
||||
client.on('commandStarted', (data) => conn.emit('commandStarted', data));
|
||||
client.on('commandFailed', (data) => conn.emit('commandFailed', data));
|
||||
client.on('commandSucceeded', (data) => conn.emit('commandSucceeded', data));
|
||||
}
|
||||
|
||||
conn.onOpen();
|
||||
|
||||
for (const i in conn.collections) {
|
||||
if (Object.hasOwn(conn.collections, i)) {
|
||||
conn.collections[i].onOpen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = NativeConnection;
|
||||
10
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/index.js
generated
vendored
Normal file
10
backend/node_modules/mongoose/lib/drivers/node-mongodb-native/index.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.BulkWriteResult = require('./bulkWriteResult');
|
||||
exports.Collection = require('./collection');
|
||||
exports.Connection = require('./connection');
|
||||
exports.ClientEncryption = require('mongodb').ClientEncryption;
|
||||
29
backend/node_modules/mongoose/lib/error/browserMissingSchema.js
generated
vendored
Normal file
29
backend/node_modules/mongoose/lib/error/browserMissingSchema.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* MissingSchema Error constructor.
|
||||
*/
|
||||
|
||||
class MissingSchemaError extends MongooseError {
|
||||
|
||||
constructor() {
|
||||
super('Schema hasn\'t been registered for document.\n'
|
||||
+ 'Use mongoose.Document(name, schema)');
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(MissingSchemaError.prototype, 'name', {
|
||||
value: 'MongooseError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MissingSchemaError;
|
||||
44
backend/node_modules/mongoose/lib/error/bulkSaveIncompleteError.js
generated
vendored
Normal file
44
backend/node_modules/mongoose/lib/error/bulkSaveIncompleteError.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
|
||||
/**
|
||||
* If the underwriting `bulkWrite()` for `bulkSave()` succeeded, but wasn't able to update or
|
||||
* insert all documents, we throw this error.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class MongooseBulkSaveIncompleteError extends MongooseError {
|
||||
constructor(modelName, documents, bulkWriteResult) {
|
||||
const matchedCount = bulkWriteResult?.matchedCount ?? 0;
|
||||
const insertedCount = bulkWriteResult?.insertedCount ?? 0;
|
||||
let preview = documents.map(doc => doc._id).join(', ');
|
||||
if (preview.length > 100) {
|
||||
preview = preview.slice(0, 100) + '...';
|
||||
}
|
||||
|
||||
const numDocumentsNotUpdated = documents.length - matchedCount - insertedCount;
|
||||
super(`${modelName}.bulkSave() was not able to update ${numDocumentsNotUpdated} of the given documents due to incorrect version or optimistic concurrency, document ids: ${preview}`);
|
||||
|
||||
this.modelName = modelName;
|
||||
this.documents = documents;
|
||||
this.bulkWriteResult = bulkWriteResult;
|
||||
this.numDocumentsNotUpdated = numDocumentsNotUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(MongooseBulkSaveIncompleteError.prototype, 'name', {
|
||||
value: 'MongooseBulkSaveIncompleteError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MongooseBulkSaveIncompleteError;
|
||||
41
backend/node_modules/mongoose/lib/error/bulkWriteError.js
generated
vendored
Normal file
41
backend/node_modules/mongoose/lib/error/bulkWriteError.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./');
|
||||
|
||||
|
||||
/**
|
||||
* If `bulkWrite()` or `insertMany()` has validation errors, but
|
||||
* all valid operations succeed, and 'throwOnValidationError' is true,
|
||||
* Mongoose will throw this error.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class MongooseBulkWriteError extends MongooseError {
|
||||
constructor(validationErrors, results, rawResult, operation) {
|
||||
let preview = validationErrors.map(e => e.message).join(', ');
|
||||
if (preview.length > 200) {
|
||||
preview = preview.slice(0, 200) + '...';
|
||||
}
|
||||
super(`${operation} failed with ${validationErrors.length} Mongoose validation errors: ${preview}`);
|
||||
|
||||
this.validationErrors = validationErrors;
|
||||
this.results = results;
|
||||
this.rawResult = rawResult;
|
||||
this.operation = operation;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(MongooseBulkWriteError.prototype, 'name', {
|
||||
value: 'MongooseBulkWriteError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MongooseBulkWriteError;
|
||||
158
backend/node_modules/mongoose/lib/error/cast.js
generated
vendored
Normal file
158
backend/node_modules/mongoose/lib/error/cast.js
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* Casting Error constructor.
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {string} value
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class CastError extends MongooseError {
|
||||
constructor(type, value, path, reason, schemaType) {
|
||||
// If no args, assume we'll `init()` later.
|
||||
if (arguments.length > 0) {
|
||||
const valueType = getValueType(value);
|
||||
const messageFormat = getMessageFormat(schemaType);
|
||||
const msg = formatMessage(null, type, value, path, messageFormat, valueType, reason);
|
||||
super(msg);
|
||||
this.init(type, value, path, reason, schemaType);
|
||||
} else {
|
||||
super(formatMessage());
|
||||
}
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
stringValue: this.stringValue,
|
||||
valueType: this.valueType,
|
||||
kind: this.kind,
|
||||
value: this.value,
|
||||
path: this.path,
|
||||
reason: this.reason,
|
||||
name: this.name,
|
||||
message: this.message
|
||||
};
|
||||
}
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
init(type, value, path, reason, schemaType) {
|
||||
this.stringValue = getStringValue(value);
|
||||
this.messageFormat = getMessageFormat(schemaType);
|
||||
this.kind = type;
|
||||
this.value = value;
|
||||
this.path = path;
|
||||
this.reason = reason;
|
||||
this.valueType = getValueType(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore
|
||||
* @param {Readonly<CastError>} other
|
||||
* @api private
|
||||
*/
|
||||
copy(other) {
|
||||
this.messageFormat = other.messageFormat;
|
||||
this.stringValue = other.stringValue;
|
||||
this.kind = other.kind;
|
||||
this.value = other.value;
|
||||
this.path = other.path;
|
||||
this.reason = other.reason;
|
||||
this.message = other.message;
|
||||
this.valueType = other.valueType;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
setModel(model) {
|
||||
this.message = formatMessage(model, this.kind, this.value, this.path,
|
||||
this.messageFormat, this.valueType);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(CastError.prototype, 'name', {
|
||||
value: 'CastError'
|
||||
});
|
||||
|
||||
function getStringValue(value) {
|
||||
let stringValue = util.inspect(value);
|
||||
stringValue = stringValue.replace(/^'|'$/g, '"');
|
||||
if (!stringValue.startsWith('"')) {
|
||||
stringValue = '"' + stringValue + '"';
|
||||
}
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
function getValueType(value) {
|
||||
if (value == null) {
|
||||
return '' + value;
|
||||
}
|
||||
|
||||
const t = typeof value;
|
||||
if (t !== 'object') {
|
||||
return t;
|
||||
}
|
||||
if (typeof value.constructor !== 'function') {
|
||||
return t;
|
||||
}
|
||||
return value.constructor.name;
|
||||
}
|
||||
|
||||
function getMessageFormat(schemaType) {
|
||||
const messageFormat = schemaType?._castErrorMessage || null;
|
||||
if (typeof messageFormat === 'string' || typeof messageFormat === 'function') {
|
||||
return messageFormat;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function formatMessage(model, kind, value, path, messageFormat, valueType, reason) {
|
||||
if (typeof messageFormat === 'string') {
|
||||
const stringValue = getStringValue(value);
|
||||
let ret = messageFormat.
|
||||
replace('{KIND}', kind).
|
||||
replace('{VALUE}', stringValue).
|
||||
replace('{PATH}', path);
|
||||
if (model != null) {
|
||||
ret = ret.replace('{MODEL}', model.modelName);
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else if (typeof messageFormat === 'function') {
|
||||
return messageFormat(value, path, model, kind);
|
||||
} else {
|
||||
const stringValue = getStringValue(value);
|
||||
const valueTypeMsg = valueType ? ' (type ' + valueType + ')' : '';
|
||||
let ret = 'Cast to ' + kind + ' failed for value ' +
|
||||
stringValue + valueTypeMsg + ' at path "' + path + '"';
|
||||
if (model != null) {
|
||||
ret += ' for model "' + model.modelName + '"';
|
||||
}
|
||||
if (reason != null &&
|
||||
typeof reason.constructor === 'function' &&
|
||||
reason.constructor.name !== 'AssertionError' &&
|
||||
reason.constructor.name !== 'Error') {
|
||||
ret += ' because of "' + reason.constructor.name + '"';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = CastError;
|
||||
26
backend/node_modules/mongoose/lib/error/createCollectionsError.js
generated
vendored
Normal file
26
backend/node_modules/mongoose/lib/error/createCollectionsError.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* createCollections Error constructor
|
||||
*
|
||||
* @param {string} message
|
||||
* @param {string} errorsMap
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class CreateCollectionsError extends MongooseError {
|
||||
constructor(message, errorsMap) {
|
||||
super(message);
|
||||
this.errors = errorsMap;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(CreateCollectionsError.prototype, 'name', {
|
||||
value: 'CreateCollectionsError'
|
||||
});
|
||||
|
||||
module.exports = CreateCollectionsError;
|
||||
|
||||
40
backend/node_modules/mongoose/lib/error/divergentArray.js
generated
vendored
Normal file
40
backend/node_modules/mongoose/lib/error/divergentArray.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* DivergentArrayError constructor.
|
||||
* @param {string[]} paths
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class DivergentArrayError extends MongooseError {
|
||||
|
||||
constructor(paths) {
|
||||
const msg = 'For your own good, using `document.save()` to update an array '
|
||||
+ 'which was selected using an $elemMatch projection OR '
|
||||
+ 'populated using skip, limit, query conditions, or exclusion of '
|
||||
+ 'the _id field when the operation results in a $pop or $set of '
|
||||
+ 'the entire array is not supported. The following '
|
||||
+ 'path(s) would have been modified unsafely:\n'
|
||||
+ ' ' + paths.join('\n ') + '\n'
|
||||
+ 'Use Model.updateOne() to update these arrays instead. '
|
||||
+ 'See https://mongoosejs.com/docs/faq.html#divergent-array-error for more information.';
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(DivergentArrayError.prototype, 'name', {
|
||||
value: 'DivergentArrayError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = DivergentArrayError;
|
||||
41
backend/node_modules/mongoose/lib/error/eachAsyncMultiError.js
generated
vendored
Normal file
41
backend/node_modules/mongoose/lib/error/eachAsyncMultiError.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
|
||||
/**
|
||||
* If `eachAsync()` is called with `continueOnError: true`, there can be
|
||||
* multiple errors. This error class contains an `errors` property, which
|
||||
* contains an array of all errors that occurred in `eachAsync()`.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class EachAsyncMultiError extends MongooseError {
|
||||
/**
|
||||
* @param {string} connectionString
|
||||
*/
|
||||
constructor(errors) {
|
||||
let preview = errors.map(e => e.message).join(', ');
|
||||
if (preview.length > 50) {
|
||||
preview = preview.slice(0, 50) + '...';
|
||||
}
|
||||
super(`eachAsync() finished with ${errors.length} errors: ${preview}`);
|
||||
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(EachAsyncMultiError.prototype, 'name', {
|
||||
value: 'EachAsyncMultiError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = EachAsyncMultiError;
|
||||
237
backend/node_modules/mongoose/lib/error/index.js
generated
vendored
Normal file
237
backend/node_modules/mongoose/lib/error/index.js
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* MongooseError constructor. MongooseError is the base class for all
|
||||
* Mongoose-specific errors.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* const Model = mongoose.model('Test', new mongoose.Schema({ answer: Number }));
|
||||
* const doc = new Model({ answer: 'not a number' });
|
||||
* const err = doc.validateSync();
|
||||
*
|
||||
* err instanceof mongoose.Error.ValidationError; // true
|
||||
*
|
||||
* @constructor Error
|
||||
* @param {string} msg Error message
|
||||
* @inherits Error https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* The name of the error. The name uniquely identifies this Mongoose error. The
|
||||
* possible values are:
|
||||
*
|
||||
* - `MongooseError`: general Mongoose error
|
||||
* - `CastError`: Mongoose could not convert a value to the type defined in the schema path. May be in a `ValidationError` class' `errors` property.
|
||||
* - `DivergentArrayError`: You attempted to `save()` an array that was modified after you loaded it with a `$elemMatch` or similar projection
|
||||
* - `MissingSchemaError`: You tried to access a model with [`mongoose.model()`](https://mongoosejs.com/docs/api/mongoose.html#Mongoose.model()) that was not defined
|
||||
* - `DocumentNotFoundError`: The document you tried to [`save()`](https://mongoosejs.com/docs/api/document.html#Document.prototype.save()) was not found
|
||||
* - `ValidatorError`: error from an individual schema path's validator
|
||||
* - `ValidationError`: error returned from [`validate()`](https://mongoosejs.com/docs/api/document.html#Document.prototype.validate()) or [`validateSync()`](https://mongoosejs.com/docs/api/document.html#Document.prototype.validateSync()). Contains zero or more `ValidatorError` instances in `.errors` property.
|
||||
* - `MissingSchemaError`: You called `mongoose.Document()` without a schema
|
||||
* - `ObjectExpectedError`: Thrown when you set a nested path to a non-object value with [strict mode set](https://mongoosejs.com/docs/guide.html#strict).
|
||||
* - `ObjectParameterError`: Thrown when you pass a non-object value to a function which expects an object as a paramter
|
||||
* - `OverwriteModelError`: Thrown when you call [`mongoose.model()`](https://mongoosejs.com/docs/api/mongoose.html#Mongoose.model()) to re-define a model that was already defined.
|
||||
* - `ParallelSaveError`: Thrown when you call [`save()`](https://mongoosejs.com/docs/api/model.html#Model.prototype.save()) on a document when the same document instance is already saving.
|
||||
* - `StrictModeError`: Thrown when you set a path that isn't the schema and [strict mode](https://mongoosejs.com/docs/guide.html#strict) is set to `throw`.
|
||||
* - `VersionError`: Thrown when the [document is out of sync](https://mongoosejs.com/docs/guide.html#versionKey)
|
||||
*
|
||||
* @api public
|
||||
* @property {string} name
|
||||
* @memberOf Error
|
||||
* @instance
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = MongooseError;
|
||||
|
||||
/**
|
||||
* The default built-in validator error messages.
|
||||
*
|
||||
* @see Error.messages https://mongoosejs.com/docs/api/error.html#Error.messages
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.messages = require('./messages');
|
||||
|
||||
// backward compat
|
||||
MongooseError.Messages = MongooseError.messages;
|
||||
|
||||
/**
|
||||
* An instance of this error class will be thrown when mongoose failed to
|
||||
* cast a value.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.CastError = require('./cast');
|
||||
|
||||
/**
|
||||
* An instance of this error class will be thrown when `save()` fails
|
||||
* because the underlying
|
||||
* document was not found. The constructor takes one parameter, the
|
||||
* conditions that mongoose passed to `updateOne()` when trying to update
|
||||
* the document.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.DocumentNotFoundError = require('./notFound');
|
||||
|
||||
/**
|
||||
* An instance of this error class will be thrown when [validation](https://mongoosejs.com/docs/validation.html) failed.
|
||||
* The `errors` property contains an object whose keys are the paths that failed and whose values are
|
||||
* instances of CastError or ValidationError.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.ValidationError = require('./validation');
|
||||
|
||||
/**
|
||||
* A `ValidationError` has a hash of `errors` that contain individual
|
||||
* `ValidatorError` instances.
|
||||
*
|
||||
* #### Example:
|
||||
*
|
||||
* const schema = Schema({ name: { type: String, required: true } });
|
||||
* const Model = mongoose.model('Test', schema);
|
||||
* const doc = new Model({});
|
||||
*
|
||||
* // Top-level error is a ValidationError, **not** a ValidatorError
|
||||
* const err = doc.validateSync();
|
||||
* err instanceof mongoose.Error.ValidationError; // true
|
||||
*
|
||||
* // A ValidationError `err` has 0 or more ValidatorErrors keyed by the
|
||||
* // path in the `err.errors` property.
|
||||
* err.errors['name'] instanceof mongoose.Error.ValidatorError;
|
||||
*
|
||||
* err.errors['name'].kind; // 'required'
|
||||
* err.errors['name'].path; // 'name'
|
||||
* err.errors['name'].value; // undefined
|
||||
*
|
||||
* Instances of `ValidatorError` have the following properties:
|
||||
*
|
||||
* - `kind`: The validator's `type`, like `'required'` or `'regexp'`
|
||||
* - `path`: The path that failed validation
|
||||
* - `value`: The value that failed validation
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.ValidatorError = require('./validator');
|
||||
|
||||
/**
|
||||
* An instance of this error class will be thrown when you call `save()` after
|
||||
* the document in the database was changed in a potentially unsafe way. See
|
||||
* the [`versionKey` option](https://mongoosejs.com/docs/guide.html#versionKey) for more information.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.VersionError = require('./version');
|
||||
|
||||
/**
|
||||
* An instance of this error class will be thrown when you call `save()` multiple
|
||||
* times on the same document in parallel. See the [FAQ](https://mongoosejs.com/docs/faq.html) for more
|
||||
* information.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.ParallelSaveError = require('./parallelSave');
|
||||
|
||||
/**
|
||||
* Thrown when a model with the given name was already registered on the connection.
|
||||
* See [the FAQ about `OverwriteModelError`](https://mongoosejs.com/docs/faq.html#overwrite-model-error).
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.OverwriteModelError = require('./overwriteModel');
|
||||
|
||||
/**
|
||||
* Thrown when you try to access a model that has not been registered yet
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.MissingSchemaError = require('./missingSchema');
|
||||
|
||||
/**
|
||||
* Thrown when some documents failed to save when calling `bulkSave()`
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.MongooseBulkSaveIncompleteError = require('./bulkSaveIncompleteError');
|
||||
|
||||
/**
|
||||
* Thrown when the MongoDB Node driver can't connect to a valid server
|
||||
* to send an operation to.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.MongooseServerSelectionError = require('./serverSelection');
|
||||
|
||||
/**
|
||||
* An instance of this error will be thrown if you used an array projection
|
||||
* and then modified the array in an unsafe way.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.DivergentArrayError = require('./divergentArray');
|
||||
|
||||
/**
|
||||
* Thrown when your try to pass values to model constructor that
|
||||
* were not specified in schema or change immutable properties when
|
||||
* `strict` mode is `"throw"`
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.StrictModeError = require('./strict');
|
||||
|
||||
/**
|
||||
* An instance of this error class will be returned when mongoose failed to
|
||||
* populate with a path that is not existing.
|
||||
*
|
||||
* @api public
|
||||
* @memberOf Error
|
||||
* @static
|
||||
*/
|
||||
|
||||
MongooseError.StrictPopulateError = require('./strictPopulate');
|
||||
32
backend/node_modules/mongoose/lib/error/invalidSchemaOption.js
generated
vendored
Normal file
32
backend/node_modules/mongoose/lib/error/invalidSchemaOption.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* InvalidSchemaOption Error constructor.
|
||||
* @param {string} name
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class InvalidSchemaOptionError extends MongooseError {
|
||||
|
||||
constructor(name, option) {
|
||||
const msg = `Cannot create use schema for property "${name}" because the schema has the ${option} option enabled.`;
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(InvalidSchemaOptionError.prototype, 'name', {
|
||||
value: 'InvalidSchemaOptionError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = InvalidSchemaOptionError;
|
||||
47
backend/node_modules/mongoose/lib/error/messages.js
generated
vendored
Normal file
47
backend/node_modules/mongoose/lib/error/messages.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
/**
|
||||
* The default built-in validator error messages. These may be customized.
|
||||
*
|
||||
* // customize within each schema or globally like so
|
||||
* const mongoose = require('mongoose');
|
||||
* mongoose.Error.messages.String.enum = "Your custom message for {PATH}.";
|
||||
*
|
||||
* Error messages support basic templating. Mongoose will replace the following strings with the corresponding value.
|
||||
*
|
||||
* - `{PATH}` is replaced with the invalid document path
|
||||
* - `{VALUE}` is replaced with the invalid value
|
||||
* - `{TYPE}` is replaced with the validator type such as "regexp", "min", or "user defined"
|
||||
* - `{MIN}` is replaced with the declared min value for the Number.min validator
|
||||
* - `{MAX}` is replaced with the declared max value for the Number.max validator
|
||||
*
|
||||
* Click the "show code" link below to see all defaults.
|
||||
*
|
||||
* @static
|
||||
* @memberOf MongooseError
|
||||
* @api public
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const msg = module.exports = exports = {};
|
||||
|
||||
msg.DocumentNotFoundError = null;
|
||||
|
||||
msg.general = {};
|
||||
msg.general.default = 'Validator failed for path `{PATH}` with value `{VALUE}`';
|
||||
msg.general.required = 'Path `{PATH}` is required.';
|
||||
|
||||
msg.Number = {};
|
||||
msg.Number.min = 'Path `{PATH}` ({VALUE}) is less than minimum allowed value ({MIN}).';
|
||||
msg.Number.max = 'Path `{PATH}` ({VALUE}) is more than maximum allowed value ({MAX}).';
|
||||
msg.Number.enum = '`{VALUE}` is not a valid enum value for path `{PATH}`.';
|
||||
|
||||
msg.Date = {};
|
||||
msg.Date.min = 'Path `{PATH}` ({VALUE}) is before minimum allowed value ({MIN}).';
|
||||
msg.Date.max = 'Path `{PATH}` ({VALUE}) is after maximum allowed value ({MAX}).';
|
||||
|
||||
msg.String = {};
|
||||
msg.String.enum = '`{VALUE}` is not a valid enum value for path `{PATH}`.';
|
||||
msg.String.match = 'Path `{PATH}` is invalid ({VALUE}).';
|
||||
msg.String.minlength = 'Path `{PATH}` (`{VALUE}`, length {LENGTH}) is shorter than the minimum allowed length ({MINLENGTH}).';
|
||||
msg.String.maxlength = 'Path `{PATH}` (`{VALUE}`, length {LENGTH}) is longer than the maximum allowed length ({MAXLENGTH}).';
|
||||
33
backend/node_modules/mongoose/lib/error/missingSchema.js
generated
vendored
Normal file
33
backend/node_modules/mongoose/lib/error/missingSchema.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* MissingSchema Error constructor.
|
||||
* @param {string} name
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class MissingSchemaError extends MongooseError {
|
||||
|
||||
constructor(name) {
|
||||
const msg = 'Schema hasn\'t been registered for model "' + name + '".\n'
|
||||
+ 'Use mongoose.model(name, schema)';
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(MissingSchemaError.prototype, 'name', {
|
||||
value: 'MissingSchemaError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MissingSchemaError;
|
||||
13
backend/node_modules/mongoose/lib/error/mongooseError.js
generated
vendored
Normal file
13
backend/node_modules/mongoose/lib/error/mongooseError.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
class MongooseError extends Error { }
|
||||
|
||||
Object.defineProperty(MongooseError.prototype, 'name', {
|
||||
value: 'MongooseError'
|
||||
});
|
||||
|
||||
module.exports = MongooseError;
|
||||
47
backend/node_modules/mongoose/lib/error/notFound.js
generated
vendored
Normal file
47
backend/node_modules/mongoose/lib/error/notFound.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* OverwriteModel Error constructor.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class DocumentNotFoundError extends MongooseError {
|
||||
|
||||
constructor(filter, model, numAffected, result) {
|
||||
let msg;
|
||||
const messages = MongooseError.messages;
|
||||
if (messages.DocumentNotFoundError != null) {
|
||||
msg = typeof messages.DocumentNotFoundError === 'function' ?
|
||||
messages.DocumentNotFoundError(filter, model) :
|
||||
messages.DocumentNotFoundError;
|
||||
} else {
|
||||
msg = 'No document found for query "' + util.inspect(filter) +
|
||||
'" on model "' + model + '"';
|
||||
}
|
||||
|
||||
super(msg);
|
||||
|
||||
this.result = result;
|
||||
this.numAffected = numAffected;
|
||||
this.filter = filter;
|
||||
// Backwards compat
|
||||
this.query = filter;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(DocumentNotFoundError.prototype, 'name', {
|
||||
value: 'DocumentNotFoundError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = DocumentNotFoundError;
|
||||
31
backend/node_modules/mongoose/lib/error/objectExpected.js
generated
vendored
Normal file
31
backend/node_modules/mongoose/lib/error/objectExpected.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Strict mode error constructor
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {string} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class ObjectExpectedError extends MongooseError {
|
||||
|
||||
constructor(path, val) {
|
||||
const typeDescription = Array.isArray(val) ? 'array' : 'primitive value';
|
||||
super('Tried to set nested object field `' + path +
|
||||
`\` to ${typeDescription} \`` + val + '`');
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(ObjectExpectedError.prototype, 'name', {
|
||||
value: 'ObjectExpectedError'
|
||||
});
|
||||
|
||||
module.exports = ObjectExpectedError;
|
||||
31
backend/node_modules/mongoose/lib/error/objectParameter.js
generated
vendored
Normal file
31
backend/node_modules/mongoose/lib/error/objectParameter.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Constructor for errors that happen when a parameter that's expected to be
|
||||
* an object isn't an object
|
||||
*
|
||||
* @param {any} value
|
||||
* @param {string} paramName
|
||||
* @param {string} fnName
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class ObjectParameterError extends MongooseError {
|
||||
constructor(value, paramName, fnName) {
|
||||
super('Parameter "' + paramName + '" to ' + fnName +
|
||||
'() must be an object, got "' + (value == null ? value : value.toString()) + '" (type ' + typeof value + ')');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object.defineProperty(ObjectParameterError.prototype, 'name', {
|
||||
value: 'ObjectParameterError'
|
||||
});
|
||||
|
||||
module.exports = ObjectParameterError;
|
||||
31
backend/node_modules/mongoose/lib/error/overwriteModel.js
generated
vendored
Normal file
31
backend/node_modules/mongoose/lib/error/overwriteModel.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* OverwriteModel Error constructor.
|
||||
* @param {string} name
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class OverwriteModelError extends MongooseError {
|
||||
|
||||
constructor(name) {
|
||||
super('Cannot overwrite `' + name + '` model once compiled.');
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(OverwriteModelError.prototype, 'name', {
|
||||
value: 'OverwriteModelError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = OverwriteModelError;
|
||||
33
backend/node_modules/mongoose/lib/error/parallelSave.js
generated
vendored
Normal file
33
backend/node_modules/mongoose/lib/error/parallelSave.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
|
||||
/**
|
||||
* ParallelSave Error constructor.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class ParallelSaveError extends MongooseError {
|
||||
|
||||
constructor(doc) {
|
||||
const msg = 'Can\'t save() the same doc multiple times in parallel. Document: ';
|
||||
super(msg + doc._doc._id);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(ParallelSaveError.prototype, 'name', {
|
||||
value: 'ParallelSaveError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = ParallelSaveError;
|
||||
33
backend/node_modules/mongoose/lib/error/parallelValidate.js
generated
vendored
Normal file
33
backend/node_modules/mongoose/lib/error/parallelValidate.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
|
||||
/**
|
||||
* ParallelValidate Error constructor.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class ParallelValidateError extends MongooseError {
|
||||
|
||||
constructor(doc) {
|
||||
const msg = 'Can\'t validate() the same doc multiple times in parallel. Document: ';
|
||||
super(msg + doc._doc._id);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(ParallelValidateError.prototype, 'name', {
|
||||
value: 'ParallelValidateError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = ParallelValidateError;
|
||||
62
backend/node_modules/mongoose/lib/error/serverSelection.js
generated
vendored
Normal file
62
backend/node_modules/mongoose/lib/error/serverSelection.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
const allServersUnknown = require('../helpers/topology/allServersUnknown');
|
||||
const isAtlas = require('../helpers/topology/isAtlas');
|
||||
const isSSLError = require('../helpers/topology/isSSLError');
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
const atlasMessage = 'Could not connect to any servers in your MongoDB Atlas cluster. ' +
|
||||
'One common reason is that you\'re trying to access the database from ' +
|
||||
'an IP that isn\'t whitelisted. Make sure your current IP address is on your Atlas ' +
|
||||
'cluster\'s IP whitelist: https://www.mongodb.com/docs/atlas/security-whitelist/';
|
||||
|
||||
const sslMessage = 'Mongoose is connecting with SSL enabled, but the server is ' +
|
||||
'not accepting SSL connections. Please ensure that the MongoDB server you are ' +
|
||||
'connecting to is configured to accept SSL connections. Learn more: ' +
|
||||
'https://mongoosejs.com/docs/tutorials/ssl.html';
|
||||
|
||||
class MongooseServerSelectionError extends MongooseError {
|
||||
/**
|
||||
* MongooseServerSelectionError constructor
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
assimilateError(err) {
|
||||
const reason = err.reason;
|
||||
// Special message for a case that is likely due to IP whitelisting issues.
|
||||
const isAtlasWhitelistError = isAtlas(reason) &&
|
||||
allServersUnknown(reason) &&
|
||||
err.message.indexOf('bad auth') === -1 &&
|
||||
err.message.indexOf('Authentication failed') === -1;
|
||||
|
||||
if (isAtlasWhitelistError) {
|
||||
this.message = atlasMessage;
|
||||
} else if (isSSLError(reason)) {
|
||||
this.message = sslMessage;
|
||||
} else {
|
||||
this.message = err.message;
|
||||
}
|
||||
for (const key in err) {
|
||||
if (key !== 'name') {
|
||||
this[key] = err[key];
|
||||
}
|
||||
}
|
||||
this.cause = reason;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(MongooseServerSelectionError.prototype, 'name', {
|
||||
value: 'MongooseServerSelectionError'
|
||||
});
|
||||
|
||||
module.exports = MongooseServerSelectionError;
|
||||
103
backend/node_modules/mongoose/lib/error/setOptionError.js
generated
vendored
Normal file
103
backend/node_modules/mongoose/lib/error/setOptionError.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
* Module requirements
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
const util = require('util');
|
||||
const combinePathErrors = require('../helpers/error/combinePathErrors');
|
||||
|
||||
/**
|
||||
* Mongoose.set Error
|
||||
*
|
||||
* @api private
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
class SetOptionError extends MongooseError {
|
||||
|
||||
constructor() {
|
||||
super('');
|
||||
|
||||
this.errors = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Console.log helper
|
||||
*/
|
||||
toString() {
|
||||
return combinePathErrors(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* inspect helper
|
||||
* @api private
|
||||
*/
|
||||
inspect() {
|
||||
return Object.assign(new Error(this.message), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* add message
|
||||
* @param {string} key
|
||||
* @param {string|Error} error
|
||||
* @api private
|
||||
*/
|
||||
addError(key, error) {
|
||||
if (error instanceof SetOptionError) {
|
||||
const { errors } = error;
|
||||
for (const optionKey of Object.keys(errors)) {
|
||||
this.addError(optionKey, errors[optionKey]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.errors[key] = error;
|
||||
this.message = combinePathErrors(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (util.inspect.custom) {
|
||||
// Avoid Node deprecation warning DEP0079
|
||||
SetOptionError.prototype[util.inspect.custom] = SetOptionError.prototype.inspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for JSON.stringify
|
||||
* Ensure `name` and `message` show up in toJSON output re: gh-9847
|
||||
* @api private
|
||||
*/
|
||||
Object.defineProperty(SetOptionError.prototype, 'toJSON', {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: function() {
|
||||
return Object.assign({}, this, { name: this.name, message: this.message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Object.defineProperty(SetOptionError.prototype, 'name', {
|
||||
value: 'SetOptionError'
|
||||
});
|
||||
|
||||
class SetOptionInnerError extends MongooseError {
|
||||
/**
|
||||
* Error for the "errors" array in "SetOptionError" with consistent message
|
||||
* @param {string} key
|
||||
*/
|
||||
constructor(key) {
|
||||
super(`"${key}" is not a valid option to set`);
|
||||
}
|
||||
}
|
||||
|
||||
SetOptionError.SetOptionInnerError = SetOptionInnerError;
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = SetOptionError;
|
||||
35
backend/node_modules/mongoose/lib/error/strict.js
generated
vendored
Normal file
35
backend/node_modules/mongoose/lib/error/strict.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Strict mode error constructor
|
||||
*
|
||||
* @param {string} path
|
||||
* @param {string} [msg]
|
||||
* @param {boolean} [immutable]
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
|
||||
class StrictModeError extends MongooseError {
|
||||
|
||||
constructor(path, msg, immutable) {
|
||||
msg = msg || 'Field `' + path + '` is not in schema and strict ' +
|
||||
'mode is set to throw.';
|
||||
super(msg);
|
||||
this.isImmutableError = !!immutable;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(StrictModeError.prototype, 'name', {
|
||||
value: 'StrictModeError'
|
||||
});
|
||||
|
||||
module.exports = StrictModeError;
|
||||
31
backend/node_modules/mongoose/lib/error/strictPopulate.js
generated
vendored
Normal file
31
backend/node_modules/mongoose/lib/error/strictPopulate.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Strict mode error constructor
|
||||
*
|
||||
* @param {string} path
|
||||
* @param {string} [msg]
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class StrictPopulateError extends MongooseError {
|
||||
|
||||
constructor(path, msg) {
|
||||
msg = msg || 'Cannot populate path `' + path + '` because it is not in your schema. ' + 'Set the `strictPopulate` option to false to override.';
|
||||
super(msg);
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(StrictPopulateError.prototype, 'name', {
|
||||
value: 'StrictPopulateError'
|
||||
});
|
||||
|
||||
module.exports = StrictPopulateError;
|
||||
30
backend/node_modules/mongoose/lib/error/syncIndexes.js
generated
vendored
Normal file
30
backend/node_modules/mongoose/lib/error/syncIndexes.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* SyncIndexes Error constructor.
|
||||
*
|
||||
* @param {string} message
|
||||
* @param {string} errorsMap
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class SyncIndexesError extends MongooseError {
|
||||
constructor(message, errorsMap) {
|
||||
super(message);
|
||||
this.errors = errorsMap;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(SyncIndexesError.prototype, 'name', {
|
||||
value: 'SyncIndexesError'
|
||||
});
|
||||
|
||||
|
||||
module.exports = SyncIndexesError;
|
||||
97
backend/node_modules/mongoose/lib/error/validation.js
generated
vendored
Normal file
97
backend/node_modules/mongoose/lib/error/validation.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*!
|
||||
* Module requirements
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
const getConstructorName = require('../helpers/getConstructorName');
|
||||
const util = require('util');
|
||||
const combinePathErrors = require('../helpers/error/combinePathErrors');
|
||||
|
||||
/**
|
||||
* Document Validation Error
|
||||
*
|
||||
* @api private
|
||||
* @param {Document} [instance]
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
class ValidationError extends MongooseError {
|
||||
|
||||
constructor(instance) {
|
||||
let _message;
|
||||
if (getConstructorName(instance) === 'model') {
|
||||
_message = instance.constructor.modelName + ' validation failed';
|
||||
} else {
|
||||
_message = 'Validation failed';
|
||||
}
|
||||
|
||||
super(_message);
|
||||
|
||||
this.errors = {};
|
||||
this._message = _message;
|
||||
|
||||
if (instance) {
|
||||
instance.$errors = this.errors;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Console.log helper
|
||||
*/
|
||||
toString() {
|
||||
return this.name + ': ' + combinePathErrors(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* add message
|
||||
* @param {string} path
|
||||
* @param {string|Error} error
|
||||
* @api private
|
||||
*/
|
||||
addError(path, error) {
|
||||
if (error instanceof ValidationError) {
|
||||
const { errors } = error;
|
||||
for (const errorPath of Object.keys(errors)) {
|
||||
this.addError(`${path}.${errorPath}`, errors[errorPath]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.errors[path] = error;
|
||||
this.message = this._message + ': ' + combinePathErrors(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (util.inspect.custom) {
|
||||
// Avoid Node deprecation warning DEP0079
|
||||
ValidationError.prototype[util.inspect.custom] = ValidationError.prototype.inspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for JSON.stringify
|
||||
* Ensure `name` and `message` show up in toJSON output re: gh-9847
|
||||
* @api private
|
||||
*/
|
||||
Object.defineProperty(ValidationError.prototype, 'toJSON', {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: function() {
|
||||
return Object.assign({}, this, { name: this.name, message: this.message });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Object.defineProperty(ValidationError.prototype, 'name', {
|
||||
value: 'ValidationError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = ValidationError;
|
||||
100
backend/node_modules/mongoose/lib/error/validator.js
generated
vendored
Normal file
100
backend/node_modules/mongoose/lib/error/validator.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Schema validator error
|
||||
*
|
||||
* @param {object} properties
|
||||
* @param {Document} doc
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class ValidatorError extends MongooseError {
|
||||
|
||||
constructor(properties, doc) {
|
||||
let msg = properties.message;
|
||||
if (!msg) {
|
||||
msg = MongooseError.messages.general.default;
|
||||
}
|
||||
|
||||
const message = formatMessage(msg, properties, doc);
|
||||
super(message);
|
||||
|
||||
properties = Object.assign({}, properties, { message: message });
|
||||
this.properties = properties;
|
||||
this.kind = properties.type;
|
||||
this.path = properties.path;
|
||||
this.value = properties.value;
|
||||
this.reason = properties.reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString helper
|
||||
* TODO remove? This defaults to `${this.name}: ${this.message}`
|
||||
* @api private
|
||||
*/
|
||||
toString() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure `name` and `message` show up in toJSON output re: gh-9296
|
||||
* @api private
|
||||
*/
|
||||
|
||||
toJSON() {
|
||||
return Object.assign({ name: this.name, message: this.message }, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object.defineProperty(ValidatorError.prototype, 'name', {
|
||||
value: 'ValidatorError'
|
||||
});
|
||||
|
||||
/**
|
||||
* The object used to define this validator. Not enumerable to hide
|
||||
* it from `require('util').inspect()` output re: gh-3925
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Object.defineProperty(ValidatorError.prototype, 'properties', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: null
|
||||
});
|
||||
|
||||
// Exposed for testing
|
||||
ValidatorError.prototype.formatMessage = formatMessage;
|
||||
|
||||
/**
|
||||
* Formats error messages
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function formatMessage(msg, properties, doc) {
|
||||
if (typeof msg === 'function') {
|
||||
return msg(properties, doc);
|
||||
}
|
||||
|
||||
const propertyNames = Object.keys(properties);
|
||||
for (const propertyName of propertyNames) {
|
||||
if (propertyName === 'message') {
|
||||
continue;
|
||||
}
|
||||
msg = msg.replace('{' + propertyName.toUpperCase() + '}', properties[propertyName]);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = ValidatorError;
|
||||
38
backend/node_modules/mongoose/lib/error/version.js
generated
vendored
Normal file
38
backend/node_modules/mongoose/lib/error/version.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const MongooseError = require('./mongooseError');
|
||||
|
||||
/**
|
||||
* Version Error constructor.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* @param {number} currentVersion
|
||||
* @param {string[]} modifiedPaths
|
||||
* @api private
|
||||
*/
|
||||
|
||||
class VersionError extends MongooseError {
|
||||
|
||||
constructor(doc, currentVersion, modifiedPaths) {
|
||||
const modifiedPathsStr = modifiedPaths.join(', ');
|
||||
super('No matching document found for id "' + doc._doc._id +
|
||||
'" version ' + currentVersion + ' modifiedPaths "' + modifiedPathsStr + '"');
|
||||
this.version = currentVersion;
|
||||
this.modifiedPaths = modifiedPaths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object.defineProperty(VersionError.prototype, 'name', {
|
||||
value: 'VersionError'
|
||||
});
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = VersionError;
|
||||
39
backend/node_modules/mongoose/lib/helpers/aggregate/prepareDiscriminatorPipeline.js
generated
vendored
Normal file
39
backend/node_modules/mongoose/lib/helpers/aggregate/prepareDiscriminatorPipeline.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function prepareDiscriminatorPipeline(pipeline, schema, prefix) {
|
||||
const discriminatorMapping = schema?.discriminatorMapping;
|
||||
prefix = prefix || '';
|
||||
|
||||
if (discriminatorMapping && !discriminatorMapping.isRoot) {
|
||||
const originalPipeline = pipeline;
|
||||
const filterKey = (prefix.length > 0 ? prefix + '.' : prefix) + discriminatorMapping.key;
|
||||
const discriminatorValue = discriminatorMapping.value;
|
||||
|
||||
// If the first pipeline stage is a match and it doesn't specify a `__t`
|
||||
// key, add the discriminator key to it. This allows for potential
|
||||
// aggregation query optimizations not to be disturbed by this feature.
|
||||
if (originalPipeline[0] != null &&
|
||||
originalPipeline[0].$match &&
|
||||
(originalPipeline[0].$match[filterKey] === undefined || originalPipeline[0].$match[filterKey] === discriminatorValue)) {
|
||||
originalPipeline[0].$match[filterKey] = discriminatorValue;
|
||||
// `originalPipeline` is a ref, so there's no need for
|
||||
// aggregate._pipeline = originalPipeline
|
||||
} else if (originalPipeline[0]?.$geoNear) {
|
||||
originalPipeline[0].$geoNear.query =
|
||||
originalPipeline[0].$geoNear.query || {};
|
||||
originalPipeline[0].$geoNear.query[filterKey] = discriminatorValue;
|
||||
} else if (originalPipeline[0]?.$search) {
|
||||
if (originalPipeline[1]?.$match != null) {
|
||||
originalPipeline[1].$match[filterKey] = originalPipeline[1].$match[filterKey] || discriminatorValue;
|
||||
} else {
|
||||
const match = {};
|
||||
match[filterKey] = discriminatorValue;
|
||||
originalPipeline.splice(1, 0, { $match: match });
|
||||
}
|
||||
} else {
|
||||
const match = {};
|
||||
match[filterKey] = discriminatorValue;
|
||||
originalPipeline.unshift({ $match: match });
|
||||
}
|
||||
}
|
||||
};
|
||||
50
backend/node_modules/mongoose/lib/helpers/aggregate/stringifyFunctionOperators.js
generated
vendored
Normal file
50
backend/node_modules/mongoose/lib/helpers/aggregate/stringifyFunctionOperators.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function stringifyFunctionOperators(pipeline) {
|
||||
if (!Array.isArray(pipeline)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const stage of pipeline) {
|
||||
if (stage == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const canHaveAccumulator = stage.$group || stage.$bucket || stage.$bucketAuto;
|
||||
if (canHaveAccumulator != null) {
|
||||
for (const key of Object.keys(canHaveAccumulator)) {
|
||||
handleAccumulator(canHaveAccumulator[key]);
|
||||
}
|
||||
}
|
||||
|
||||
const stageType = Object.keys(stage)[0];
|
||||
if (stageType && typeof stage[stageType] === 'object') {
|
||||
const stageOptions = stage[stageType];
|
||||
for (const key of Object.keys(stageOptions)) {
|
||||
if (stageOptions[key] != null &&
|
||||
stageOptions[key].$function != null &&
|
||||
typeof stageOptions[key].$function.body === 'function') {
|
||||
stageOptions[key].$function.body = stageOptions[key].$function.body.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stage.$facet != null) {
|
||||
for (const key of Object.keys(stage.$facet)) {
|
||||
stringifyFunctionOperators(stage.$facet[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function handleAccumulator(operator) {
|
||||
if (operator == null || operator.$accumulator == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of ['init', 'accumulate', 'merge', 'finalize']) {
|
||||
if (typeof operator.$accumulator[key] === 'function') {
|
||||
operator.$accumulator[key] = String(operator.$accumulator[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
33
backend/node_modules/mongoose/lib/helpers/arrayDepth.js
generated
vendored
Normal file
33
backend/node_modules/mongoose/lib/helpers/arrayDepth.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = arrayDepth;
|
||||
|
||||
function arrayDepth(arr) {
|
||||
if (!Array.isArray(arr)) {
|
||||
return { min: 0, max: 0, containsNonArrayItem: true };
|
||||
}
|
||||
if (arr.length === 0) {
|
||||
return { min: 1, max: 1, containsNonArrayItem: false };
|
||||
}
|
||||
if (arr.length === 1 && !Array.isArray(arr[0])) {
|
||||
return { min: 1, max: 1, containsNonArrayItem: false };
|
||||
}
|
||||
|
||||
const res = arrayDepth(arr[0]);
|
||||
|
||||
for (let i = 1; i < arr.length; ++i) {
|
||||
const _res = arrayDepth(arr[i]);
|
||||
if (_res.min < res.min) {
|
||||
res.min = _res.min;
|
||||
}
|
||||
if (_res.max > res.max) {
|
||||
res.max = _res.max;
|
||||
}
|
||||
res.containsNonArrayItem = res.containsNonArrayItem || _res.containsNonArrayItem;
|
||||
}
|
||||
|
||||
res.min = res.min + 1;
|
||||
res.max = res.max + 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
24
backend/node_modules/mongoose/lib/helpers/buildMiddlewareFilter.js
generated
vendored
Normal file
24
backend/node_modules/mongoose/lib/helpers/buildMiddlewareFilter.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const symbols = require('../schema/symbols');
|
||||
|
||||
/**
|
||||
* Filter predicate that returns true for built-in middleware (marked with `builtInMiddleware` symbol).
|
||||
*/
|
||||
const isBuiltInMiddleware = hook => hook.fn[symbols.builtInMiddleware];
|
||||
|
||||
/**
|
||||
* Builds a filter for kareem's execPre/execPost based on middleware options.
|
||||
*
|
||||
* @param {object} options - Options object that may contain `middleware` setting
|
||||
* @param {string} phase - Either 'pre' or 'post'
|
||||
* @returns {Function|null} - null runs all middleware, isBuiltInMiddleware skips user middleware
|
||||
*/
|
||||
function buildMiddlewareFilter(options, phase) {
|
||||
const shouldRun = options?.middleware?.[phase] ?? options?.middleware ?? true;
|
||||
return shouldRun ? null : isBuiltInMiddleware;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildMiddlewareFilter
|
||||
};
|
||||
236
backend/node_modules/mongoose/lib/helpers/clone.js
generated
vendored
Normal file
236
backend/node_modules/mongoose/lib/helpers/clone.js
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
'use strict';
|
||||
|
||||
const Decimal = require('../types/decimal128');
|
||||
const ObjectId = require('../types/objectid');
|
||||
const specialProperties = require('./specialProperties');
|
||||
const isMongooseObject = require('./isMongooseObject');
|
||||
const getFunctionName = require('./getFunctionName');
|
||||
const isBsonType = require('./isBsonType');
|
||||
const isMongooseArray = require('../types/array/isMongooseArray').isMongooseArray;
|
||||
const isObject = require('./isObject');
|
||||
const isPOJO = require('./isPOJO');
|
||||
const symbols = require('./symbols');
|
||||
const trustedSymbol = require('./query/trusted').trustedSymbol;
|
||||
const BSON = require('mongodb/lib/bson');
|
||||
const UUID = BSON.UUID;
|
||||
|
||||
const Binary = BSON.Binary;
|
||||
|
||||
/**
|
||||
* Object clone with Mongoose natives support.
|
||||
*
|
||||
* If options.minimize is true, creates a minimal data object. Empty objects and undefined values will not be cloned. This makes the data payload sent to MongoDB as small as possible.
|
||||
*
|
||||
* Functions and primitives are never cloned.
|
||||
*
|
||||
* @param {object} obj the object to clone
|
||||
* @param {object} options
|
||||
* @param {boolean} isArrayChild true if cloning immediately underneath an array. Special case for minimize.
|
||||
* @return {object} the cloned object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function clone(obj, options, isArrayChild) {
|
||||
if (obj == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (isBsonType(obj, 'Double')) {
|
||||
return new BSON.Double(obj.value);
|
||||
}
|
||||
if (typeof obj === 'number' || typeof obj === 'string' || typeof obj === 'boolean' || typeof obj === 'bigint') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
return cloneArray(obj, options);
|
||||
}
|
||||
|
||||
if (isMongooseObject(obj)) {
|
||||
if (options) {
|
||||
if (options.flattenUUIDs) {
|
||||
if (obj instanceof Binary && obj._subtype === Binary.SUBTYPE_UUID) {
|
||||
return obj.toString();
|
||||
}
|
||||
if (obj?.isMongooseBuffer && obj._subtype === Binary.SUBTYPE_UUID) {
|
||||
return obj.toUUID().toString();
|
||||
}
|
||||
}
|
||||
if (options.retainDocuments && obj.$__ != null) {
|
||||
const clonedDoc = obj.$clone();
|
||||
if (obj.__index != null) {
|
||||
clonedDoc.__index = obj.__index;
|
||||
}
|
||||
if (obj.__parentArray != null) {
|
||||
clonedDoc.__parentArray = options.parentArray ?? obj.__parentArray;
|
||||
}
|
||||
clonedDoc.$__setParent(options.parentDoc ?? obj.$__parent);
|
||||
return clonedDoc;
|
||||
}
|
||||
if (options.retainDocuments && obj.$isMongooseMap) {
|
||||
const clonedParent = options.parentDoc ?? obj.$__parent;
|
||||
const MongooseMap = obj.constructor;
|
||||
const ret = new MongooseMap({}, obj.$__path, clonedParent, obj.$__schemaType);
|
||||
for (const [key, value] of obj) {
|
||||
ret.$__set(key, clone(value, { ...options, parentDoc: clonedParent }));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (isPOJO(obj) && obj.$__ != null && obj._doc != null) {
|
||||
return obj._doc;
|
||||
}
|
||||
|
||||
let ret;
|
||||
if (options?.json && typeof obj.toJSON === 'function') {
|
||||
ret = obj.toJSON(options);
|
||||
} else {
|
||||
ret = obj.toObject(options);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const objConstructor = obj.constructor;
|
||||
|
||||
if (objConstructor) {
|
||||
switch (getFunctionName(objConstructor)) {
|
||||
case 'Object':
|
||||
return cloneObject(obj, options, isArrayChild);
|
||||
case 'Date':
|
||||
return new objConstructor(+obj);
|
||||
case 'RegExp':
|
||||
return cloneRegExp(obj);
|
||||
default:
|
||||
// ignore
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBsonType(obj, 'ObjectId')) {
|
||||
if (options?.flattenObjectIds) {
|
||||
return obj.toJSON();
|
||||
}
|
||||
return new ObjectId(obj.id);
|
||||
}
|
||||
|
||||
if (isBsonType(obj, 'Decimal128')) {
|
||||
if (options?.flattenDecimals) {
|
||||
return obj.toJSON();
|
||||
}
|
||||
return Decimal.fromString(obj.toString());
|
||||
}
|
||||
|
||||
if (obj instanceof UUID) {
|
||||
if (options?.flattenUUIDs) {
|
||||
return obj.toJSON();
|
||||
}
|
||||
return new UUID(obj.buffer);
|
||||
}
|
||||
|
||||
// object created with Object.create(null)
|
||||
if (!objConstructor && isObject(obj)) {
|
||||
return cloneObject(obj, options, isArrayChild);
|
||||
}
|
||||
|
||||
if (typeof obj === 'object' && obj[symbols.schemaTypeSymbol]) {
|
||||
return obj.clone();
|
||||
}
|
||||
|
||||
// If we're cloning this object to go into a MongoDB command,
|
||||
// and there's a `toBSON()` function, assume this object will be
|
||||
// stored as a primitive in MongoDB and doesn't need to be cloned.
|
||||
if (options?.bson && typeof obj.toBSON === 'function') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (typeof obj.valueOf === 'function') {
|
||||
return obj.valueOf();
|
||||
}
|
||||
|
||||
return cloneObject(obj, options, isArrayChild);
|
||||
}
|
||||
module.exports = clone;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function cloneObject(obj, options, isArrayChild) {
|
||||
const minimize = options?.minimize;
|
||||
const omitUndefined = options?.omitUndefined;
|
||||
const seen = options?._seen;
|
||||
const ret = {};
|
||||
let hasKeys;
|
||||
|
||||
if (seen && seen.has(obj)) {
|
||||
return seen.get(obj);
|
||||
} else if (seen) {
|
||||
seen.set(obj, ret);
|
||||
}
|
||||
if (trustedSymbol in obj && options?.copyTrustedSymbol !== false) {
|
||||
ret[trustedSymbol] = obj[trustedSymbol];
|
||||
}
|
||||
|
||||
const keys = Object.keys(obj);
|
||||
const len = keys.length;
|
||||
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const key = keys[i];
|
||||
if (specialProperties.has(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't pass `isArrayChild` down
|
||||
const val = clone(obj[key], options, false);
|
||||
|
||||
if ((minimize === false || omitUndefined) && typeof val === 'undefined') {
|
||||
delete ret[key];
|
||||
} else if (minimize !== true || (typeof val !== 'undefined')) {
|
||||
hasKeys || (hasKeys = true);
|
||||
ret[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return minimize && !isArrayChild ? hasKeys && ret : ret;
|
||||
}
|
||||
|
||||
function cloneArray(arr, options) {
|
||||
let i = 0;
|
||||
const len = arr.length;
|
||||
|
||||
let ret = null;
|
||||
if (options?.retainDocuments) {
|
||||
if (arr.isMongooseDocumentArray) {
|
||||
ret = new (arr.$schemaType().schema.base.Types.DocumentArray)([], arr.$path(), arr.$parent(), arr.$schemaType());
|
||||
} else if (arr.isMongooseArray) {
|
||||
ret = new (arr.$parent().schema.base.Types.Array)([], arr.$path(), arr.$parent(), arr.$schemaType());
|
||||
} else {
|
||||
ret = new Array(len);
|
||||
}
|
||||
} else {
|
||||
ret = new Array(len);
|
||||
}
|
||||
|
||||
arr = isMongooseArray(arr) ? arr.__array : arr;
|
||||
if (ret.isMongooseDocumentArray) {
|
||||
// Create new options object to avoid mutating the shared options.
|
||||
// Subdocs need parentArray to point to their own cloned array.
|
||||
options = { ...options, parentArray: ret };
|
||||
}
|
||||
for (i = 0; i < len; ++i) {
|
||||
ret[i] = clone(arr[i], options, true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function cloneRegExp(regexp) {
|
||||
const ret = new RegExp(regexp.source, regexp.flags);
|
||||
|
||||
if (ret.lastIndex !== regexp.lastIndex) {
|
||||
ret.lastIndex = regexp.lastIndex;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
127
backend/node_modules/mongoose/lib/helpers/common.js
generated
vendored
Normal file
127
backend/node_modules/mongoose/lib/helpers/common.js
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const Binary = require('mongodb/lib/bson').Binary;
|
||||
const isBsonType = require('./isBsonType');
|
||||
const isMongooseObject = require('./isMongooseObject');
|
||||
const MongooseError = require('../error');
|
||||
const util = require('util');
|
||||
|
||||
exports.flatten = flatten;
|
||||
exports.modifiedPaths = modifiedPaths;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function flatten(update, path, options, schema) {
|
||||
let keys;
|
||||
if (update && isMongooseObject(update) && !Buffer.isBuffer(update)) {
|
||||
keys = Object.keys(update.toObject({ transform: false, virtuals: false }) || {});
|
||||
} else {
|
||||
keys = Object.keys(update || {});
|
||||
}
|
||||
|
||||
const numKeys = keys.length;
|
||||
const result = {};
|
||||
path = path ? path + '.' : '';
|
||||
|
||||
for (let i = 0; i < numKeys; ++i) {
|
||||
const key = keys[i];
|
||||
const val = update[key];
|
||||
result[path + key] = val;
|
||||
|
||||
// Avoid going into mixed paths if schema is specified
|
||||
const keySchema = schema?.path?.(path + key);
|
||||
const isNested = schema?.nested?.[path + key];
|
||||
if (keySchema?.instance === 'Mixed') continue;
|
||||
|
||||
if (shouldFlatten(val)) {
|
||||
if (options?.skipArrays && Array.isArray(val)) {
|
||||
continue;
|
||||
}
|
||||
const flat = flatten(val, path + key, options, schema);
|
||||
for (const k in flat) {
|
||||
result[k] = flat[k];
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
result[path + key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (isNested) {
|
||||
const paths = Object.keys(schema.paths);
|
||||
for (const p of paths) {
|
||||
if (p.startsWith(path + key + '.') && !Object.hasOwn(result, p)) {
|
||||
result[p] = void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function modifiedPaths(update, path, result, recursion = null) {
|
||||
if (update == null || typeof update !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (recursion == null) {
|
||||
recursion = {
|
||||
raw: { update, path },
|
||||
trace: new WeakSet()
|
||||
};
|
||||
}
|
||||
|
||||
if (recursion.trace.has(update)) {
|
||||
throw new MongooseError(`a circular reference in the update value, updateValue:
|
||||
${util.inspect(recursion.raw.update, { showHidden: false, depth: 1 })}
|
||||
updatePath: '${recursion.raw.path}'`);
|
||||
}
|
||||
recursion.trace.add(update);
|
||||
|
||||
const keys = Object.keys(update || {});
|
||||
const numKeys = keys.length;
|
||||
result = result || {};
|
||||
path = path ? path + '.' : '';
|
||||
|
||||
for (let i = 0; i < numKeys; ++i) {
|
||||
const key = keys[i];
|
||||
let val = update[key];
|
||||
|
||||
const _path = path + key;
|
||||
result[_path] = true;
|
||||
if (!Buffer.isBuffer(val) && isMongooseObject(val)) {
|
||||
val = val.toObject({ transform: false, virtuals: false });
|
||||
}
|
||||
if (shouldFlatten(val)) {
|
||||
modifiedPaths(val, path + key, result, recursion);
|
||||
}
|
||||
}
|
||||
recursion.trace.delete(update);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function shouldFlatten(val) {
|
||||
return val &&
|
||||
typeof val === 'object' &&
|
||||
!(val instanceof Date) &&
|
||||
!isBsonType(val, 'ObjectId') &&
|
||||
(!Array.isArray(val) || val.length !== 0) &&
|
||||
!(val instanceof Buffer) &&
|
||||
!isBsonType(val, 'Decimal128') &&
|
||||
!(val instanceof Binary);
|
||||
}
|
||||
24
backend/node_modules/mongoose/lib/helpers/createJSONSchemaTypeDefinition.js
generated
vendored
Normal file
24
backend/node_modules/mongoose/lib/helpers/createJSONSchemaTypeDefinition.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Handles creating `{ type: 'object' }` vs `{ bsonType: 'object' }` vs `{ bsonType: ['object', 'null'] }`
|
||||
*
|
||||
* @param {string} type
|
||||
* @param {string} bsonType
|
||||
* @param {boolean} useBsonType
|
||||
* @param {boolean} isRequired
|
||||
*/
|
||||
|
||||
module.exports = function createJSONSchemaTypeArray(type, bsonType, useBsonType, isRequired) {
|
||||
if (useBsonType) {
|
||||
if (isRequired) {
|
||||
return { bsonType };
|
||||
}
|
||||
return { bsonType: [bsonType, 'null'] };
|
||||
} else {
|
||||
if (isRequired) {
|
||||
return { type };
|
||||
}
|
||||
return { type: [type, 'null'] };
|
||||
}
|
||||
};
|
||||
225
backend/node_modules/mongoose/lib/helpers/cursor/eachAsync.js
generated
vendored
Normal file
225
backend/node_modules/mongoose/lib/helpers/cursor/eachAsync.js
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const EachAsyncMultiError = require('../../error/eachAsyncMultiError');
|
||||
const immediate = require('../immediate');
|
||||
|
||||
/**
|
||||
* Execute `fn` for every document in the cursor. If `fn` returns a promise,
|
||||
* will wait for the promise to resolve before iterating on to the next one.
|
||||
* Returns a promise that resolves when done.
|
||||
*
|
||||
* @param {Function} next the thunk to call to get the next document
|
||||
* @param {Function} fn
|
||||
* @param {object} options
|
||||
* @param {number} [options.batchSize=null] if set, Mongoose will call `fn` with an array of at most `batchSize` documents, instead of a single document
|
||||
* @param {number} [options.parallel=1] maximum number of `fn` calls that Mongoose will run in parallel
|
||||
* @param {AbortSignal} [options.signal] allow cancelling this eachAsync(). Once the abort signal is fired, `eachAsync()` will immediately fulfill the returned promise (or call the callback) and not fetch any more documents.
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method eachAsync
|
||||
*/
|
||||
|
||||
module.exports = async function eachAsync(next, fn, options) {
|
||||
const parallel = options.parallel || 1;
|
||||
const batchSize = options.batchSize;
|
||||
const signal = options.signal;
|
||||
const continueOnError = options.continueOnError;
|
||||
const aggregatedErrors = [];
|
||||
const enqueue = asyncQueue();
|
||||
|
||||
let aborted = false;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (signal != null) {
|
||||
if (signal.aborted) {
|
||||
return resolve(null);
|
||||
}
|
||||
|
||||
signal.addEventListener('abort', () => {
|
||||
aborted = true;
|
||||
return resolve(null);
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
if (batchSize != null) {
|
||||
if (typeof batchSize !== 'number') {
|
||||
throw new TypeError('batchSize must be a number');
|
||||
} else if (!Number.isInteger(batchSize)) {
|
||||
throw new TypeError('batchSize must be an integer');
|
||||
} else if (batchSize < 1) {
|
||||
throw new TypeError('batchSize must be at least 1');
|
||||
}
|
||||
}
|
||||
|
||||
iterate((err, res) => {
|
||||
if (err != null) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
|
||||
function iterate(finalCallback) {
|
||||
let handleResultsInProgress = 0;
|
||||
let currentDocumentIndex = 0;
|
||||
|
||||
let error = null;
|
||||
for (let i = 0; i < parallel; ++i) {
|
||||
enqueue(createFetch());
|
||||
}
|
||||
|
||||
function createFetch() {
|
||||
let documentsBatch = [];
|
||||
let drained = false;
|
||||
|
||||
return fetch;
|
||||
|
||||
function fetch(done) {
|
||||
if (drained || aborted) {
|
||||
return done();
|
||||
} else if (error) {
|
||||
return done();
|
||||
}
|
||||
|
||||
next(function(err, doc) {
|
||||
if (error != null) {
|
||||
return done();
|
||||
}
|
||||
if (err != null) {
|
||||
if (err.name === 'MongoCursorExhaustedError') {
|
||||
// We may end up calling `next()` multiple times on an exhausted
|
||||
// cursor, which leads to an error. In case cursor is exhausted,
|
||||
// just treat it as if the cursor returned no document, which is
|
||||
// how a cursor indicates it is exhausted.
|
||||
doc = null;
|
||||
} else if (continueOnError) {
|
||||
aggregatedErrors.push(err);
|
||||
} else {
|
||||
error = err;
|
||||
finalCallback(err);
|
||||
return done();
|
||||
}
|
||||
}
|
||||
if (doc == null) {
|
||||
drained = true;
|
||||
if (handleResultsInProgress <= 0) {
|
||||
const finalErr = continueOnError ?
|
||||
createEachAsyncMultiError(aggregatedErrors) :
|
||||
error;
|
||||
|
||||
finalCallback(finalErr);
|
||||
} else if (batchSize && documentsBatch.length) {
|
||||
handleNextResult(documentsBatch, currentDocumentIndex++, handleNextResultCallBack);
|
||||
}
|
||||
return done();
|
||||
}
|
||||
|
||||
++handleResultsInProgress;
|
||||
|
||||
// Kick off the subsequent `next()` before handling the result, but
|
||||
// make sure we know that we still have a result to handle re: #8422
|
||||
immediate(() => done());
|
||||
|
||||
if (batchSize) {
|
||||
documentsBatch.push(doc);
|
||||
}
|
||||
|
||||
// If the current documents size is less than the provided batch size don't process the documents yet
|
||||
if (batchSize && documentsBatch.length !== batchSize) {
|
||||
immediate(() => enqueue(fetch));
|
||||
return;
|
||||
}
|
||||
|
||||
const docsToProcess = batchSize ? documentsBatch : doc;
|
||||
|
||||
function handleNextResultCallBack(err) {
|
||||
if (batchSize) {
|
||||
handleResultsInProgress -= documentsBatch.length;
|
||||
documentsBatch = [];
|
||||
} else {
|
||||
--handleResultsInProgress;
|
||||
}
|
||||
if (err != null) {
|
||||
if (continueOnError) {
|
||||
aggregatedErrors.push(err);
|
||||
} else {
|
||||
error = err;
|
||||
return finalCallback(err);
|
||||
}
|
||||
}
|
||||
if ((drained || aborted) && handleResultsInProgress <= 0) {
|
||||
const finalErr = continueOnError ?
|
||||
createEachAsyncMultiError(aggregatedErrors) :
|
||||
error;
|
||||
return finalCallback(finalErr);
|
||||
}
|
||||
|
||||
immediate(() => enqueue(fetch));
|
||||
}
|
||||
|
||||
handleNextResult(docsToProcess, currentDocumentIndex++, handleNextResultCallBack);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleNextResult(doc, i, callback) {
|
||||
let maybePromise;
|
||||
try {
|
||||
maybePromise = fn(doc, i);
|
||||
} catch (err) {
|
||||
return callback(err);
|
||||
}
|
||||
if (typeof maybePromise?.then === 'function') {
|
||||
maybePromise.then(
|
||||
function() { callback(null); },
|
||||
function(error) {
|
||||
callback(error || new Error('`eachAsync()` promise rejected without error'));
|
||||
});
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// `next()` can only execute one at a time, so make sure we always execute
|
||||
// `next()` in series, while still allowing multiple `fn()` instances to run
|
||||
// in parallel.
|
||||
function asyncQueue() {
|
||||
const _queue = [];
|
||||
let inProgress = null;
|
||||
let id = 0;
|
||||
|
||||
return function enqueue(fn) {
|
||||
if (
|
||||
inProgress === null &&
|
||||
_queue.length === 0
|
||||
) {
|
||||
inProgress = id++;
|
||||
return fn(_step);
|
||||
}
|
||||
_queue.push(fn);
|
||||
};
|
||||
|
||||
function _step() {
|
||||
if (_queue.length !== 0) {
|
||||
inProgress = id++;
|
||||
const fn = _queue.shift();
|
||||
fn(_step);
|
||||
} else {
|
||||
inProgress = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createEachAsyncMultiError(aggregatedErrors) {
|
||||
if (aggregatedErrors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new EachAsyncMultiError(aggregatedErrors);
|
||||
}
|
||||
36
backend/node_modules/mongoose/lib/helpers/discriminator/applyEmbeddedDiscriminators.js
generated
vendored
Normal file
36
backend/node_modules/mongoose/lib/helpers/discriminator/applyEmbeddedDiscriminators.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = applyEmbeddedDiscriminators;
|
||||
|
||||
function applyEmbeddedDiscriminators(schema, seen = new WeakSet(), overwriteExisting = false) {
|
||||
if (seen.has(schema)) {
|
||||
return;
|
||||
}
|
||||
seen.add(schema);
|
||||
for (const path of Object.keys(schema.paths)) {
|
||||
const schemaType = schema.paths[path];
|
||||
if (!schemaType.schema) {
|
||||
continue;
|
||||
}
|
||||
applyEmbeddedDiscriminators(schemaType.schema, seen);
|
||||
if (!schemaType.schema._applyDiscriminators) {
|
||||
continue;
|
||||
}
|
||||
if (schemaType._appliedDiscriminators && !overwriteExisting) {
|
||||
continue;
|
||||
}
|
||||
for (const discriminatorKey of schemaType.schema._applyDiscriminators.keys()) {
|
||||
const {
|
||||
schema: discriminatorSchema,
|
||||
options
|
||||
} = schemaType.schema._applyDiscriminators.get(discriminatorKey);
|
||||
applyEmbeddedDiscriminators(discriminatorSchema, seen);
|
||||
schemaType.discriminator(
|
||||
discriminatorKey,
|
||||
discriminatorSchema,
|
||||
overwriteExisting ? { ...options, overwriteExisting: true } : options
|
||||
);
|
||||
}
|
||||
schemaType._appliedDiscriminators = true;
|
||||
}
|
||||
}
|
||||
16
backend/node_modules/mongoose/lib/helpers/discriminator/areDiscriminatorValuesEqual.js
generated
vendored
Normal file
16
backend/node_modules/mongoose/lib/helpers/discriminator/areDiscriminatorValuesEqual.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
'use strict';
|
||||
|
||||
const isBsonType = require('../isBsonType');
|
||||
|
||||
module.exports = function areDiscriminatorValuesEqual(a, b) {
|
||||
if (typeof a === 'string' && typeof b === 'string') {
|
||||
return a === b;
|
||||
}
|
||||
if (typeof a === 'number' && typeof b === 'number') {
|
||||
return a === b;
|
||||
}
|
||||
if (isBsonType(a, 'ObjectId') && isBsonType(b, 'ObjectId')) {
|
||||
return a.toString() === b.toString();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
12
backend/node_modules/mongoose/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js
generated
vendored
Normal file
12
backend/node_modules/mongoose/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function checkEmbeddedDiscriminatorKeyProjection(userProjection, path, schema, selected, addedPaths) {
|
||||
const userProjectedInPath = Object.keys(userProjection).
|
||||
reduce((cur, key) => cur || key.startsWith(path + '.'), false);
|
||||
const _discriminatorKey = path + '.' + schema.options.discriminatorKey;
|
||||
if (!userProjectedInPath &&
|
||||
addedPaths.length === 1 &&
|
||||
addedPaths[0] === _discriminatorKey) {
|
||||
selected.splice(selected.indexOf(_discriminatorKey), 1);
|
||||
}
|
||||
};
|
||||
29
backend/node_modules/mongoose/lib/helpers/discriminator/getConstructor.js
generated
vendored
Normal file
29
backend/node_modules/mongoose/lib/helpers/discriminator/getConstructor.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const getDiscriminatorByValue = require('./getDiscriminatorByValue');
|
||||
|
||||
/**
|
||||
* Find the correct constructor, taking into account discriminators
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function getConstructor(Constructor, value, defaultDiscriminatorValue) {
|
||||
const discriminatorKey = Constructor.schema.options.discriminatorKey;
|
||||
let discriminatorValue = value?.[discriminatorKey];
|
||||
if (discriminatorValue == null) {
|
||||
discriminatorValue = defaultDiscriminatorValue;
|
||||
}
|
||||
if (Constructor.discriminators &&
|
||||
discriminatorValue != null) {
|
||||
if (Constructor.discriminators[discriminatorValue]) {
|
||||
Constructor = Constructor.discriminators[discriminatorValue];
|
||||
} else {
|
||||
const constructorByValue = getDiscriminatorByValue(Constructor.discriminators, discriminatorValue);
|
||||
if (constructorByValue) {
|
||||
Constructor = constructorByValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Constructor;
|
||||
};
|
||||
28
backend/node_modules/mongoose/lib/helpers/discriminator/getDiscriminatorByValue.js
generated
vendored
Normal file
28
backend/node_modules/mongoose/lib/helpers/discriminator/getDiscriminatorByValue.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const areDiscriminatorValuesEqual = require('./areDiscriminatorValuesEqual');
|
||||
|
||||
/**
|
||||
* returns discriminator by discriminatorMapping.value
|
||||
*
|
||||
* @param {object} discriminators
|
||||
* @param {string} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function getDiscriminatorByValue(discriminators, value) {
|
||||
if (discriminators == null) {
|
||||
return null;
|
||||
}
|
||||
for (const name of Object.keys(discriminators)) {
|
||||
const it = discriminators[name];
|
||||
if (
|
||||
it.schema &&
|
||||
it.schema.discriminatorMapping &&
|
||||
areDiscriminatorValuesEqual(it.schema.discriminatorMapping.value, value)
|
||||
) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
27
backend/node_modules/mongoose/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js
generated
vendored
Normal file
27
backend/node_modules/mongoose/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const areDiscriminatorValuesEqual = require('./areDiscriminatorValuesEqual');
|
||||
|
||||
/**
|
||||
* returns discriminator by discriminatorMapping.value
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {string} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function getSchemaDiscriminatorByValue(schema, value) {
|
||||
if (schema?.discriminators == null) {
|
||||
return null;
|
||||
}
|
||||
for (const key of Object.keys(schema.discriminators)) {
|
||||
const discriminatorSchema = schema.discriminators[key];
|
||||
if (discriminatorSchema.discriminatorMapping == null) {
|
||||
continue;
|
||||
}
|
||||
if (areDiscriminatorValuesEqual(discriminatorSchema.discriminatorMapping.value, value)) {
|
||||
return discriminatorSchema;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
96
backend/node_modules/mongoose/lib/helpers/discriminator/mergeDiscriminatorSchema.js
generated
vendored
Normal file
96
backend/node_modules/mongoose/lib/helpers/discriminator/mergeDiscriminatorSchema.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
'use strict';
|
||||
const schemaMerge = require('../schema/merge');
|
||||
const specialProperties = require('../../helpers/specialProperties');
|
||||
const isBsonType = require('../../helpers/isBsonType');
|
||||
const ObjectId = require('../../types/objectid');
|
||||
const SchemaType = require('../../schemaType');
|
||||
const isObject = require('../../helpers/isObject');
|
||||
/**
|
||||
* Merges `from` into `to` without overwriting existing properties.
|
||||
*
|
||||
* @param {object} to
|
||||
* @param {object} from
|
||||
* @param {string} [path]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function mergeDiscriminatorSchema(to, from, path, seen) {
|
||||
const keys = Object.keys(from);
|
||||
let i = 0;
|
||||
const len = keys.length;
|
||||
let key;
|
||||
|
||||
path = path || '';
|
||||
seen = seen || new WeakSet();
|
||||
|
||||
if (seen.has(from)) {
|
||||
return;
|
||||
}
|
||||
seen.add(from);
|
||||
|
||||
while (i < len) {
|
||||
key = keys[i++];
|
||||
if (!path) {
|
||||
if (key === 'discriminators' ||
|
||||
key === 'base' ||
|
||||
key === '_applyDiscriminators' ||
|
||||
key === '_userProvidedOptions' ||
|
||||
key === 'options' ||
|
||||
key === 'tree') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (path === 'tree' && from?.instanceOfSchema) {
|
||||
continue;
|
||||
}
|
||||
if (specialProperties.has(key)) {
|
||||
continue;
|
||||
}
|
||||
if (key === 'parentSchema') {
|
||||
// Skip parentSchema to avoid merging parent schema multiple times
|
||||
// through child paths' back-references (gh-15966)
|
||||
continue;
|
||||
}
|
||||
if (to[key] == null) {
|
||||
to[key] = from[key];
|
||||
} else if (isObject(from[key])) {
|
||||
if (!isObject(to[key])) {
|
||||
to[key] = {};
|
||||
}
|
||||
if (from[key] != null) {
|
||||
// Skip merging schemas if we're creating a discriminator schema and
|
||||
// base schema has a given path as a single nested but discriminator schema
|
||||
// has the path as a document array, or vice versa (gh-9534)
|
||||
if ((from[key].$isSingleNested && to[key].$isMongooseDocumentArray) ||
|
||||
(from[key].$isMongooseDocumentArray && to[key].$isSingleNested) ||
|
||||
(from[key].$isMongooseDocumentArrayElement && to[key].$isMongooseDocumentArrayElement)) {
|
||||
continue;
|
||||
} else if (from[key].instanceOfSchema) {
|
||||
if (to[key].instanceOfSchema) {
|
||||
schemaMerge(to[key], from[key].clone(), true);
|
||||
} else {
|
||||
to[key] = from[key].clone();
|
||||
}
|
||||
continue;
|
||||
} else if (isBsonType(from[key], 'ObjectId')) {
|
||||
to[key] = new ObjectId(from[key]);
|
||||
continue;
|
||||
} else if (from[key] instanceof SchemaType) {
|
||||
if (to[key] == null) {
|
||||
to[key] = from[key].clone();
|
||||
}
|
||||
// For container types with nested schemas, we need to continue to the
|
||||
// recursive merge below to properly merge the nested schemas
|
||||
if (!from[key].$isMongooseDocumentArray && !from[key].$isSingleNested) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
mergeDiscriminatorSchema(to[key], from[key], path ? path + '.' + key : key, seen);
|
||||
}
|
||||
}
|
||||
|
||||
if (from?.instanceOfSchema) {
|
||||
to.tree = Object.assign({}, from.tree, to.tree);
|
||||
}
|
||||
};
|
||||
132
backend/node_modules/mongoose/lib/helpers/document/applyDefaults.js
generated
vendored
Normal file
132
backend/node_modules/mongoose/lib/helpers/document/applyDefaults.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
'use strict';
|
||||
|
||||
const isNestedProjection = require('../projection/isNestedProjection');
|
||||
|
||||
module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSetters, pathsToSkip, options) {
|
||||
const paths = Object.keys(doc.$__schema.paths);
|
||||
const plen = paths.length;
|
||||
const skipParentChangeTracking = options?.skipParentChangeTracking;
|
||||
|
||||
for (let i = 0; i < plen; ++i) {
|
||||
let def;
|
||||
let curPath = '';
|
||||
const p = paths[i];
|
||||
|
||||
if (p === '_id' && doc.$__.skipId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const type = doc.$__schema.paths[p];
|
||||
const path = type.splitPath();
|
||||
const len = path.length;
|
||||
if (path[len - 1] === '$*') {
|
||||
continue;
|
||||
}
|
||||
let included = false;
|
||||
let doc_ = doc._doc;
|
||||
for (let j = 0; j < len; ++j) {
|
||||
if (doc_ == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
const piece = path[j];
|
||||
curPath += (!curPath.length ? '' : '.') + piece;
|
||||
|
||||
if (exclude === true) {
|
||||
if (curPath in fields) {
|
||||
break;
|
||||
}
|
||||
} else if (exclude === false && fields && !included) {
|
||||
const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray;
|
||||
if ((curPath in fields && !isNestedProjection(fields[curPath])) || (j === len - 1 && hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
|
||||
included = true;
|
||||
} else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j === len - 1) {
|
||||
if (doc_[piece] !== void 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isBeforeSetters != null) {
|
||||
if (typeof type.defaultValue === 'function') {
|
||||
if (!type.defaultValue.$runBeforeSetters && isBeforeSetters) {
|
||||
break;
|
||||
}
|
||||
if (type.defaultValue.$runBeforeSetters && !isBeforeSetters) {
|
||||
break;
|
||||
}
|
||||
} else if (!isBeforeSetters) {
|
||||
// Non-function defaults should always run **before** setters
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (pathsToSkip && pathsToSkip[curPath]) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (fields && exclude !== null) {
|
||||
if (exclude === true) {
|
||||
// apply defaults to all non-excluded fields
|
||||
if (p in fields) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
def = type.getDefault(doc, false);
|
||||
} catch (err) {
|
||||
doc.invalidate(p, err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof def !== 'undefined') {
|
||||
doc_[piece] = def;
|
||||
applyChangeTracking(doc, p, skipParentChangeTracking);
|
||||
}
|
||||
} else if (included) {
|
||||
// selected field
|
||||
try {
|
||||
def = type.getDefault(doc, false);
|
||||
} catch (err) {
|
||||
doc.invalidate(p, err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof def !== 'undefined') {
|
||||
doc_[piece] = def;
|
||||
applyChangeTracking(doc, p, skipParentChangeTracking);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
def = type.getDefault(doc, false);
|
||||
} catch (err) {
|
||||
doc.invalidate(p, err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof def !== 'undefined') {
|
||||
doc_[piece] = def;
|
||||
applyChangeTracking(doc, p, skipParentChangeTracking);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
doc_ = doc_[piece];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function applyChangeTracking(doc, fullPath, skipParentChangeTracking) {
|
||||
doc.$__.activePaths.default(fullPath);
|
||||
if (!skipParentChangeTracking && doc.$isSubdocument && doc.$isSingleNested && doc.$parent() != null) {
|
||||
doc.$parent().$__.activePaths.default(doc.$__pathRelativeToParent(fullPath));
|
||||
}
|
||||
}
|
||||
106
backend/node_modules/mongoose/lib/helpers/document/applyTimestamps.js
generated
vendored
Normal file
106
backend/node_modules/mongoose/lib/helpers/document/applyTimestamps.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
'use strict';
|
||||
|
||||
const handleTimestampOption = require('../schema/handleTimestampOption');
|
||||
const mpath = require('mpath');
|
||||
const utils = require('../../utils');
|
||||
|
||||
module.exports = applyTimestamps;
|
||||
|
||||
/**
|
||||
* Apply a given schema's timestamps to the given POJO
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {object} obj
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.isUpdate=false] if true, treat this as an update: just set updatedAt, skip setting createdAt. If false, set both createdAt and updatedAt
|
||||
* @param {Function} [options.currentTime] if set, Mongoose will call this function to get the current time.
|
||||
*/
|
||||
|
||||
function applyTimestamps(schema, obj, options) {
|
||||
if (obj == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
applyTimestampsToChildren(schema, obj, options);
|
||||
return applyTimestampsToDoc(schema, obj, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply timestamps to any subdocuments
|
||||
*
|
||||
* @param {Schema} schema subdocument schema
|
||||
* @param {object} res subdocument
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.isUpdate=false] if true, treat this as an update: just set updatedAt, skip setting createdAt. If false, set both createdAt and updatedAt
|
||||
* @param {Function} [options.currentTime] if set, Mongoose will call this function to get the current time.
|
||||
*/
|
||||
|
||||
function applyTimestampsToChildren(schema, res, options) {
|
||||
for (const childSchema of schema.childSchemas) {
|
||||
const _path = childSchema.model.path;
|
||||
const _schema = childSchema.schema;
|
||||
if (!_path) {
|
||||
continue;
|
||||
}
|
||||
const _obj = mpath.get(_path, res);
|
||||
if (_obj == null || (Array.isArray(_obj) && _obj.flat(Infinity).length === 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
applyTimestamps(_schema, _obj, options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply timestamps to a given document. Does not apply timestamps to subdocuments: use `applyTimestampsToChildren` instead
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {object} obj
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.isUpdate=false] if true, treat this as an update: just set updatedAt, skip setting createdAt. If false, set both createdAt and updatedAt
|
||||
* @param {Function} [options.currentTime] if set, Mongoose will call this function to get the current time.
|
||||
*/
|
||||
|
||||
function applyTimestampsToDoc(schema, obj, options) {
|
||||
if (obj == null || typeof obj !== 'object') {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(obj)) {
|
||||
for (const el of obj) {
|
||||
applyTimestampsToDoc(schema, el, options);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (schema.discriminators && utils.hasOwnKeys(schema.discriminators)) {
|
||||
for (const discriminatorKey of Object.keys(schema.discriminators)) {
|
||||
const discriminator = schema.discriminators[discriminatorKey];
|
||||
const key = discriminator.discriminatorMapping.key;
|
||||
const value = discriminator.discriminatorMapping.value;
|
||||
if (obj[key] == value) {
|
||||
schema = discriminator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const createdAt = handleTimestampOption(schema.options.timestamps, 'createdAt');
|
||||
const updatedAt = handleTimestampOption(schema.options.timestamps, 'updatedAt');
|
||||
const currentTime = options?.currentTime;
|
||||
|
||||
let ts = null;
|
||||
if (currentTime != null) {
|
||||
ts = currentTime();
|
||||
} else if (schema.base?.now) {
|
||||
ts = schema.base.now();
|
||||
} else {
|
||||
ts = new Date();
|
||||
}
|
||||
|
||||
if (createdAt && obj[createdAt] == null && !options?.isUpdate) {
|
||||
obj[createdAt] = ts;
|
||||
}
|
||||
if (updatedAt) {
|
||||
obj[updatedAt] = ts;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user