notherbase-fs 4.0.22 → 4.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/controllers/creation.js +147 -147
- package/controllers/spirit-world.js +174 -174
- package/controllers/user.js +240 -240
- package/controllers/util.js +64 -64
- package/models/index.js +33 -33
- package/models/send-mail.js +58 -58
- package/models/spirit.js +234 -234
- package/notherbase-fs.js +112 -112
- package/package.json +40 -40
- package/public/js/base.js +222 -227
- package/public/js/chat-box.js +120 -120
- package/test/coast/tall-beach/nono-cove/index.css +17 -17
- package/test/coast/tall-beach/nono-cove/index.ejs +29 -29
- package/test/coast/tall-beach/nono-cove/nono-og/add-gold.js +15 -15
- package/test/coast/tall-beach/nono-cove/nono-og/index.ejs +46 -46
- package/test/coast/tall-beach/nono-cove/nono-og/nono.css +88 -88
- package/test/coast/tall-beach/nono-cove/nono-og/nono.js +207 -207
- package/test/pages/test-page/emailTime.js +8 -8
- package/test/pages/test-page/index.ejs +104 -104
- package/test/pages/void/index.ejs +35 -35
- package/test/pages/void/void.css +2 -2
- package/test/public/styles/main.css +792 -792
- package/test/the-front/add-gold.js +13 -13
- package/test/the-front/check/check.css +2 -2
- package/test/the-front/check/emailTime.js +9 -9
- package/test/the-front/check/flip.js +9 -9
- package/test/the-front/check/index.ejs +54 -54
- package/test/the-front/check/save-input.js +7 -7
- package/test/the-front/index.ejs +116 -99
- package/test/the-front/keeper/clipboards.js +133 -133
- package/test/the-front/keeper/index.ejs +80 -80
- package/test/the-front/keeper/keeper.css +157 -157
- package/test/the-front/keeper/keeper.js +140 -140
- package/test-index.js +19 -19
- package/test2/pages/test-page/emailTime.js +8 -8
- package/test2/pages/test-page/index.ejs +104 -104
- package/test2/pages/void/index.ejs +35 -35
- package/test2/pages/void/void.css +2 -2
- package/test2/public/styles/main.css +792 -792
- package/test2/the-front/add-gold.js +13 -13
- package/test2/the-front/check/check.css +2 -2
- package/test2/the-front/check/emailTime.js +9 -9
- package/test2/the-front/check/flip.js +9 -9
- package/test2/the-front/check/index.ejs +54 -54
- package/test2/the-front/check/save-input.js +7 -7
- package/test2/the-front/index.ejs +99 -99
- package/test2/the-front/keeper/clipboards.js +133 -133
- package/test2/the-front/keeper/index.ejs +80 -80
- package/test2/the-front/keeper/keeper.css +157 -157
- package/test2/the-front/keeper/keeper.js +140 -140
- package/views/explorer.ejs +82 -82
- package/views/footer.ejs +9 -9
- package/views/head.ejs +17 -17
package/models/index.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import mongoose from "mongoose";
|
|
2
|
-
import dotenv from "dotenv";
|
|
3
|
-
dotenv.config();
|
|
4
|
-
import Spirit from "./spirit.js";
|
|
5
|
-
import SendMail from "./send-mail.js";
|
|
6
|
-
|
|
7
|
-
mongoose.set('strictQuery', true);
|
|
8
|
-
|
|
9
|
-
mongoose.connection.on('connected', (err) => {
|
|
10
|
-
console.log(`Mongoose connected to db`);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
mongoose.connection.on('error', (err) => {
|
|
14
|
-
console.log(`Mongoose ${err}`);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
mongoose.connection.on('disconnected', () => {
|
|
18
|
-
console.log('Mongoose disconnected');
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
mongoose.connect(process.env.MONGODB_URI, {
|
|
23
|
-
useNewUrlParser: true,
|
|
24
|
-
useUnifiedTopology: true
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
catch (err) {
|
|
28
|
-
console.log(`Mongoose on connect: ${err}`);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default {
|
|
32
|
-
SendMail: SendMail,
|
|
33
|
-
Spirit: Spirit
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
dotenv.config();
|
|
4
|
+
import Spirit from "./spirit.js";
|
|
5
|
+
import SendMail from "./send-mail.js";
|
|
6
|
+
|
|
7
|
+
mongoose.set('strictQuery', true);
|
|
8
|
+
|
|
9
|
+
mongoose.connection.on('connected', (err) => {
|
|
10
|
+
console.log(`Mongoose connected to db`);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
mongoose.connection.on('error', (err) => {
|
|
14
|
+
console.log(`Mongoose ${err}`);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
mongoose.connection.on('disconnected', () => {
|
|
18
|
+
console.log('Mongoose disconnected');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
mongoose.connect(process.env.MONGODB_URI, {
|
|
23
|
+
useNewUrlParser: true,
|
|
24
|
+
useUnifiedTopology: true
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.log(`Mongoose on connect: ${err}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default {
|
|
32
|
+
SendMail: SendMail,
|
|
33
|
+
Spirit: Spirit
|
|
34
34
|
}
|
package/models/send-mail.js
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import dotenv from "dotenv";
|
|
2
|
-
dotenv.config();
|
|
3
|
-
import nodemailer from "nodemailer";
|
|
4
|
-
import { google } from "googleapis";
|
|
5
|
-
|
|
6
|
-
const OAuth2 = google.auth.OAuth2;
|
|
7
|
-
const OAuth2Client = new OAuth2(process.env.CLIENTID, process.env.CLIENTSECRET);
|
|
8
|
-
OAuth2Client.setCredentials({ refresh_token: process.env.CLIENTREFRESH });
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Sends an email with a password reset code. WIP
|
|
13
|
-
* @param {String} toEmail Email address to send to.
|
|
14
|
-
* @param {Number} resetToken Token to reset by.
|
|
15
|
-
*/
|
|
16
|
-
const passwordReset = async (toEmail, resetToken) => {
|
|
17
|
-
return await send(toEmail, 'Password Reset for NotherBase',
|
|
18
|
-
`<h1>Your One-Time Password Reset Code:<h1>
|
|
19
|
-
<h2>${resetToken}<h2>
|
|
20
|
-
<p>Visit <a href="https://www.notherbase.com/the-front/keeper">notherbase.com/the-front/keeper</a> to finish changing your password.</p>`);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Sends an email. WIP
|
|
25
|
-
* @param {String} toEmail Email Address to send to.
|
|
26
|
-
* @param {String} subject Subject of the email.
|
|
27
|
-
* @param {String} html Body of the email.
|
|
28
|
-
* @returns
|
|
29
|
-
*/
|
|
30
|
-
const send = async (toEmail, subject, html, name = "NotherBase") => {
|
|
31
|
-
let accessToken = OAuth2Client.getAccessToken();
|
|
32
|
-
|
|
33
|
-
let transporter = nodemailer.createTransport({
|
|
34
|
-
service: 'gmail',
|
|
35
|
-
auth: {
|
|
36
|
-
type: 'OAuth2',
|
|
37
|
-
user: process.env.NOREPLY,
|
|
38
|
-
clientId: process.env.CLIENTID,
|
|
39
|
-
clientSecret: process.env.CLIENTSECRET,
|
|
40
|
-
refreshToken: process.env.CLIENTREFRESH,
|
|
41
|
-
accessToken: accessToken
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
let mailOptions = {
|
|
46
|
-
from: name + " <" + process.env.NOREPLY +">",
|
|
47
|
-
to: toEmail,
|
|
48
|
-
subject: subject,
|
|
49
|
-
html: html
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
let sent = await transporter.sendMail(mailOptions, function(error, info){
|
|
53
|
-
if (error) console.log(error);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
return sent;
|
|
57
|
-
}
|
|
58
|
-
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
dotenv.config();
|
|
3
|
+
import nodemailer from "nodemailer";
|
|
4
|
+
import { google } from "googleapis";
|
|
5
|
+
|
|
6
|
+
const OAuth2 = google.auth.OAuth2;
|
|
7
|
+
const OAuth2Client = new OAuth2(process.env.CLIENTID, process.env.CLIENTSECRET);
|
|
8
|
+
OAuth2Client.setCredentials({ refresh_token: process.env.CLIENTREFRESH });
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Sends an email with a password reset code. WIP
|
|
13
|
+
* @param {String} toEmail Email address to send to.
|
|
14
|
+
* @param {Number} resetToken Token to reset by.
|
|
15
|
+
*/
|
|
16
|
+
const passwordReset = async (toEmail, resetToken) => {
|
|
17
|
+
return await send(toEmail, 'Password Reset for NotherBase',
|
|
18
|
+
`<h1>Your One-Time Password Reset Code:<h1>
|
|
19
|
+
<h2>${resetToken}<h2>
|
|
20
|
+
<p>Visit <a href="https://www.notherbase.com/the-front/keeper">notherbase.com/the-front/keeper</a> to finish changing your password.</p>`);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Sends an email. WIP
|
|
25
|
+
* @param {String} toEmail Email Address to send to.
|
|
26
|
+
* @param {String} subject Subject of the email.
|
|
27
|
+
* @param {String} html Body of the email.
|
|
28
|
+
* @returns
|
|
29
|
+
*/
|
|
30
|
+
const send = async (toEmail, subject, html, name = "NotherBase") => {
|
|
31
|
+
let accessToken = OAuth2Client.getAccessToken();
|
|
32
|
+
|
|
33
|
+
let transporter = nodemailer.createTransport({
|
|
34
|
+
service: 'gmail',
|
|
35
|
+
auth: {
|
|
36
|
+
type: 'OAuth2',
|
|
37
|
+
user: process.env.NOREPLY,
|
|
38
|
+
clientId: process.env.CLIENTID,
|
|
39
|
+
clientSecret: process.env.CLIENTSECRET,
|
|
40
|
+
refreshToken: process.env.CLIENTREFRESH,
|
|
41
|
+
accessToken: accessToken
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
let mailOptions = {
|
|
46
|
+
from: name + " <" + process.env.NOREPLY +">",
|
|
47
|
+
to: toEmail,
|
|
48
|
+
subject: subject,
|
|
49
|
+
html: html
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
let sent = await transporter.sendMail(mailOptions, function(error, info){
|
|
53
|
+
if (error) console.log(error);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return sent;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
59
|
export default { passwordReset, send };
|
package/models/spirit.js
CHANGED
|
@@ -1,235 +1,235 @@
|
|
|
1
|
-
import mongoose from "mongoose";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Curated Mongoose.js documents for use in bases.
|
|
5
|
-
*/
|
|
6
|
-
export default class Spirit {
|
|
7
|
-
// The actual Mongoose.js model for accessing the database.
|
|
8
|
-
static db = mongoose.model('spirits', new mongoose.Schema({
|
|
9
|
-
_lastUpdate: Number,
|
|
10
|
-
service: String,
|
|
11
|
-
parent: {
|
|
12
|
-
type: mongoose.Schema.Types.ObjectId,
|
|
13
|
-
ref: "spirits",
|
|
14
|
-
required: false
|
|
15
|
-
},
|
|
16
|
-
data: {},
|
|
17
|
-
backups: []
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Builds query objects for Mongoose.js searches.
|
|
22
|
-
* @param {String} service The name of the spirit.
|
|
23
|
-
* @param {Object} data An object with data to query the spirit by.
|
|
24
|
-
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
25
|
-
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
26
|
-
* @returns A query object.
|
|
27
|
-
*/
|
|
28
|
-
static buildQuery = (service, data = null, parent = null, id = null) => {
|
|
29
|
-
let query = {
|
|
30
|
-
parent: parent
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
if (service) query.service = service;
|
|
34
|
-
if (id) query._id = id;
|
|
35
|
-
else if (data){
|
|
36
|
-
let keys = Object.keys(data);
|
|
37
|
-
for (let i = 0; i < keys.length; i++) {
|
|
38
|
-
query[`data.${keys[i]}`] = data[keys[i]];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return query;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// static buildBackupQuery = (service, data = null, parent = null, id = null) => {
|
|
46
|
-
// let query = {
|
|
47
|
-
// service: service,
|
|
48
|
-
// parent: parent
|
|
49
|
-
// };
|
|
50
|
-
|
|
51
|
-
// if (id) query._id = id;
|
|
52
|
-
// else if (data){
|
|
53
|
-
// let keys = Object.keys(data);
|
|
54
|
-
// for (let i = 0; i < keys.length; i++) {
|
|
55
|
-
|
|
56
|
-
// query[`data.backups.0.data.${keys[i]}`] = data[keys[i]];
|
|
57
|
-
// }
|
|
58
|
-
// }
|
|
59
|
-
|
|
60
|
-
// return query;
|
|
61
|
-
// }
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Creates a spirit in the database.
|
|
65
|
-
* @param {String} service The name of the spirit.
|
|
66
|
-
* @param {Object} data An object with data to create the spirit with.
|
|
67
|
-
* @param {ObjectID} parent The MongoDB id of the parent of the spirit to be created.
|
|
68
|
-
* @returns A new spirit.
|
|
69
|
-
*/
|
|
70
|
-
static create = async (service, data = {}, parent = null) => {
|
|
71
|
-
let spirit = new Spirit();
|
|
72
|
-
|
|
73
|
-
spirit.memory = await Spirit.db.create({
|
|
74
|
-
service,
|
|
75
|
-
parent,
|
|
76
|
-
_lastUpdate: Date.now(),
|
|
77
|
-
data: data,
|
|
78
|
-
backups: []
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
return spirit;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Recalls all spirits in the database with a given name.
|
|
86
|
-
* @param {String} service The name of the spirit.
|
|
87
|
-
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
88
|
-
* @param {Object} data An object with data to query the spirit by.
|
|
89
|
-
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
90
|
-
* @returns All spirits found.
|
|
91
|
-
*/
|
|
92
|
-
static recallAll = async (service, parent = null, data = {}, id = null) => {
|
|
93
|
-
let spirits = [];
|
|
94
|
-
|
|
95
|
-
let query = Spirit.buildQuery(service, data, parent, id);
|
|
96
|
-
|
|
97
|
-
let found = await Spirit.db.find(query);
|
|
98
|
-
|
|
99
|
-
if (found) {
|
|
100
|
-
for (let i = 0; i < found.length; i++) {
|
|
101
|
-
let spirit = new Spirit(found[i]);
|
|
102
|
-
spirits.push(spirit);
|
|
103
|
-
// convert old backups to new format
|
|
104
|
-
if (spirit.memory.data?._backupsEnabled) {
|
|
105
|
-
spirit.memory.backups = spirit.memory.data.backups;
|
|
106
|
-
spirit.memory.data = spirit.memory.backups[0].data;
|
|
107
|
-
spirit.memory.markModified("backups");
|
|
108
|
-
await spirit.commit();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return spirits;
|
|
113
|
-
}
|
|
114
|
-
else return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Recalls one spirit from the database or creates a new one.
|
|
119
|
-
* @param {String} service The name of the spirit.
|
|
120
|
-
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
121
|
-
* @param {Object} data An object with data to query the spirit by.
|
|
122
|
-
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
123
|
-
* @returns The spirit found or a new one created in the database.
|
|
124
|
-
*/
|
|
125
|
-
static recallOne = async (service, parent = null, data = {}, id = null) => {
|
|
126
|
-
let spirit = null;
|
|
127
|
-
|
|
128
|
-
let query = Spirit.buildQuery(service, data, parent, id);
|
|
129
|
-
|
|
130
|
-
let found = await Spirit.db.findOne(query);
|
|
131
|
-
|
|
132
|
-
if (found) {
|
|
133
|
-
spirit = new Spirit(found);
|
|
134
|
-
|
|
135
|
-
// convert old backups to new format
|
|
136
|
-
if (spirit.memory.data?._backupsEnabled) {
|
|
137
|
-
spirit.memory.backups = spirit.memory.data.backups;
|
|
138
|
-
spirit.memory.data = spirit.memory.backups[0].data;
|
|
139
|
-
spirit.memory.markModified("backups");
|
|
140
|
-
await spirit.commit();
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return spirit;
|
|
144
|
-
}
|
|
145
|
-
else return null;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Recalls or creates a spirit in the database.
|
|
150
|
-
* @param {String} service The name of the spirit.
|
|
151
|
-
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
152
|
-
* @param {Object} data An object with data to query the spirit by.
|
|
153
|
-
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
154
|
-
* @returns The spirit found or a new one created in the database.
|
|
155
|
-
*/
|
|
156
|
-
static recallOrCreateOne = async (service, parent = null, data = {}, id = null) => {
|
|
157
|
-
let spirit = null;
|
|
158
|
-
|
|
159
|
-
let query = Spirit.buildQuery(service, data, parent, id);
|
|
160
|
-
|
|
161
|
-
let found = await Spirit.db.findOne(query);
|
|
162
|
-
|
|
163
|
-
if (found) spirit = new Spirit(found);
|
|
164
|
-
else spirit = await Spirit.create(service, data, parent);
|
|
165
|
-
|
|
166
|
-
// convert old backups to new format
|
|
167
|
-
if (spirit.memory.data?._backupsEnabled) {
|
|
168
|
-
spirit.memory.backups = spirit.memory.data.backups;
|
|
169
|
-
spirit.memory.data = spirit.memory.backups[0].data;
|
|
170
|
-
spirit.memory.markModified("backups");
|
|
171
|
-
await spirit.commit();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return spirit;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Deletes all of the specified spirit.
|
|
179
|
-
* @param {String} service The name of the spirit.
|
|
180
|
-
* @param {ObjectID} parent The MongoDB id of the parent spirit to search with.
|
|
181
|
-
* @param {Object} data An object with data to query the spirit by.
|
|
182
|
-
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
183
|
-
* @returns The number of documents deleted.
|
|
184
|
-
*/
|
|
185
|
-
static delete = async (service, parent = null, data = {}, id = null) => {
|
|
186
|
-
let found = await Spirit.db.deleteMany(Spirit.buildQuery(service, data, parent, id));
|
|
187
|
-
|
|
188
|
-
return found.deletedCount;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
constructor(memory = {}) {
|
|
192
|
-
this.memory = memory;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Commits new data to a spirit.
|
|
197
|
-
* @param {Object} data Data to save.
|
|
198
|
-
* @returns Updated
|
|
199
|
-
*/
|
|
200
|
-
commit = async (data = this.memory.data) => {
|
|
201
|
-
this.memory._lastUpdate = Date.now();
|
|
202
|
-
|
|
203
|
-
this.memory.data = data;
|
|
204
|
-
this.memory.markModified("data");
|
|
205
|
-
await this.memory.save();
|
|
206
|
-
|
|
207
|
-
return "Updated";
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Normalizes the data property to an array.
|
|
212
|
-
*/
|
|
213
|
-
normalizeDataToArray = () => {
|
|
214
|
-
if (!Array.isArray(this.memory.data)) this.memory.data = [];
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Adds a new backup to the spirit's data.
|
|
219
|
-
* @param {Object} data Data to add to the backup.
|
|
220
|
-
*/
|
|
221
|
-
addBackup = (data, max = 5) => {
|
|
222
|
-
this.memory.backups.unshift({
|
|
223
|
-
_lastUpdate: Date.now(),
|
|
224
|
-
data: this.memory.data
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
this.memory.data = data;
|
|
228
|
-
|
|
229
|
-
if (max > 1) {
|
|
230
|
-
while (this.memory.backups.length > max) this.memory.backups.pop();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
this.memory.markModified("backups");
|
|
234
|
-
}
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Curated Mongoose.js documents for use in bases.
|
|
5
|
+
*/
|
|
6
|
+
export default class Spirit {
|
|
7
|
+
// The actual Mongoose.js model for accessing the database.
|
|
8
|
+
static db = mongoose.model('spirits', new mongoose.Schema({
|
|
9
|
+
_lastUpdate: Number,
|
|
10
|
+
service: String,
|
|
11
|
+
parent: {
|
|
12
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
13
|
+
ref: "spirits",
|
|
14
|
+
required: false
|
|
15
|
+
},
|
|
16
|
+
data: {},
|
|
17
|
+
backups: []
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Builds query objects for Mongoose.js searches.
|
|
22
|
+
* @param {String} service The name of the spirit.
|
|
23
|
+
* @param {Object} data An object with data to query the spirit by.
|
|
24
|
+
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
25
|
+
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
26
|
+
* @returns A query object.
|
|
27
|
+
*/
|
|
28
|
+
static buildQuery = (service, data = null, parent = null, id = null) => {
|
|
29
|
+
let query = {
|
|
30
|
+
parent: parent
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
if (service) query.service = service;
|
|
34
|
+
if (id) query._id = id;
|
|
35
|
+
else if (data){
|
|
36
|
+
let keys = Object.keys(data);
|
|
37
|
+
for (let i = 0; i < keys.length; i++) {
|
|
38
|
+
query[`data.${keys[i]}`] = data[keys[i]];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return query;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// static buildBackupQuery = (service, data = null, parent = null, id = null) => {
|
|
46
|
+
// let query = {
|
|
47
|
+
// service: service,
|
|
48
|
+
// parent: parent
|
|
49
|
+
// };
|
|
50
|
+
|
|
51
|
+
// if (id) query._id = id;
|
|
52
|
+
// else if (data){
|
|
53
|
+
// let keys = Object.keys(data);
|
|
54
|
+
// for (let i = 0; i < keys.length; i++) {
|
|
55
|
+
|
|
56
|
+
// query[`data.backups.0.data.${keys[i]}`] = data[keys[i]];
|
|
57
|
+
// }
|
|
58
|
+
// }
|
|
59
|
+
|
|
60
|
+
// return query;
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Creates a spirit in the database.
|
|
65
|
+
* @param {String} service The name of the spirit.
|
|
66
|
+
* @param {Object} data An object with data to create the spirit with.
|
|
67
|
+
* @param {ObjectID} parent The MongoDB id of the parent of the spirit to be created.
|
|
68
|
+
* @returns A new spirit.
|
|
69
|
+
*/
|
|
70
|
+
static create = async (service, data = {}, parent = null) => {
|
|
71
|
+
let spirit = new Spirit();
|
|
72
|
+
|
|
73
|
+
spirit.memory = await Spirit.db.create({
|
|
74
|
+
service,
|
|
75
|
+
parent,
|
|
76
|
+
_lastUpdate: Date.now(),
|
|
77
|
+
data: data,
|
|
78
|
+
backups: []
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return spirit;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Recalls all spirits in the database with a given name.
|
|
86
|
+
* @param {String} service The name of the spirit.
|
|
87
|
+
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
88
|
+
* @param {Object} data An object with data to query the spirit by.
|
|
89
|
+
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
90
|
+
* @returns All spirits found.
|
|
91
|
+
*/
|
|
92
|
+
static recallAll = async (service, parent = null, data = {}, id = null) => {
|
|
93
|
+
let spirits = [];
|
|
94
|
+
|
|
95
|
+
let query = Spirit.buildQuery(service, data, parent, id);
|
|
96
|
+
|
|
97
|
+
let found = await Spirit.db.find(query);
|
|
98
|
+
|
|
99
|
+
if (found) {
|
|
100
|
+
for (let i = 0; i < found.length; i++) {
|
|
101
|
+
let spirit = new Spirit(found[i]);
|
|
102
|
+
spirits.push(spirit);
|
|
103
|
+
// convert old backups to new format
|
|
104
|
+
if (spirit.memory.data?._backupsEnabled) {
|
|
105
|
+
spirit.memory.backups = spirit.memory.data.backups;
|
|
106
|
+
spirit.memory.data = spirit.memory.backups[0].data;
|
|
107
|
+
spirit.memory.markModified("backups");
|
|
108
|
+
await spirit.commit();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return spirits;
|
|
113
|
+
}
|
|
114
|
+
else return null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Recalls one spirit from the database or creates a new one.
|
|
119
|
+
* @param {String} service The name of the spirit.
|
|
120
|
+
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
121
|
+
* @param {Object} data An object with data to query the spirit by.
|
|
122
|
+
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
123
|
+
* @returns The spirit found or a new one created in the database.
|
|
124
|
+
*/
|
|
125
|
+
static recallOne = async (service, parent = null, data = {}, id = null) => {
|
|
126
|
+
let spirit = null;
|
|
127
|
+
|
|
128
|
+
let query = Spirit.buildQuery(service, data, parent, id);
|
|
129
|
+
|
|
130
|
+
let found = await Spirit.db.findOne(query);
|
|
131
|
+
|
|
132
|
+
if (found) {
|
|
133
|
+
spirit = new Spirit(found);
|
|
134
|
+
|
|
135
|
+
// convert old backups to new format
|
|
136
|
+
if (spirit.memory.data?._backupsEnabled) {
|
|
137
|
+
spirit.memory.backups = spirit.memory.data.backups;
|
|
138
|
+
spirit.memory.data = spirit.memory.backups[0].data;
|
|
139
|
+
spirit.memory.markModified("backups");
|
|
140
|
+
await spirit.commit();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return spirit;
|
|
144
|
+
}
|
|
145
|
+
else return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Recalls or creates a spirit in the database.
|
|
150
|
+
* @param {String} service The name of the spirit.
|
|
151
|
+
* @param {ObjectID} parent The MongoDB id of the parent spirit to search by.
|
|
152
|
+
* @param {Object} data An object with data to query the spirit by.
|
|
153
|
+
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
154
|
+
* @returns The spirit found or a new one created in the database.
|
|
155
|
+
*/
|
|
156
|
+
static recallOrCreateOne = async (service, parent = null, data = {}, id = null) => {
|
|
157
|
+
let spirit = null;
|
|
158
|
+
|
|
159
|
+
let query = Spirit.buildQuery(service, data, parent, id);
|
|
160
|
+
|
|
161
|
+
let found = await Spirit.db.findOne(query);
|
|
162
|
+
|
|
163
|
+
if (found) spirit = new Spirit(found);
|
|
164
|
+
else spirit = await Spirit.create(service, data, parent);
|
|
165
|
+
|
|
166
|
+
// convert old backups to new format
|
|
167
|
+
if (spirit.memory.data?._backupsEnabled) {
|
|
168
|
+
spirit.memory.backups = spirit.memory.data.backups;
|
|
169
|
+
spirit.memory.data = spirit.memory.backups[0].data;
|
|
170
|
+
spirit.memory.markModified("backups");
|
|
171
|
+
await spirit.commit();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return spirit;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Deletes all of the specified spirit.
|
|
179
|
+
* @param {String} service The name of the spirit.
|
|
180
|
+
* @param {ObjectID} parent The MongoDB id of the parent spirit to search with.
|
|
181
|
+
* @param {Object} data An object with data to query the spirit by.
|
|
182
|
+
* @param {ObjectID} id The exact id of the MongoDB document.
|
|
183
|
+
* @returns The number of documents deleted.
|
|
184
|
+
*/
|
|
185
|
+
static delete = async (service, parent = null, data = {}, id = null) => {
|
|
186
|
+
let found = await Spirit.db.deleteMany(Spirit.buildQuery(service, data, parent, id));
|
|
187
|
+
|
|
188
|
+
return found.deletedCount;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
constructor(memory = {}) {
|
|
192
|
+
this.memory = memory;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Commits new data to a spirit.
|
|
197
|
+
* @param {Object} data Data to save.
|
|
198
|
+
* @returns Updated
|
|
199
|
+
*/
|
|
200
|
+
commit = async (data = this.memory.data) => {
|
|
201
|
+
this.memory._lastUpdate = Date.now();
|
|
202
|
+
|
|
203
|
+
this.memory.data = data;
|
|
204
|
+
this.memory.markModified("data");
|
|
205
|
+
await this.memory.save();
|
|
206
|
+
|
|
207
|
+
return "Updated";
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Normalizes the data property to an array.
|
|
212
|
+
*/
|
|
213
|
+
normalizeDataToArray = () => {
|
|
214
|
+
if (!Array.isArray(this.memory.data)) this.memory.data = [];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Adds a new backup to the spirit's data.
|
|
219
|
+
* @param {Object} data Data to add to the backup.
|
|
220
|
+
*/
|
|
221
|
+
addBackup = (data, max = 5) => {
|
|
222
|
+
this.memory.backups.unshift({
|
|
223
|
+
_lastUpdate: Date.now(),
|
|
224
|
+
data: this.memory.data
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
this.memory.data = data;
|
|
228
|
+
|
|
229
|
+
if (max > 1) {
|
|
230
|
+
while (this.memory.backups.length > max) this.memory.backups.pop();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this.memory.markModified("backups");
|
|
234
|
+
}
|
|
235
235
|
};
|