feat: migrate-to-mongo 0.4.6

This commit is contained in:
Gabriel Pastori 2023-12-13 13:05:48 -03:00
parent a0cd4d370c
commit be7fea49a1
10 changed files with 2497 additions and 3388 deletions

View File

@ -5,6 +5,7 @@ const functions = {
uninstall: require('./uninstall.js'),
cv: require('./changeVersion.js'),
changeVersion: require('./changeVersion.js'),
'migrate-to-mongo': require('./migrateToMongo/index.js'),
}
module.exports = async (argv) => {

View File

@ -0,0 +1,130 @@
const verifyEvolutionInstallation = require('../../utils/verifyEvolutionInstallation.js');
const cliProgress = require('cli-progress');
const inquirer = require('inquirer');
const fs = require('fs');
const path = require('path');
const colors = require('ansi-colors');
const mongoose = require('mongoose');
const migratorsFunctions = {
INSTANCE: require('./migrators/instance.js'),
CONTACTS: require('./migrators/contacts.js'),
NEW_MESSAGE: require('./migrators/newMessage.js'),
MESSAGE_UPDATE: require('./migrators/messageUpdate.js'),
CHATS: require('./migrators/chats.js'),
};
module.exports = async () => {
const isEvolutionInstalled = verifyEvolutionInstallation();
if (!isEvolutionInstalled) return;
const instancesNames = fs.readdirSync(path.join(process.cwd(), 'instances')).filter((file) => {
return fs.statSync(path.join(process.cwd(), 'instances', file)).isDirectory();
});
const questions = [
{
type: 'input',
name: 'mongodbUrl',
message: 'MongoDB url:',
default: 'mongodb://admin:password@localhost:27017',
},
{
type: 'input',
name: 'prefix',
message: 'MongoDB prefix:',
default: 'evolution',
},
{
type: 'checkbox',
name: 'saveData',
message: 'What data do you want to migrate?',
choices: [
{
name: 'Instance',
value: 'INSTANCE',
checked: true,
},
{
name: 'New Message',
value: 'NEW_MESSAGE',
checked: true,
},
{
name: 'Message Update',
value: 'MESSAGE_UPDATE',
checked: true,
},
{
name: 'Contacts',
value: 'CONTACTS',
checked: true,
},
{
name: 'Chats',
value: 'CHATS',
checked: true,
},
],
},
{
type: 'checkbox',
name: 'selectedInstances',
message: 'Select instances to migrate:',
choices: instancesNames.map((instanceName) => {
return {
name: instanceName,
value: instanceName,
checked: true,
}
}),
}
];
// get folders from /instances
const answers = await inquirer.prompt(questions);
// connect to mongodb
console.log('\n\n🌱 Connecting to MongoDB...');
const conn = await mongoose.createConnection(answers.mongodbUrl, {
dbName: answers.prefix + '-whatsapp-api',
}).asPromise();
const connInstance = answers.saveData.includes('INSTANCE') ? await mongoose.createConnection(answers.mongodbUrl, {
dbName: answers.prefix + '-instances',
}).asPromise() : null;
console.log('🌱 Connected to MongoDB!\n\n');
const instancesBar = new cliProgress.SingleBar({
format: 'Instance: ' + colors.blue('{instanceName}') + ' |' + colors.cyan('{bar}') + '| {percentage}% || {value}/{total} Instances',
}, cliProgress.Presets.shades_classic);
instancesBar.start(answers.selectedInstances.length, 0);
for (const instanceName of answers.selectedInstances) {
instancesBar.update({ instanceName });
const instanceBars = new cliProgress.MultiBar({
format: '|' + colors.cyan('{bar}') + '| ' + colors.blue('{process}') + ' | {percentage}% || {value}/{total} Files',
clearOnComplete: true,
}, cliProgress.Presets.shades_classic);
for (const migration of answers.saveData) {
await migratorsFunctions[migration](instanceName, answers, instanceBars, conn, connInstance);
}
instanceBars.stop();
instancesBar.increment();
}
instancesBar.stop();
// disconnect from mongodb
console.log('\n\n🌱 Disconnecting from MongoDB...');
await conn.close();
console.log('🌱 Disconnected from MongoDB!\n\n');
console.log('🌱 Migration completed!\n\n');
process.exit(0);
};

View File

@ -0,0 +1,44 @@
const FOLDER_PATH = [{
path: "/store/chats",
key: "chats"
}]
const fs = require("fs")
const path = require("path")
module.exports = async (instanceName, options, progressBars, conn) => {
var files = []
FOLDER_PATH.forEach(folder => {
files = files.concat(getFiles(instanceName, folder))
})
const progress = progressBars.create(files.length, 0)
progress.update({ process: 'Chats' })
for (const file of files) {
const collectionName = file.key
const collection = conn.collection(collectionName)
const data = JSON.parse(fs.readFileSync(file.path, 'utf8'))
data._id = file.path.split('\\').pop().split('.')[0]
await collection.findOneAndUpdate({ _id: data._id }, { $set: data }, { upsert: true })
progress.increment()
}
}
function getFiles(instanceName, opts) {
var files = []
const folder = opts.path || opts
const folderPath = path.join(process.cwd(), folder)
fs.readdirSync(folderPath).forEach(file => {
const filePath = path.join(folderPath, file)
if (fs.statSync(filePath).isDirectory()) {
files = files.concat(getFiles(instanceName, { ...opts, path: `${folder}/${file}` }))
} else if (file.includes(instanceName) || folder.includes(instanceName)) {
files.push({ ...opts, path: filePath })
}
})
return files
}

View File

@ -0,0 +1,44 @@
const FOLDER_PATH = [{
path: "/store/contacts",
key: "contacts"
}]
const fs = require("fs")
const path = require("path")
module.exports = async (instanceName, options, progressBars, conn) => {
var files = []
FOLDER_PATH.forEach(folder => {
files = files.concat(getFiles(instanceName, folder))
})
const progress = progressBars.create(files.length, 0)
progress.update({ process: 'Contacts' })
for (const file of files) {
const collectionName = file.key
const collection = conn.collection(collectionName)
const data = JSON.parse(fs.readFileSync(file.path, 'utf8'))
data._id = file.path.split('\\').pop().split('.')[0]
await collection.findOneAndUpdate({ _id: data._id }, { $set: data }, { upsert: true })
progress.increment()
}
}
function getFiles(instanceName, opts) {
var files = []
const folder = opts.path || opts
const folderPath = path.join(process.cwd(), folder)
fs.readdirSync(folderPath).forEach(file => {
const filePath = path.join(folderPath, file)
if (fs.statSync(filePath).isDirectory()) {
files = files.concat(getFiles(instanceName, { ...opts, path: `${folder}/${file}` }))
} else if (file.includes(instanceName) || folder.includes(instanceName)) {
files.push({ ...opts, path: filePath })
}
})
return files
}

View File

@ -0,0 +1,57 @@
const FOLDER_PATH = [
{
path: "/store/auth/apikey",
key: "authentication"
},
{
path: "/instances",
secondaryConnection: true
},
{ path: "/store/chamaai", key: "chamaai" },
{ path: "/store/chatwoot", key: "chatwoot" },
{ path: "/store/proxy", key: "proxy" },
{ path: "/store/rabbitmq", key: "rabbitmq" },
{ path: "/store/settings", key: "settings" },
{ path: "/store/typebot", key: "typebot" },
{ path: "/store/webhook", key: "webhook" },
{ path: "/store/websocket", key: "websocket" },
]
const fs = require("fs")
const path = require("path")
module.exports = async (instanceName, options, progressBars, conn, connInstance) => {
var files = []
FOLDER_PATH.forEach(folder => {
files = files.concat(getFiles(instanceName, folder))
})
const progress = progressBars.create(files.length, 0)
progress.update({ process: 'Instance' })
for (const file of files) {
const collectionName = file.key || instanceName
const collection = (!file.secondaryConnection ? conn : connInstance).collection(collectionName)
const data = JSON.parse(fs.readFileSync(file.path, 'utf8'))
data._id = file.path.split('\\').pop().split('.')[0]
await collection.findOneAndUpdate({ _id: data._id }, { $set: data }, { upsert: true })
progress.increment()
}
}
function getFiles(instanceName, opts) {
var files = []
const folder = opts.path || opts
const folderPath = path.join(process.cwd(), folder)
fs.readdirSync(folderPath).forEach(file => {
const filePath = path.join(folderPath, file)
if (fs.statSync(filePath).isDirectory()) {
files = files.concat(getFiles(instanceName, { ...opts, path: `${folder}/${file}` }))
} else if (file.includes(instanceName) || opts.path.includes(instanceName)) {
files.push({ ...opts, path: filePath })
}
})
return files
}

View File

@ -0,0 +1,44 @@
const FOLDER_PATH = [{
path: "/store/message-up",
key: "messageUpdate"
}]
const fs = require("fs")
const path = require("path")
module.exports = async (instanceName, options, progressBars, conn) => {
var files = []
FOLDER_PATH.forEach(folder => {
files = files.concat(getFiles(instanceName, folder))
})
const progress = progressBars.create(files.length, 0)
progress.update({ process: 'Message Update' })
for (const file of files) {
const collectionName = file.key
const collection = conn.collection(collectionName)
const data = JSON.parse(fs.readFileSync(file.path, 'utf8'))
data._id = file.path.split('\\').pop().split('.')[0]
await collection.findOneAndUpdate({ _id: data._id }, { $set: data }, { upsert: true })
progress.increment()
}
}
function getFiles(instanceName, opts) {
var files = []
const folder = opts.path || opts
const folderPath = path.join(process.cwd(), folder)
fs.readdirSync(folderPath).forEach(file => {
const filePath = path.join(folderPath, file)
if (fs.statSync(filePath).isDirectory()) {
files = files.concat(getFiles(instanceName, { ...opts, path: `${folder}/${file}` }))
} else if (file.includes(instanceName) || folder.includes(instanceName)) {
files.push({ ...opts, path: filePath })
}
})
return files
}

View File

@ -0,0 +1,44 @@
const FOLDER_PATH = [{
path: "/store/messages",
key: "messages"
}]
const fs = require("fs")
const path = require("path")
module.exports = async (instanceName, options, progressBars, conn) => {
var files = []
FOLDER_PATH.forEach(folder => {
files = files.concat(getFiles(instanceName, folder))
})
const progress = progressBars.create(files.length, 0)
progress.update({ process: 'Messages' })
for (const file of files) {
const collectionName = file.key
const collection = conn.collection(collectionName)
const data = JSON.parse(fs.readFileSync(file.path, 'utf8'))
data._id = file.path.split('\\').pop().split('.')[0]
await collection.findOneAndUpdate({ _id: data._id }, { $set: data }, { upsert: true })
progress.increment()
}
}
function getFiles(instanceName, opts) {
var files = []
const folder = opts.path || opts
const folderPath = path.join(process.cwd(), folder)
fs.readdirSync(folderPath).forEach(file => {
const filePath = path.join(folderPath, file)
if (fs.statSync(filePath).isDirectory()) {
files = files.concat(getFiles(instanceName, { ...opts, path: `${folder}/${file}` }))
} else if (file.includes(instanceName) || folder.includes(instanceName)) {
files.push({ ...opts, path: filePath })
}
})
return files
}

3016
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
{
"name": "evolution-manager",
"description": "Evolution Manager is an open-source interface for managing the Evolution API, simplifying the creation and administration of API instances with advanced features and diverse integrations.",
"version": "0.4.5",
"version": "0.4.6",
"main": "dist",
"engines": {
"node": ">=16.0.0"
@ -19,10 +19,14 @@
"dependencies": {
"@mdi/font": "7.0.96",
"@vitejs/plugin-vue": "^4.0.0",
"ansi-colors": "^4.1.3",
"axios": "^1.6.0",
"cli-progress": "^3.12.0",
"core-js": "^3.29.0",
"eslint": "^8.37.0",
"eslint-plugin-vue": "^9.3.0",
"inquirer": "^8.0.0",
"mongoose": "^8.0.3",
"optimist": "^0.6.1",
"pinia": "^2.0.0",
"pm2": "^5.3.0",

2499
yarn.lock

File diff suppressed because it is too large Load Diff