@cocreate/crud-server 1.22.0 → 1.22.2
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/.github/FUNDING.yml +3 -3
- package/.github/workflows/automated.yml +56 -43
- package/CHANGELOG.md +811 -796
- package/CONTRIBUTING.md +96 -96
- package/CoCreate.config.js +25 -25
- package/LICENSE +578 -578
- package/README.md +66 -66
- package/docs/index.html +193 -65
- package/package.json +3 -3
- package/release.config.js +21 -21
- package/src/backup.js +150 -150
- package/src/index.js +240 -240
package/src/index.js
CHANGED
|
@@ -1,241 +1,241 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { ObjectId, searchData, sortData } = require("@cocreate/utils");
|
|
4
|
-
|
|
5
|
-
class CoCreateCrudServer {
|
|
6
|
-
constructor(wsManager, databases, db) {
|
|
7
|
-
this.wsManager = wsManager
|
|
8
|
-
this.databases = databases
|
|
9
|
-
this.db = db
|
|
10
|
-
this.ObjectId = ObjectId
|
|
11
|
-
this.dbUrls = new Map();
|
|
12
|
-
this.init();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
init() {
|
|
16
|
-
if (this.wsManager) {
|
|
17
|
-
this.wsManager.on('createDatabase', (socket, data) => this.crud(socket, 'createDatabase', data))
|
|
18
|
-
this.wsManager.on('readDatabase', (socket, data) => this.crud(socket, 'readDatabase', data))
|
|
19
|
-
this.wsManager.on('updateDatabase', (socket, data) => this.crud(socket, 'updateDatabase', data))
|
|
20
|
-
this.wsManager.on('deleteDatabase', (socket, data) => this.crud(socket, 'deleteDatabase', data))
|
|
21
|
-
this.wsManager.on('createCollection', (socket, data) => this.crud(socket, 'createCollection', data))
|
|
22
|
-
this.wsManager.on('readCollection', (socket, data) => this.crud(socket, 'readCollection', data))
|
|
23
|
-
this.wsManager.on('updateCollection', (socket, data) => this.crud(socket, 'updateCollection', data))
|
|
24
|
-
this.wsManager.on('deleteCollection', (socket, data) => this.crud(socket, 'deleteCollection', data))
|
|
25
|
-
this.wsManager.on('createDocument', (socket, data) => this.crud(socket, 'createDocument', data))
|
|
26
|
-
this.wsManager.on('readDocument', (socket, data) => this.crud(socket, 'readDocument', data))
|
|
27
|
-
this.wsManager.on('updateDocument', (socket, data) => this.crud(socket, 'updateDocument', data))
|
|
28
|
-
this.wsManager.on('deleteDocument', (socket, data) => this.crud(socket, 'deleteDocument', data))
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async databaseStats(data) {
|
|
33
|
-
data = await this.crud('', 'databaseStats', data)
|
|
34
|
-
return data
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async createDatabase(data) {
|
|
38
|
-
data = await this.crud('', 'createDatabase', data)
|
|
39
|
-
return data
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async readDatabase(data) {
|
|
43
|
-
data = await this.crud('', 'readDatabase', data)
|
|
44
|
-
return data
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async updateDatabase(data) {
|
|
48
|
-
data = await this.crud('', 'updateDatabase', data)
|
|
49
|
-
return data
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async deleteDatabase(data) {
|
|
53
|
-
data = await this.crud('', 'deleteDatabase', data)
|
|
54
|
-
return data
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async createCollection(data) {
|
|
58
|
-
data = await this.crud('', 'createCollection', data)
|
|
59
|
-
return data
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async readCollection(data) {
|
|
63
|
-
data = await this.crud('', 'readCollection', data)
|
|
64
|
-
return data
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
async updateCollection(data) {
|
|
68
|
-
data = await this.crud('', 'updateCollection', data)
|
|
69
|
-
return data
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async deleteCollection(data) {
|
|
73
|
-
data = await this.crud('', 'deleteCollection', data)
|
|
74
|
-
return data
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async createDocument(data) {
|
|
78
|
-
data = await this.crud('', 'createDocument', data)
|
|
79
|
-
return data
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async readDocument(data) {
|
|
83
|
-
data = await this.crud('', 'readDocument', data)
|
|
84
|
-
return data
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async updateDocument(data) {
|
|
88
|
-
data = await this.crud('', 'updateDocument', data)
|
|
89
|
-
return data
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async deleteDocument(data) {
|
|
93
|
-
data = await this.crud('', 'deleteDocument', data)
|
|
94
|
-
return data
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async crud(socket, action, data) {
|
|
98
|
-
return new Promise(async (resolve) => {
|
|
99
|
-
try {
|
|
100
|
-
if (!data.organization_id)
|
|
101
|
-
return resolve()
|
|
102
|
-
|
|
103
|
-
let dbUrl = this.dbUrls.get(data.organization_id)
|
|
104
|
-
if (dbUrl === false)
|
|
105
|
-
return resolve({ dbUrl: false, error: 'database url could not be found' })
|
|
106
|
-
|
|
107
|
-
if (!dbUrl) {
|
|
108
|
-
if (data.organization_id === process.env.organization_id) {
|
|
109
|
-
dbUrl = this.db
|
|
110
|
-
this.dbUrls.set(data.organization_id, dbUrl)
|
|
111
|
-
} else {
|
|
112
|
-
let organization = await this.readDocument({
|
|
113
|
-
database: process.env.organization_id,
|
|
114
|
-
collection: 'organizations',
|
|
115
|
-
document: [{ _id: data.organization_id }],
|
|
116
|
-
organization_id: process.env.organization_id
|
|
117
|
-
})
|
|
118
|
-
if (organization && organization.document && organization.document[0])
|
|
119
|
-
organization = organization.document[0]
|
|
120
|
-
if (organization && organization.databases) {
|
|
121
|
-
dbUrl = organization.databases
|
|
122
|
-
this.dbUrls.set(data.organization_id, dbUrl)
|
|
123
|
-
} else {
|
|
124
|
-
this.dbUrls.set(data.organization_id, false)
|
|
125
|
-
if (organization)
|
|
126
|
-
return resolve({ dbUrl: false, error: 'database url could not be found' })
|
|
127
|
-
else
|
|
128
|
-
return resolve({ organization: false, error: 'organization could not be found' })
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (!data['timeStamp'])
|
|
134
|
-
data['timeStamp'] = new Date().toISOString()
|
|
135
|
-
|
|
136
|
-
if (action == 'updateDocument' && data.upsert != false)
|
|
137
|
-
data.upsert = true
|
|
138
|
-
|
|
139
|
-
// TODO: support stats from multiple dbs
|
|
140
|
-
if (data.collection || action === 'databaseStats') {
|
|
141
|
-
if (!data.database)
|
|
142
|
-
data['database'] = data.organization_id
|
|
143
|
-
|
|
144
|
-
if (action === 'updateDocument' && data.organization_id !== process.env.organization_id) {
|
|
145
|
-
let syncKeys
|
|
146
|
-
if (data.collection === 'organizations')
|
|
147
|
-
syncKeys = ['name', 'logo', 'databases', 'hosts', 'apis']
|
|
148
|
-
else if (data.collection === 'users')
|
|
149
|
-
syncKeys = ['name', 'email', 'password', 'avatar']
|
|
150
|
-
|
|
151
|
-
if (syncKeys && syncKeys.length) {
|
|
152
|
-
let platformUpdate = {
|
|
153
|
-
database: process.env.organization_id,
|
|
154
|
-
collection: data.collection,
|
|
155
|
-
document: [{}],
|
|
156
|
-
organization_id: process.env.organization_id
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let document = data.document[0] || data.document
|
|
160
|
-
if (document) {
|
|
161
|
-
for (let key of syncKeys) {
|
|
162
|
-
if (document[key])
|
|
163
|
-
platformUpdate.document[0][key] = document[key]
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this[action](platformUpdate)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (!data.db || !data.db.length) {
|
|
175
|
-
data.db = [Object.keys(dbUrl)[0]]
|
|
176
|
-
} else if (!Array.isArray(data.db))
|
|
177
|
-
data.db = [data.db]
|
|
178
|
-
|
|
179
|
-
for (let i = 0; i < data.db.length; i++) {
|
|
180
|
-
if (dbUrl && dbUrl[data.db[i]]) {
|
|
181
|
-
let db = dbUrl[data.db[i]]
|
|
182
|
-
|
|
183
|
-
if (db.provider && this.databases[db.provider]) {
|
|
184
|
-
if (!Array.isArray(db.url))
|
|
185
|
-
db.url = [db.url]
|
|
186
|
-
for (let i = 0; i < db.url.length; i++) {
|
|
187
|
-
data['dbUrl'] = db.url[i]
|
|
188
|
-
data = await this.databases[db.provider][action](data)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
//TODO: sorting should take place here in order to return sorted values from multiple dbs
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
delete data.dbUrl
|
|
197
|
-
if (socket) {
|
|
198
|
-
if (data.organization_id === process.env.organization_id && socket.config.organization_id !== data.organization_id) {
|
|
199
|
-
this.wsManager.broadcast({
|
|
200
|
-
config: {
|
|
201
|
-
organization_id: process.env.organization_id,
|
|
202
|
-
}
|
|
203
|
-
}, action, { ...data });
|
|
204
|
-
data.organization_id = socket.config.organization_id
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
this.wsManager.broadcast(socket, action, data);
|
|
208
|
-
process.emit('changed-document', data)
|
|
209
|
-
resolve()
|
|
210
|
-
} else {
|
|
211
|
-
resolve(data)
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
if (socket) {
|
|
215
|
-
this.errorHandler(data, error)
|
|
216
|
-
this.wsManager.send(socket, action, data);
|
|
217
|
-
resolve()
|
|
218
|
-
} else {
|
|
219
|
-
resolve(data)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
errorHandler(data, error, database, collection) {
|
|
226
|
-
if (typeof error == 'object')
|
|
227
|
-
error['db'] = 'mongodb'
|
|
228
|
-
else
|
|
229
|
-
error = { location: 'crudServer', message: error }
|
|
230
|
-
|
|
231
|
-
if (database)
|
|
232
|
-
error['database'] = database
|
|
233
|
-
|
|
234
|
-
if (data.error)
|
|
235
|
-
data.error.push(error)
|
|
236
|
-
else
|
|
237
|
-
data.error = [error]
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { ObjectId, searchData, sortData } = require("@cocreate/utils");
|
|
4
|
+
|
|
5
|
+
class CoCreateCrudServer {
|
|
6
|
+
constructor(wsManager, databases, db) {
|
|
7
|
+
this.wsManager = wsManager
|
|
8
|
+
this.databases = databases
|
|
9
|
+
this.db = db
|
|
10
|
+
this.ObjectId = ObjectId
|
|
11
|
+
this.dbUrls = new Map();
|
|
12
|
+
this.init();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
init() {
|
|
16
|
+
if (this.wsManager) {
|
|
17
|
+
this.wsManager.on('createDatabase', (socket, data) => this.crud(socket, 'createDatabase', data))
|
|
18
|
+
this.wsManager.on('readDatabase', (socket, data) => this.crud(socket, 'readDatabase', data))
|
|
19
|
+
this.wsManager.on('updateDatabase', (socket, data) => this.crud(socket, 'updateDatabase', data))
|
|
20
|
+
this.wsManager.on('deleteDatabase', (socket, data) => this.crud(socket, 'deleteDatabase', data))
|
|
21
|
+
this.wsManager.on('createCollection', (socket, data) => this.crud(socket, 'createCollection', data))
|
|
22
|
+
this.wsManager.on('readCollection', (socket, data) => this.crud(socket, 'readCollection', data))
|
|
23
|
+
this.wsManager.on('updateCollection', (socket, data) => this.crud(socket, 'updateCollection', data))
|
|
24
|
+
this.wsManager.on('deleteCollection', (socket, data) => this.crud(socket, 'deleteCollection', data))
|
|
25
|
+
this.wsManager.on('createDocument', (socket, data) => this.crud(socket, 'createDocument', data))
|
|
26
|
+
this.wsManager.on('readDocument', (socket, data) => this.crud(socket, 'readDocument', data))
|
|
27
|
+
this.wsManager.on('updateDocument', (socket, data) => this.crud(socket, 'updateDocument', data))
|
|
28
|
+
this.wsManager.on('deleteDocument', (socket, data) => this.crud(socket, 'deleteDocument', data))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async databaseStats(data) {
|
|
33
|
+
data = await this.crud('', 'databaseStats', data)
|
|
34
|
+
return data
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async createDatabase(data) {
|
|
38
|
+
data = await this.crud('', 'createDatabase', data)
|
|
39
|
+
return data
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async readDatabase(data) {
|
|
43
|
+
data = await this.crud('', 'readDatabase', data)
|
|
44
|
+
return data
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async updateDatabase(data) {
|
|
48
|
+
data = await this.crud('', 'updateDatabase', data)
|
|
49
|
+
return data
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async deleteDatabase(data) {
|
|
53
|
+
data = await this.crud('', 'deleteDatabase', data)
|
|
54
|
+
return data
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async createCollection(data) {
|
|
58
|
+
data = await this.crud('', 'createCollection', data)
|
|
59
|
+
return data
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async readCollection(data) {
|
|
63
|
+
data = await this.crud('', 'readCollection', data)
|
|
64
|
+
return data
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async updateCollection(data) {
|
|
68
|
+
data = await this.crud('', 'updateCollection', data)
|
|
69
|
+
return data
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async deleteCollection(data) {
|
|
73
|
+
data = await this.crud('', 'deleteCollection', data)
|
|
74
|
+
return data
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async createDocument(data) {
|
|
78
|
+
data = await this.crud('', 'createDocument', data)
|
|
79
|
+
return data
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async readDocument(data) {
|
|
83
|
+
data = await this.crud('', 'readDocument', data)
|
|
84
|
+
return data
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async updateDocument(data) {
|
|
88
|
+
data = await this.crud('', 'updateDocument', data)
|
|
89
|
+
return data
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async deleteDocument(data) {
|
|
93
|
+
data = await this.crud('', 'deleteDocument', data)
|
|
94
|
+
return data
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async crud(socket, action, data) {
|
|
98
|
+
return new Promise(async (resolve) => {
|
|
99
|
+
try {
|
|
100
|
+
if (!data.organization_id)
|
|
101
|
+
return resolve()
|
|
102
|
+
|
|
103
|
+
let dbUrl = this.dbUrls.get(data.organization_id)
|
|
104
|
+
if (dbUrl === false)
|
|
105
|
+
return resolve({ dbUrl: false, error: 'database url could not be found' })
|
|
106
|
+
|
|
107
|
+
if (!dbUrl) {
|
|
108
|
+
if (data.organization_id === process.env.organization_id) {
|
|
109
|
+
dbUrl = this.db
|
|
110
|
+
this.dbUrls.set(data.organization_id, dbUrl)
|
|
111
|
+
} else {
|
|
112
|
+
let organization = await this.readDocument({
|
|
113
|
+
database: process.env.organization_id,
|
|
114
|
+
collection: 'organizations',
|
|
115
|
+
document: [{ _id: data.organization_id }],
|
|
116
|
+
organization_id: process.env.organization_id
|
|
117
|
+
})
|
|
118
|
+
if (organization && organization.document && organization.document[0])
|
|
119
|
+
organization = organization.document[0]
|
|
120
|
+
if (organization && organization.databases) {
|
|
121
|
+
dbUrl = organization.databases
|
|
122
|
+
this.dbUrls.set(data.organization_id, dbUrl)
|
|
123
|
+
} else {
|
|
124
|
+
this.dbUrls.set(data.organization_id, false)
|
|
125
|
+
if (organization)
|
|
126
|
+
return resolve({ dbUrl: false, error: 'database url could not be found' })
|
|
127
|
+
else
|
|
128
|
+
return resolve({ organization: false, error: 'organization could not be found' })
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!data['timeStamp'])
|
|
134
|
+
data['timeStamp'] = new Date().toISOString()
|
|
135
|
+
|
|
136
|
+
if (action == 'updateDocument' && data.upsert != false)
|
|
137
|
+
data.upsert = true
|
|
138
|
+
|
|
139
|
+
// TODO: support stats from multiple dbs
|
|
140
|
+
if (data.collection || action === 'databaseStats') {
|
|
141
|
+
if (!data.database)
|
|
142
|
+
data['database'] = data.organization_id
|
|
143
|
+
|
|
144
|
+
if (action === 'updateDocument' && data.organization_id !== process.env.organization_id) {
|
|
145
|
+
let syncKeys
|
|
146
|
+
if (data.collection === 'organizations')
|
|
147
|
+
syncKeys = ['name', 'logo', 'databases', 'hosts', 'apis']
|
|
148
|
+
else if (data.collection === 'users')
|
|
149
|
+
syncKeys = ['name', 'email', 'password', 'avatar']
|
|
150
|
+
|
|
151
|
+
if (syncKeys && syncKeys.length) {
|
|
152
|
+
let platformUpdate = {
|
|
153
|
+
database: process.env.organization_id,
|
|
154
|
+
collection: data.collection,
|
|
155
|
+
document: [{}],
|
|
156
|
+
organization_id: process.env.organization_id
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let document = data.document[0] || data.document
|
|
160
|
+
if (document) {
|
|
161
|
+
for (let key of syncKeys) {
|
|
162
|
+
if (document[key])
|
|
163
|
+
platformUpdate.document[0][key] = document[key]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this[action](platformUpdate)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!data.db || !data.db.length) {
|
|
175
|
+
data.db = [Object.keys(dbUrl)[0]]
|
|
176
|
+
} else if (!Array.isArray(data.db))
|
|
177
|
+
data.db = [data.db]
|
|
178
|
+
|
|
179
|
+
for (let i = 0; i < data.db.length; i++) {
|
|
180
|
+
if (dbUrl && dbUrl[data.db[i]]) {
|
|
181
|
+
let db = dbUrl[data.db[i]]
|
|
182
|
+
|
|
183
|
+
if (db.provider && this.databases[db.provider]) {
|
|
184
|
+
if (!Array.isArray(db.url))
|
|
185
|
+
db.url = [db.url]
|
|
186
|
+
for (let i = 0; i < db.url.length; i++) {
|
|
187
|
+
data['dbUrl'] = db.url[i]
|
|
188
|
+
data = await this.databases[db.provider][action](data)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
//TODO: sorting should take place here in order to return sorted values from multiple dbs
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
delete data.dbUrl
|
|
197
|
+
if (socket) {
|
|
198
|
+
if (data.organization_id === process.env.organization_id && socket.config.organization_id !== data.organization_id) {
|
|
199
|
+
this.wsManager.broadcast({
|
|
200
|
+
config: {
|
|
201
|
+
organization_id: process.env.organization_id,
|
|
202
|
+
}
|
|
203
|
+
}, action, { ...data });
|
|
204
|
+
data.organization_id = socket.config.organization_id
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.wsManager.broadcast(socket, action, data);
|
|
208
|
+
process.emit('changed-document', data)
|
|
209
|
+
resolve()
|
|
210
|
+
} else {
|
|
211
|
+
resolve(data)
|
|
212
|
+
}
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (socket) {
|
|
215
|
+
this.errorHandler(data, error)
|
|
216
|
+
this.wsManager.send(socket, action, data);
|
|
217
|
+
resolve()
|
|
218
|
+
} else {
|
|
219
|
+
resolve(data)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
errorHandler(data, error, database, collection) {
|
|
226
|
+
if (typeof error == 'object')
|
|
227
|
+
error['db'] = 'mongodb'
|
|
228
|
+
else
|
|
229
|
+
error = { location: 'crudServer', message: error }
|
|
230
|
+
|
|
231
|
+
if (database)
|
|
232
|
+
error['database'] = database
|
|
233
|
+
|
|
234
|
+
if (data.error)
|
|
235
|
+
data.error.push(error)
|
|
236
|
+
else
|
|
237
|
+
data.error = [error]
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
241
|
module.exports = CoCreateCrudServer;
|