@joystick.js/cli-canary 0.0.0-canary.174 → 0.0.0-canary.176
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/_package.json +2 -2
- package/dist/lib/dev/databases/drivers/index.js +50 -0
- package/dist/lib/dev/databases/drivers/mongodb/availableQueryParameters.js +42 -0
- package/dist/lib/dev/databases/drivers/mongodb/buildConnectionString.js +22 -0
- package/dist/lib/dev/databases/drivers/mongodb/buildQueryParameters.js +14 -0
- package/dist/lib/dev/databases/drivers/mongodb/index.js +45 -0
- package/dist/lib/dev/databases/drivers/mongodb/queries/accounts.js +300 -0
- package/dist/lib/dev/databases/drivers/mongodb/queries/queues.js +115 -0
- package/dist/lib/dev/databases/drivers/postgresql/addColumnToTable.js +6 -0
- package/dist/lib/dev/databases/drivers/postgresql/createAccountsIndexes.js +21 -0
- package/dist/lib/dev/databases/drivers/postgresql/createAccountsTables.js +41 -0
- package/dist/lib/dev/databases/drivers/postgresql/createDatabase.js +0 -0
- package/dist/lib/dev/databases/drivers/postgresql/index.js +60 -0
- package/dist/lib/dev/databases/drivers/postgresql/queries/accounts.js +293 -0
- package/dist/lib/dev/databases/drivers/postgresql/queries/queues.js +211 -0
- package/dist/lib/dev/index.js +1 -1
- package/package.json +1 -1
- package/src/lib/dev/databases/drivers/index.js +83 -0
- package/src/lib/dev/databases/drivers/mongodb/availableQueryParameters.js +39 -0
- package/src/lib/dev/databases/drivers/mongodb/buildConnectionString.js +28 -0
- package/src/lib/dev/databases/drivers/mongodb/buildQueryParameters.js +15 -0
- package/src/lib/dev/databases/drivers/mongodb/index.js +43 -0
- package/src/lib/dev/databases/drivers/mongodb/queries/accounts.js +338 -0
- package/src/lib/dev/databases/drivers/mongodb/queries/queues.js +121 -0
- package/src/lib/dev/databases/drivers/postgresql/addColumnToTable.js +3 -0
- package/src/lib/dev/databases/drivers/postgresql/createAccountsIndexes.js +29 -0
- package/src/lib/dev/databases/drivers/postgresql/createAccountsTables.js +44 -0
- package/src/lib/dev/databases/drivers/postgresql/createDatabase.js +0 -0
- package/src/lib/dev/databases/drivers/postgresql/index.js +52 -0
- package/src/lib/dev/databases/drivers/postgresql/queries/accounts.js +341 -0
- package/src/lib/dev/databases/drivers/postgresql/queries/queues.js +219 -0
- package/src/lib/dev/index.js +2 -3
package/_package.json
CHANGED
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"kill-port-process": "^3.1.0",
|
|
41
41
|
"lodash": "^4.17.21",
|
|
42
42
|
"mongo-uri-tool": "^1.0.1",
|
|
43
|
-
"mongodb": "^4.
|
|
43
|
+
"mongodb": "^4.16.0",
|
|
44
44
|
"netstats": "^0.0.6",
|
|
45
45
|
"node-fetch": "^3.2.0",
|
|
46
46
|
"node-watch": "^0.7.2",
|
|
47
|
-
"pg": "^8.
|
|
47
|
+
"pg": "^8.11.2",
|
|
48
48
|
"port-pid": "^0.0.7",
|
|
49
49
|
"ps-node": "^0.1.6",
|
|
50
50
|
"replace-in-files": "^3.0.0",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import loadSettings from "../../loadSettings.js";
|
|
2
|
+
import connectMongoDB from "./mongodb/index.js";
|
|
3
|
+
import connectPostgreSQL from "./postgresql/index.js";
|
|
4
|
+
var drivers_default = async (callback) => {
|
|
5
|
+
const settings = (await loadSettings())?.parsed;
|
|
6
|
+
const databases = settings?.config?.databases?.map((database) => {
|
|
7
|
+
return {
|
|
8
|
+
provider: database?.provider,
|
|
9
|
+
settings: database
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
for (let databaseIndex = 0; databaseIndex < databases?.length; databaseIndex += 1) {
|
|
13
|
+
const database = databases[databaseIndex];
|
|
14
|
+
const hasMultipleOfProvider = databases?.filter((database2) => database2?.provider === database2?.provider)?.length > 1;
|
|
15
|
+
const databasePort = parseInt(process.env.PORT, 10) + 10 + databaseIndex;
|
|
16
|
+
if (database?.provider === "mongodb") {
|
|
17
|
+
const mongodb = await connectMongoDB(database?.settings, databasePort);
|
|
18
|
+
process.databases = {
|
|
19
|
+
...process.databases || {},
|
|
20
|
+
mongodb: !hasMultipleOfProvider ? mongodb : {
|
|
21
|
+
...process?.databases?.mongodb || {},
|
|
22
|
+
[database?.settings?.name || `mongodb_${databasePort}`]: mongodb
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (database?.provider === "postgresql") {
|
|
27
|
+
const postgresql = await connectPostgreSQL(
|
|
28
|
+
database?.settings,
|
|
29
|
+
databasePort
|
|
30
|
+
);
|
|
31
|
+
process.databases = {
|
|
32
|
+
...process.databases || {},
|
|
33
|
+
postgresql: !hasMultipleOfProvider ? {
|
|
34
|
+
...postgresql?.pool,
|
|
35
|
+
query: postgresql?.query
|
|
36
|
+
} : {
|
|
37
|
+
...process?.databases?.postgresql || {},
|
|
38
|
+
[database?.settings?.name || `postgresql_${databasePort}`]: {
|
|
39
|
+
...postgresql?.pool,
|
|
40
|
+
query: postgresql?.query
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return process.databases;
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
drivers_default as default
|
|
50
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var availableQueryParameters_default = [
|
|
2
|
+
"replicaSet",
|
|
3
|
+
"tls",
|
|
4
|
+
"ssl",
|
|
5
|
+
"tlsCertificateKeyFile",
|
|
6
|
+
"tlsCertificateKeyFilePassword",
|
|
7
|
+
"tlsCAFile",
|
|
8
|
+
"tlsAllowInvalidCertificates",
|
|
9
|
+
"tlsAllowInvalidHostnames",
|
|
10
|
+
"tlsInsecure",
|
|
11
|
+
"connectTimeoutMS",
|
|
12
|
+
"socketTimeoutMS",
|
|
13
|
+
"compressors",
|
|
14
|
+
"zlibCompressionLevel",
|
|
15
|
+
"maxPoolSize",
|
|
16
|
+
"minPoolSize",
|
|
17
|
+
"maxIdleTimeMS",
|
|
18
|
+
"waitQueueMultiple",
|
|
19
|
+
"waitQueueTimeoutMS",
|
|
20
|
+
"w",
|
|
21
|
+
"wtimeoutMS",
|
|
22
|
+
"journal",
|
|
23
|
+
"readConcernLevel",
|
|
24
|
+
"readPreference",
|
|
25
|
+
"maxStalenessSeconds",
|
|
26
|
+
"readPreferenceTags",
|
|
27
|
+
"authSource",
|
|
28
|
+
"authMechanism",
|
|
29
|
+
"authMechanismProperties",
|
|
30
|
+
"gssapiServiceName",
|
|
31
|
+
"localThresholdMS",
|
|
32
|
+
"serverSelectionTimeoutMS",
|
|
33
|
+
"serverSelectionTryOnce",
|
|
34
|
+
"heartbeatFrequencyMS",
|
|
35
|
+
"appName",
|
|
36
|
+
"retryReads",
|
|
37
|
+
"retryWrites",
|
|
38
|
+
"uuidRepresentation"
|
|
39
|
+
];
|
|
40
|
+
export {
|
|
41
|
+
availableQueryParameters_default as default
|
|
42
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import buildQueryParameters from "./buildQueryParameters.js";
|
|
2
|
+
import serializeQueryParameters from "../../../../serializeQueryParameters.js";
|
|
3
|
+
var buildConnectionString_default = (connection = {}) => {
|
|
4
|
+
let connectionString = "mongodb://";
|
|
5
|
+
if (connection && (connection.username || connection.password)) {
|
|
6
|
+
connectionString = `${connectionString}${connection.username || connection.password ? `${connection.username || ""}${!!connection.username && !!connection.password ? ":" : ""}${connection.password || ""}@` : ""}`;
|
|
7
|
+
}
|
|
8
|
+
if (connection && connection.hosts && Array.isArray(connection.hosts)) {
|
|
9
|
+
connectionString = `${connectionString}${connection.hosts.map((host) => `${host.hostname}:${host.port}`).join(",")}`;
|
|
10
|
+
}
|
|
11
|
+
if (connection && connection.database) {
|
|
12
|
+
connectionString = `${connectionString}/${connection.database}`;
|
|
13
|
+
}
|
|
14
|
+
const queryParameters = buildQueryParameters(connection);
|
|
15
|
+
if (Object.keys(queryParameters)?.length > 0) {
|
|
16
|
+
connectionString = `${connectionString}?${serializeQueryParameters(queryParameters)}`;
|
|
17
|
+
}
|
|
18
|
+
return connectionString;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
buildConnectionString_default as default
|
|
22
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import availableQueryParameters from "./availableQueryParameters.js";
|
|
2
|
+
var buildQueryParameters_default = (connection = {}) => {
|
|
3
|
+
const queryParameters = {};
|
|
4
|
+
for (let i = 0; i < availableQueryParameters.length; i += 1) {
|
|
5
|
+
const availableParameter = availableQueryParameters[i];
|
|
6
|
+
if (connection && connection[availableParameter]) {
|
|
7
|
+
queryParameters[availableParameter] = connection[availableParameter];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return queryParameters;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
buildQueryParameters_default as default
|
|
14
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MongoClient } from "mongodb";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import mongoUri from "mongo-uri-tool";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import buildConnectionString from "./buildConnectionString.js";
|
|
6
|
+
var mongodb_default = async (settings = {}, databasePort = 2610) => {
|
|
7
|
+
const connection = settings?.connection || {
|
|
8
|
+
hosts: [
|
|
9
|
+
// NOTE: By default, expect databases start from 2610 (assuming a PORT of 2600).
|
|
10
|
+
{ hostname: "127.0.0.1", port: databasePort }
|
|
11
|
+
],
|
|
12
|
+
database: "app",
|
|
13
|
+
replicaSet: `joystick_${databasePort}`
|
|
14
|
+
};
|
|
15
|
+
const connectionString = buildConnectionString(connection);
|
|
16
|
+
const parsedURI = mongoUri.parseUri(connectionString);
|
|
17
|
+
try {
|
|
18
|
+
const connectionOptions = {
|
|
19
|
+
useNewUrlParser: true,
|
|
20
|
+
useUnifiedTopology: true,
|
|
21
|
+
ssl: !["development", "test"].includes(process.env.NODE_ENV),
|
|
22
|
+
...settings?.options || {}
|
|
23
|
+
};
|
|
24
|
+
if (settings?.options?.ca) {
|
|
25
|
+
connectionOptions.ca = fs.readFileSync(settings?.options?.ca);
|
|
26
|
+
}
|
|
27
|
+
const client = await MongoClient.connect(connectionString, connectionOptions);
|
|
28
|
+
const db = client.db(parsedURI.db);
|
|
29
|
+
return db;
|
|
30
|
+
} catch (exception) {
|
|
31
|
+
console.warn(
|
|
32
|
+
chalk.yellowBright(
|
|
33
|
+
`
|
|
34
|
+
Failed to connect to MongoDB. Please double-check connection settings and try again.
|
|
35
|
+
|
|
36
|
+
Error from MongoDB:
|
|
37
|
+
|
|
38
|
+
${chalk.redBright(exception?.message)}`
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
mongodb_default as default
|
|
45
|
+
};
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import generateId from "../../../../lib/generateId";
|
|
2
|
+
import dayjs from "dayjs";
|
|
3
|
+
var accounts_default = {
|
|
4
|
+
existingUser: async (input = {}) => {
|
|
5
|
+
let existingUserWithEmailAddress;
|
|
6
|
+
let existingUserWithUsername;
|
|
7
|
+
if (input?.emailAddress) {
|
|
8
|
+
existingUserWithEmailAddress = await process.databases._users?.collection("users").findOne({ emailAddress: input.emailAddress });
|
|
9
|
+
}
|
|
10
|
+
if (input?.username) {
|
|
11
|
+
existingUserWithUsername = await process.databases._users?.collection("users").findOne({ username: input.username });
|
|
12
|
+
}
|
|
13
|
+
return existingUserWithEmailAddress || existingUserWithUsername ? {
|
|
14
|
+
existingEmailAddress: existingUserWithEmailAddress?.emailAddress,
|
|
15
|
+
existingUsername: existingUserWithUsername?.username
|
|
16
|
+
} : null;
|
|
17
|
+
},
|
|
18
|
+
createUser: async (input = {}) => {
|
|
19
|
+
const userId = generateId();
|
|
20
|
+
await process.databases._users?.collection("users").insertOne({ _id: userId, ...input });
|
|
21
|
+
return userId;
|
|
22
|
+
},
|
|
23
|
+
user: async (input) => {
|
|
24
|
+
if (input?.emailAddress) {
|
|
25
|
+
const user = await process.databases._users?.collection("users").findOne({ emailAddress: input.emailAddress });
|
|
26
|
+
return user;
|
|
27
|
+
}
|
|
28
|
+
if (input?.username) {
|
|
29
|
+
const user = await process.databases._users?.collection("users").findOne({ username: input.username });
|
|
30
|
+
return user;
|
|
31
|
+
}
|
|
32
|
+
if (input?._id) {
|
|
33
|
+
const user = await process.databases._users?.collection("users").findOne({ _id: input._id });
|
|
34
|
+
return user;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
},
|
|
38
|
+
deleteOldSessions: async (input = {}) => {
|
|
39
|
+
const user = await process.databases._users?.collection("users").findOne({
|
|
40
|
+
_id: input?.userId
|
|
41
|
+
});
|
|
42
|
+
if (user) {
|
|
43
|
+
const sessions = user?.sessions?.filter((session) => {
|
|
44
|
+
return dayjs(session?.tokenExpiresAt).isAfter(dayjs().utc().format());
|
|
45
|
+
});
|
|
46
|
+
await process.databases._users?.collection("users").updateOne(
|
|
47
|
+
{
|
|
48
|
+
_id: input.userId
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
$set: {
|
|
52
|
+
sessions
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
addSession: async (input = {}) => {
|
|
59
|
+
await process.databases._users?.collection("users").updateOne(
|
|
60
|
+
{
|
|
61
|
+
_id: input.userId
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
$addToSet: {
|
|
65
|
+
sessions: input.session
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
},
|
|
70
|
+
userWithLoginToken: async (input) => {
|
|
71
|
+
const user = await process.databases._users?.collection("users").findOne({
|
|
72
|
+
"sessions.token": input?.token
|
|
73
|
+
});
|
|
74
|
+
return user;
|
|
75
|
+
},
|
|
76
|
+
createVerifyEmailToken: async (input) => {
|
|
77
|
+
const token = generateId();
|
|
78
|
+
await process.databases._users?.collection("users").updateOne(
|
|
79
|
+
{
|
|
80
|
+
_id: input?.userId
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
$addToSet: {
|
|
84
|
+
verifyEmailTokens: {
|
|
85
|
+
userId: input?.userId,
|
|
86
|
+
token
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
return token;
|
|
92
|
+
},
|
|
93
|
+
userWithVerifyEmailToken: async (input) => {
|
|
94
|
+
const user = await process.databases._users?.collection("users").findOne({
|
|
95
|
+
"verifyEmailTokens.token": input?.token
|
|
96
|
+
});
|
|
97
|
+
return user;
|
|
98
|
+
},
|
|
99
|
+
markEmailVerifiedAt: async (input) => {
|
|
100
|
+
const user = await process.databases._users?.collection("users").findOne({
|
|
101
|
+
_id: input?.userId
|
|
102
|
+
});
|
|
103
|
+
await process.databases._users?.collection("users").updateOne(
|
|
104
|
+
{
|
|
105
|
+
_id: input?.userId
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
$set: {
|
|
109
|
+
emailVerified: true,
|
|
110
|
+
emailVerifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
111
|
+
verifyEmailTokens: user?.verifyEmailTokens?.filter(
|
|
112
|
+
(verifyEmailToken) => {
|
|
113
|
+
return verifyEmailToken?.token === input?.token;
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
return true;
|
|
120
|
+
},
|
|
121
|
+
addPasswordResetToken: (input = {}) => {
|
|
122
|
+
return process.databases._users?.collection("users").updateOne(
|
|
123
|
+
{
|
|
124
|
+
emailAddress: input.emailAddress
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
$addToSet: {
|
|
128
|
+
passwordResetTokens: {
|
|
129
|
+
token: input.token,
|
|
130
|
+
requestedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
userWithResetToken: async (input) => {
|
|
137
|
+
const user = await process.databases._users?.collection("users").findOne({
|
|
138
|
+
"passwordResetTokens.token": input["passwordResetTokens.token"]
|
|
139
|
+
});
|
|
140
|
+
return user;
|
|
141
|
+
},
|
|
142
|
+
setNewPassword: async (input = {}) => {
|
|
143
|
+
return process.databases._users?.collection("users").updateOne(
|
|
144
|
+
{
|
|
145
|
+
_id: input?.userId
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
$set: {
|
|
149
|
+
password: input?.hashedPassword
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
},
|
|
154
|
+
removeResetToken: async (input = {}) => {
|
|
155
|
+
const user = await process.databases._users?.collection("users").findOne({ _id: input?.userId });
|
|
156
|
+
await process.databases._users?.collection("users").updateOne(
|
|
157
|
+
{
|
|
158
|
+
_id: input?.userId
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
$set: {
|
|
162
|
+
passwordResetTokens: user?.passwordResetTokens?.filter(
|
|
163
|
+
({ token }) => {
|
|
164
|
+
return token !== input?.token;
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
return process.databases._users?.collection("users").findOne({ _id: input?.userId });
|
|
171
|
+
},
|
|
172
|
+
addRole: async (input = {}) => {
|
|
173
|
+
const existingRole = input?.role ? await process.databases._users?.collection("roles").findOne({ role: input?.role }) : null;
|
|
174
|
+
if (!existingRole && input?.role) {
|
|
175
|
+
await process.databases._users?.collection("roles").insertOne({
|
|
176
|
+
_id: generateId(),
|
|
177
|
+
role: input?.role
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
_id: input?.userId,
|
|
181
|
+
action: "add",
|
|
182
|
+
role: input?.role,
|
|
183
|
+
ok: true,
|
|
184
|
+
error: null
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
action: "add",
|
|
189
|
+
role: input?.role,
|
|
190
|
+
ok: false,
|
|
191
|
+
error: input?.role ? `Role already exists: ${input?.role}.` : `Must pass a name for role to add.`
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
removeRole: async (input = {}) => {
|
|
195
|
+
const existingRole = input?.role ? await process.databases._users?.collection("roles").findOne({ role: input?.role }) : null;
|
|
196
|
+
if (existingRole) {
|
|
197
|
+
await process.databases._users?.collection("users").updateMany(
|
|
198
|
+
{
|
|
199
|
+
roles: { $in: [input?.role] }
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
$pull: {
|
|
203
|
+
roles: input?.role
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
await process.databases._users?.collection("roles").deleteOne({
|
|
208
|
+
role: input?.role
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
_id: input?.userId,
|
|
212
|
+
action: "remove",
|
|
213
|
+
role: input?.role,
|
|
214
|
+
ok: true,
|
|
215
|
+
error: null
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
action: "add",
|
|
220
|
+
role: input?.role,
|
|
221
|
+
ok: false,
|
|
222
|
+
error: `Could not find an existing role with the name ${input?.role}.`
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
listRoles: async (input = {}) => {
|
|
226
|
+
const roles = await process.databases._users?.collection("roles").find().toArray();
|
|
227
|
+
return (roles || []).map(({ role }) => role);
|
|
228
|
+
},
|
|
229
|
+
grantRole: async (input = {}) => {
|
|
230
|
+
const user = await process.databases._users?.collection("users").findOne({ _id: input?.userId });
|
|
231
|
+
if (user) {
|
|
232
|
+
await process.databases._users?.collection("users").updateOne(
|
|
233
|
+
{ _id: input?.userId },
|
|
234
|
+
{
|
|
235
|
+
$addToSet: {
|
|
236
|
+
roles: input?.role
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
const existingRole = await process.databases._users?.collection("roles").findOne({ role: input?.role });
|
|
241
|
+
if (!existingRole) {
|
|
242
|
+
await process.databases._users?.collection("roles").insertOne({
|
|
243
|
+
_id: generateId(),
|
|
244
|
+
role: input?.role
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
_id: input?.userId,
|
|
249
|
+
action: "grant",
|
|
250
|
+
role: input?.role,
|
|
251
|
+
ok: true,
|
|
252
|
+
error: null
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
_id: input?.userId,
|
|
257
|
+
action: "grant",
|
|
258
|
+
role: input?.role,
|
|
259
|
+
ok: false,
|
|
260
|
+
error: `User not found with the _id ${input?.userId}.`
|
|
261
|
+
};
|
|
262
|
+
},
|
|
263
|
+
revokeRole: async (input = {}) => {
|
|
264
|
+
const user = await process.databases._users?.collection("users").findOne({ _id: input?.userId });
|
|
265
|
+
if (user && user.roles) {
|
|
266
|
+
await process.databases._users?.collection("users").updateOne(
|
|
267
|
+
{ _id: input?.userId },
|
|
268
|
+
{
|
|
269
|
+
$pull: {
|
|
270
|
+
roles: input?.role
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
);
|
|
274
|
+
return {
|
|
275
|
+
_id: input?.userId,
|
|
276
|
+
action: "revoke",
|
|
277
|
+
role: input?.role,
|
|
278
|
+
ok: true,
|
|
279
|
+
error: null
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
return {
|
|
283
|
+
_id: input?.userId,
|
|
284
|
+
action: "revoke",
|
|
285
|
+
role: input?.role,
|
|
286
|
+
ok: false,
|
|
287
|
+
error: `User not found with the _id ${input?.userId}.`
|
|
288
|
+
};
|
|
289
|
+
},
|
|
290
|
+
userHasRole: async (input = {}) => {
|
|
291
|
+
const user = await process.databases._users?.collection("users").findOne({ _id: input?.userId });
|
|
292
|
+
if (user && user.roles) {
|
|
293
|
+
return user?.roles?.includes(input?.role);
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
export {
|
|
299
|
+
accounts_default as default
|
|
300
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
var queues_default = {
|
|
3
|
+
addJob: function(jobToAdd = {}) {
|
|
4
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
5
|
+
return db.insertOne(jobToAdd);
|
|
6
|
+
},
|
|
7
|
+
countJobs: function(status = "") {
|
|
8
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
9
|
+
return db.countDocuments({ status });
|
|
10
|
+
},
|
|
11
|
+
deleteJob: function(jobId = "") {
|
|
12
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
13
|
+
return db.deleteOne({ _id: jobId });
|
|
14
|
+
},
|
|
15
|
+
getJobs: function(query = {}) {
|
|
16
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
17
|
+
return db.find(query).toArray();
|
|
18
|
+
},
|
|
19
|
+
getNextJobToRun: async function() {
|
|
20
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
21
|
+
const nextJob = await db.findOneAndUpdate({
|
|
22
|
+
$or: [
|
|
23
|
+
{
|
|
24
|
+
status: "pending",
|
|
25
|
+
// NOTE: Do this to avoid accidentally running jobs intended for the future too early.
|
|
26
|
+
nextRunAt: { $lte: dayjs().format() },
|
|
27
|
+
lockedBy: { $exists: false }
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
status: "pending",
|
|
31
|
+
// NOTE: Do this to avoid accidentally running jobs intended for the future too early.
|
|
32
|
+
nextRunAt: { $lte: dayjs().format() },
|
|
33
|
+
lockedBy: null
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}, {
|
|
37
|
+
$set: {
|
|
38
|
+
status: "running",
|
|
39
|
+
startedAt: dayjs().format(),
|
|
40
|
+
lockedBy: this.machineId
|
|
41
|
+
}
|
|
42
|
+
}, {
|
|
43
|
+
sort: {
|
|
44
|
+
nextRunAt: 1
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return nextJob?.value;
|
|
48
|
+
},
|
|
49
|
+
initializeDatabase: function() {
|
|
50
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
51
|
+
db.createIndex({ status: 1 });
|
|
52
|
+
db.createIndex({ status: 1, nextRunAt: 1 });
|
|
53
|
+
if (this.queue.options?.cleanup?.completedAfterSeconds) {
|
|
54
|
+
db.createIndex({ completedAt: 1 }, { expireAfterSeconds: this?.queue?.options?.cleanup?.completedAfterSeconds });
|
|
55
|
+
}
|
|
56
|
+
if (this.queue.options?.cleanup?.failedAfterSeconds) {
|
|
57
|
+
db.createIndex({ failedAt: 1 }, { expireAfterSeconds: this?.queue?.options?.cleanup?.failedAfterSeconds });
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
requeueJob: function(jobId = "", nextRunAt = null) {
|
|
61
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
62
|
+
return db.updateOne({ _id: jobId }, {
|
|
63
|
+
$set: {
|
|
64
|
+
status: "pending",
|
|
65
|
+
nextRunAt
|
|
66
|
+
},
|
|
67
|
+
$unset: {
|
|
68
|
+
lockedBy: ""
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
setJobsForMachineIncomplete: function() {
|
|
73
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
74
|
+
return db.updateMany({ status: "running", lockedBy: this.machineId }, {
|
|
75
|
+
$set: {
|
|
76
|
+
status: "incomplete"
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
setJobCompleted: function(jobId = "") {
|
|
81
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
82
|
+
return db.updateOne({ _id: jobId }, {
|
|
83
|
+
$set: {
|
|
84
|
+
status: "completed",
|
|
85
|
+
completedAt: dayjs().format()
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
setJobFailed: function(jobId = "", error = "") {
|
|
90
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
91
|
+
return db.updateOne({ _id: jobId }, {
|
|
92
|
+
$set: {
|
|
93
|
+
status: "failed",
|
|
94
|
+
failedAt: dayjs().format(),
|
|
95
|
+
error
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
setJobsForMachinePending: function() {
|
|
100
|
+
const db = process.databases._queues?.collection(`queue_${this.queue.name}`);
|
|
101
|
+
return db.updateMany({ status: { $in: ["pending", "running"] }, lockedBy: this.machineId }, {
|
|
102
|
+
$set: {
|
|
103
|
+
status: "pending"
|
|
104
|
+
},
|
|
105
|
+
// NOTE: Unpin job from the machine that originally had it and toss it back in the queue
|
|
106
|
+
// for any machine to pick it up.
|
|
107
|
+
$unset: {
|
|
108
|
+
lockedBy: ""
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
export {
|
|
114
|
+
queues_default as default
|
|
115
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const createUniqueIndex = async (indexName = "", tableName = "", tableColumns = []) => {
|
|
2
|
+
return process.databases._users?.query(`CREATE UNIQUE INDEX IF NOT EXISTS ${indexName} ON ${tableName}(${tableColumns.join(", ")})`);
|
|
3
|
+
};
|
|
4
|
+
const createIndex = async (indexName = "", tableName = "", tableColumns = []) => {
|
|
5
|
+
return process.databases._users?.query(`CREATE INDEX IF NOT EXISTS ${indexName} ON ${tableName}(${tableColumns.join(", ")})`);
|
|
6
|
+
};
|
|
7
|
+
var createAccountsIndexes_default = async () => {
|
|
8
|
+
await createIndex("user_by_email", "users", ["email_address"]);
|
|
9
|
+
await createIndex("user_by_username", "users", ["username"]);
|
|
10
|
+
await createIndex("user_by_user_id", "users", ["user_id"]);
|
|
11
|
+
await createIndex("user_session_by_token", "users_sessions", ["token"]);
|
|
12
|
+
await createIndex("user_password_reset_token_by_token", "users_password_reset_tokens", ["token"]);
|
|
13
|
+
await createIndex("user_password_reset_token_by_user_id_token", "users_password_reset_tokens", ["user_id", "token"]);
|
|
14
|
+
await createIndex("user_role", "users_roles", ["role"]);
|
|
15
|
+
await createIndex("user_roles_by_user_id_role", "users_roles", ["user_id", "role"]);
|
|
16
|
+
await createIndex("role", "roles", ["role"]);
|
|
17
|
+
await createUniqueIndex("user_roles", "users_roles", ["user_id", "role"]);
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
createAccountsIndexes_default as default
|
|
21
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const createTable = async (table = "", tableColumns = []) => {
|
|
2
|
+
return process.databases._users?.query(
|
|
3
|
+
`CREATE TABLE IF NOT EXISTS ${table} (${tableColumns.join(", ")})`
|
|
4
|
+
);
|
|
5
|
+
};
|
|
6
|
+
var createAccountsTables_default = async () => {
|
|
7
|
+
await createTable("users", [
|
|
8
|
+
"id bigserial primary key",
|
|
9
|
+
"user_id text",
|
|
10
|
+
"email_address text",
|
|
11
|
+
"password text",
|
|
12
|
+
"username text",
|
|
13
|
+
"language text"
|
|
14
|
+
]);
|
|
15
|
+
await createTable("users_sessions", [
|
|
16
|
+
"id bigserial primary key",
|
|
17
|
+
"user_id text",
|
|
18
|
+
"token text",
|
|
19
|
+
"token_expires_at text"
|
|
20
|
+
]);
|
|
21
|
+
await createTable("users_password_reset_tokens", [
|
|
22
|
+
"id bigserial primary key",
|
|
23
|
+
"user_id text",
|
|
24
|
+
"token text",
|
|
25
|
+
"requested_at text"
|
|
26
|
+
]);
|
|
27
|
+
await createTable("users_verify_email_tokens", [
|
|
28
|
+
"id bigserial primary key",
|
|
29
|
+
"user_id text",
|
|
30
|
+
"token text"
|
|
31
|
+
]);
|
|
32
|
+
await createTable("roles", ["id bigserial primary key", "role text"]);
|
|
33
|
+
await createTable("users_roles", [
|
|
34
|
+
"id bigserial primary key",
|
|
35
|
+
"user_id text",
|
|
36
|
+
"role text"
|
|
37
|
+
]);
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
createAccountsTables_default as default
|
|
41
|
+
};
|
|
File without changes
|