@cocreate/crud-server
Advanced tools
Comparing version 1.20.5 to 1.21.0
@@ -0,1 +1,14 @@ | ||
# [1.21.0](https://github.com/CoCreate-app/CoCreate-crud-server/compare/v1.20.5...v1.21.0) (2023-05-19) | ||
### Bug Fixes | ||
* wsManager listeners & add async/await consistency ([f8b21be](https://github.com/CoCreate-app/CoCreate-crud-server/commit/f8b21beafa41888ea85c16391880fb1bfce10231)) | ||
### Features | ||
* Refactor code to ensure data.db is always an Array ([ce76271](https://github.com/CoCreate-app/CoCreate-crud-server/commit/ce76271518a0b7525e6dbbd80d7dc25e8184692d)) | ||
* update data.organization_id if previously transformed to platform_id ([bb95274](https://github.com/CoCreate-app/CoCreate-crud-server/commit/bb9527425ee5cb13c81933a658a6a732ac306407)) | ||
## [1.20.5](https://github.com/CoCreate-app/CoCreate-crud-server/compare/v1.20.4...v1.20.5) (2023-05-11) | ||
@@ -2,0 +15,0 @@ |
{ | ||
"name": "@cocreate/crud-server", | ||
"version": "1.20.5", | ||
"version": "1.21.0", | ||
"description": "CoCreate-crud-server", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -123,3 +123,3 @@ const json2csv = require("json-2-csv") | ||
// } | ||
// // todo: validate json / if json is object error happens | ||
// // TODO: validate json / if json is object error happens | ||
// jsonData.map((item) => delete item._id); | ||
@@ -126,0 +126,0 @@ // console.log('json: ', jsonData) |
400
src/index.js
'use strict'; | ||
const {ObjectId, searchData, sortData} = require("@cocreate/utils"); | ||
const { ObjectId, searchData, sortData } = require("@cocreate/utils"); | ||
class CoCreateCrudServer { | ||
constructor(wsManager, databases, database) { | ||
this.wsManager = wsManager | ||
this.databases = databases | ||
this.database = database | ||
this.ObjectId = ObjectId | ||
this.databaseUrls = new Map(); | ||
this.init(); | ||
} | ||
init() { | ||
if (this.wsManager) { | ||
this.wsManager.on('createDatabase', (socket, data) => this.db(socket, 'createDatabase', data)) | ||
this.wsManager.on('readDatabase', (socket, data) => this.db(socket, 'readDatabase', data)) | ||
this.wsManager.on('updateDatabase', (socket, data) => this.db(socket, 'updateDatabase', data)) | ||
this.wsManager.on('deleteDatabase', (socket, data) => this.db(socket, 'deleteDatabase', data)) | ||
this.wsManager.on('createCollection', (socket, data) => this.db(socket, 'createCollection', data)) | ||
this.wsManager.on('readCollection', (socket, data) => this.db(socket, 'readCollection', data)) | ||
this.wsManager.on('updateCollection', (socket, data) => this.db(socket, 'updateCollection', data)) | ||
this.wsManager.on('deleteCollection', (socket, data) => this.db(socket, 'deleteCollection', data)) | ||
this.wsManager.on('createDocument', (socket, data) => this.db(socket, 'createDocument', data)) | ||
this.wsManager.on('readDocument', (socket, data) => this.db(socket, 'readDocument', data)) | ||
this.wsManager.on('updateDocument', (socket, data) => this.db(socket, 'updateDocument', data)) | ||
this.wsManager.on('deleteDocument', (socket, data) => this.db(socket, 'deleteDocument', data)) | ||
} | ||
} | ||
constructor(wsManager, databases, database) { | ||
this.wsManager = wsManager | ||
this.databases = databases | ||
this.database = database | ||
this.ObjectId = ObjectId | ||
this.databaseUrls = new Map(); | ||
this.init(); | ||
} | ||
async databaseStats(data) { | ||
data = await this.db('', 'databaseStats', data) | ||
return data | ||
} | ||
init() { | ||
if (this.wsManager) { | ||
this.wsManager.on('createDatabase', (socket, data) => this.db(socket, 'createDatabase', data)) | ||
this.wsManager.on('readDatabase', (socket, data) => this.db(socket, 'readDatabase', data)) | ||
this.wsManager.on('updateDatabase', (socket, data) => this.db(socket, 'updateDatabase', data)) | ||
this.wsManager.on('deleteDatabase', (socket, data) => this.db(socket, 'deleteDatabase', data)) | ||
this.wsManager.on('createCollection', (socket, data) => this.db(socket, 'createCollection', data)) | ||
this.wsManager.on('readCollection', (socket, data) => this.db(socket, 'readCollection', data)) | ||
this.wsManager.on('updateCollection', (socket, data) => this.db(socket, 'updateCollection', data)) | ||
this.wsManager.on('deleteCollection', (socket, data) => this.db(socket, 'deleteCollection', data)) | ||
this.wsManager.on('createDocument', (socket, data) => this.db(socket, 'createDocument', data)) | ||
this.wsManager.on('readDocument', (socket, data) => this.db(socket, 'readDocument', data)) | ||
this.wsManager.on('updateDocument', (socket, data) => this.db(socket, 'updateDocument', data)) | ||
this.wsManager.on('deleteDocument', (socket, data) => this.db(socket, 'deleteDocument', data)) | ||
} | ||
} | ||
async createDatabase(data) { | ||
data = await this.db('', 'createDatabase', data) | ||
return data | ||
} | ||
async databaseStats(data) { | ||
data = await this.db('', 'databaseStats', data) | ||
return data | ||
} | ||
async readDatabase(data) { | ||
data = await this.db('', 'readDatabase', data) | ||
return data | ||
} | ||
async updateDatabase(data) { | ||
data = await this.db('', 'updateDatabase', data) | ||
return data | ||
} | ||
async createDatabase(data) { | ||
data = await this.db('', 'createDatabase', data) | ||
return data | ||
} | ||
async deleteDatabase(data) { | ||
data = await this.db('', 'deleteDatabase', data) | ||
return data | ||
} | ||
async readDatabase(data) { | ||
data = await this.db('', 'readDatabase', data) | ||
return data | ||
} | ||
async createCollection(data) { | ||
data = await this.db('', 'createCollection', data) | ||
return data | ||
} | ||
async updateDatabase(data) { | ||
data = await this.db('', 'updateDatabase', data) | ||
return data | ||
} | ||
async readCollection(data) { | ||
data = await this.db('', 'readCollection', data) | ||
return data | ||
} | ||
async updateCollection(data) { | ||
data = await this.db('', 'updateCollection', data) | ||
return data | ||
} | ||
async deleteDatabase(data) { | ||
data = await this.db('', 'deleteDatabase', data) | ||
return data | ||
} | ||
async deleteCollection(data) { | ||
data = await this.db('', 'deleteCollection', data) | ||
return data | ||
} | ||
async createCollection(data) { | ||
data = await this.db('', 'createCollection', data) | ||
return data | ||
} | ||
async createDocument(data) { | ||
data = await this.db('', 'createDocument', data) | ||
return data | ||
} | ||
async readDocument(data) { | ||
data = await this.db('', 'readDocument', data) | ||
return data | ||
} | ||
async readCollection(data) { | ||
data = await this.db('', 'readCollection', data) | ||
return data | ||
} | ||
async updateDocument(data) { | ||
data = await this.db('', 'updateDocument', data) | ||
return data | ||
} | ||
async updateCollection(data) { | ||
data = await this.db('', 'updateCollection', data) | ||
return data | ||
} | ||
async deleteDocument(data) { | ||
data = await this.db('', 'deleteDocument', data) | ||
return data | ||
} | ||
async deleteCollection(data) { | ||
data = await this.db('', 'deleteCollection', data) | ||
return data | ||
} | ||
async db(socket, action, data) { | ||
return new Promise(async (resolve) => { | ||
try { | ||
if (!data.organization_id) | ||
return resolve() | ||
async createDocument(data) { | ||
data = await this.db('', 'createDocument', data) | ||
return data | ||
} | ||
let dbUrl = this.databaseUrls.get(data.organization_id) | ||
if (dbUrl === false) | ||
return resolve({dbUrl: false, error: 'database url could not be found'}) | ||
async readDocument(data) { | ||
data = await this.db('', 'readDocument', data) | ||
return data | ||
} | ||
if (!dbUrl) { | ||
if (data.organization_id === process.env.organization_id) { | ||
dbUrl = { [this.database.name]: this.database} | ||
this.databaseUrls.set(data.organization_id, dbUrl) | ||
} else { | ||
let organization = await this.databases[this.database.name]['readDocument']({ | ||
dbUrl: this.database.url[0], | ||
database: process.env.organization_id, | ||
collection: 'organizations', | ||
document: [{_id: data.organization_id}], | ||
organization_id: process.env.organization_id | ||
}) | ||
if (organization && organization.document && organization.document[0]) | ||
organization = organization.document[0] | ||
if (organization && organization.databases) { | ||
dbUrl = organization.databases | ||
this.databaseUrls.set(data.organization_id, dbUrl) | ||
} else { | ||
this.databaseUrls.set(data.organization_id, false) | ||
if (organization) | ||
return resolve({dbUrl: false, error: 'database url could not be found'}) | ||
else | ||
return resolve({organization: false, error: 'organization could not be found'}) | ||
} | ||
} | ||
} | ||
if (!data['timeStamp']) | ||
data['timeStamp'] = new Date().toISOString() | ||
async updateDocument(data) { | ||
data = await this.db('', 'updateDocument', data) | ||
return data | ||
} | ||
async deleteDocument(data) { | ||
data = await this.db('', 'deleteDocument', data) | ||
return data | ||
} | ||
async db(socket, action, data) { | ||
return new Promise(async (resolve) => { | ||
try { | ||
if (!data.organization_id) | ||
return resolve() | ||
let dbUrl = this.databaseUrls.get(data.organization_id) | ||
if (dbUrl === false) | ||
return resolve({ dbUrl: false, error: 'database url could not be found' }) | ||
if (!dbUrl) { | ||
if (data.organization_id === process.env.organization_id) { | ||
dbUrl = { [this.database.name]: this.database } | ||
this.databaseUrls.set(data.organization_id, dbUrl) | ||
} else { | ||
let organization = await this.databases[this.database.name]['readDocument']({ | ||
dbUrl: this.database.url[0], | ||
database: process.env.organization_id, | ||
collection: 'organizations', | ||
document: [{ _id: data.organization_id }], | ||
organization_id: process.env.organization_id | ||
}) | ||
if (organization && organization.document && organization.document[0]) | ||
organization = organization.document[0] | ||
if (organization && organization.databases) { | ||
dbUrl = organization.databases | ||
this.databaseUrls.set(data.organization_id, dbUrl) | ||
} else { | ||
this.databaseUrls.set(data.organization_id, false) | ||
if (organization) | ||
return resolve({ dbUrl: false, error: 'database url could not be found' }) | ||
else | ||
return resolve({ organization: false, error: 'organization could not be found' }) | ||
} | ||
} | ||
} | ||
if (!data['timeStamp']) | ||
data['timeStamp'] = new Date().toISOString() | ||
if (action == 'updateDocument' && data.upsert != false) | ||
data.upsert = true | ||
// ToDo: support stats from multiple dbs | ||
// TODO: support stats from multiple dbs | ||
if (data.collection || action === 'databaseStats') { | ||
if (!data.database) | ||
data['database'] = data.organization_id | ||
if (action === 'updateDocument' && data.organization_id !== process.env.organization_id) { | ||
let syncKeys | ||
if (data.collection === 'organizations') | ||
syncKeys = ['name', 'logo', 'databases', 'hosts', 'apis'] | ||
else if (data.collection === 'users') | ||
syncKeys = ['name', 'email', 'password', 'avatar'] | ||
if (syncKeys && syncKeys.length) { | ||
let platformUpdate = { | ||
dbUrl: this.database.url, | ||
database: process.env.organization_id, | ||
collection: data.collection, | ||
document: [{}], | ||
organization_id: process.env.organization_id | ||
} | ||
if (action === 'updateDocument' && data.organization_id !== process.env.organization_id) { | ||
let syncKeys | ||
if (data.collection === 'organizations') | ||
syncKeys = ['name', 'logo', 'databases', 'hosts', 'apis'] | ||
else if (data.collection === 'users') | ||
syncKeys = ['name', 'email', 'password', 'avatar'] | ||
let document = data.document[0] || data.document | ||
if (document) { | ||
for (let key of syncKeys) { | ||
if (document[key]) | ||
platformUpdate.document[0][key] = document[key] | ||
} | ||
} | ||
if (syncKeys && syncKeys.length) { | ||
let platformUpdate = { | ||
dbUrl: this.database.url, | ||
database: process.env.organization_id, | ||
collection: data.collection, | ||
document: [{}], | ||
organization_id: process.env.organization_id | ||
} | ||
this.databases[this.database.name][action](platformUpdate) | ||
} | ||
let document = data.document[0] || data.document | ||
if (document) { | ||
for (let key of syncKeys) { | ||
if (document[key]) | ||
platformUpdate.document[0][key] = document[key] | ||
} | ||
} | ||
} | ||
this.databases[this.database.name][action](platformUpdate) | ||
} | ||
} | ||
} | ||
if (!data.db || !data.db.length) | ||
data.db = ['mongodb'] | ||
else if (!Array.isArray(data.db)) | ||
data.db = [data.db] | ||
if (!data.db || !data.db.length) | ||
data.db = ['mongodb'] | ||
for (let i = 0; i < data.db.length; i++) { | ||
if (dbUrl && dbUrl[data.db[i]]) { | ||
let db = dbUrl[data.db[i]] | ||
for (let i = 0; i < data.db.length; i++) { | ||
if (dbUrl && dbUrl[data.db[i]]) { | ||
let db = dbUrl[data.db[i]] | ||
if (db.name && this.databases[db.name]) { | ||
if (db.name && this.databases[db.name]) { | ||
for (let i = 0; i < db.url.length; i++) { | ||
data['dbUrl'] = db.url[i] | ||
data = await this.databases[db.name][action](data) | ||
} | ||
for (let i = 0; i < db.url.length; i++) { | ||
data['dbUrl'] = db.url[i] | ||
data = await this.databases[db.name][action](data) | ||
} | ||
//ToDo: sorting should take place here in order to return sorted values from multiple dbs | ||
} | ||
} | ||
} | ||
delete data.dbUrl | ||
if (socket) { | ||
this.wsManager.broadcast(socket, action, data); | ||
process.emit('changed-document', data) | ||
resolve() | ||
} else { | ||
resolve(data) | ||
} | ||
} catch(error) { | ||
if (socket) { | ||
errorHandler(data, error) | ||
this.wsManager.send(socket, action, data); | ||
resolve() | ||
} else { | ||
resolve(data) | ||
} | ||
} | ||
}); | ||
} | ||
//TODO: sorting should take place here in order to return sorted values from multiple dbs | ||
} | ||
} | ||
} | ||
errorHandler(data, error, database, collection){ | ||
if (typeof error == 'object') | ||
error['db'] = 'mongodb' | ||
else | ||
error = {location: 'crudServer', message: error} | ||
if (database) | ||
error['database'] = database | ||
if (data.error) | ||
data.error.push(error) | ||
else | ||
data.error = [error] | ||
} | ||
delete data.dbUrl | ||
if (socket) { | ||
if (data.organization_id === process.env.organization_id && socket.config.organization_id !== data.organization_id) { | ||
this.wsManager.broadcast({ | ||
config: { | ||
organization_id: process.env.organization_id, | ||
} | ||
}, action, { ...data }); | ||
data.organization_id = socket.config.organization_id | ||
} | ||
this.wsManager.broadcast(socket, action, data); | ||
process.emit('changed-document', data) | ||
resolve() | ||
} else { | ||
resolve(data) | ||
} | ||
} catch (error) { | ||
if (socket) { | ||
errorHandler(data, error) | ||
this.wsManager.send(socket, action, data); | ||
resolve() | ||
} else { | ||
resolve(data) | ||
} | ||
} | ||
}); | ||
} | ||
errorHandler(data, error, database, collection) { | ||
if (typeof error == 'object') | ||
error['db'] = 'mongodb' | ||
else | ||
error = { location: 'crudServer', message: error } | ||
if (database) | ||
error['database'] = database | ||
if (data.error) | ||
data.error.push(error) | ||
else | ||
data.error = [error] | ||
} | ||
} | ||
module.exports = CoCreateCrudServer; |
97660
374
8