diff --git a/lib/api/index.js b/lib/api/index.js new file mode 100644 index 0000000..117dbbb --- /dev/null +++ b/lib/api/index.js @@ -0,0 +1,16 @@ +const functions = { + setup: require('./setup.js'), +} + +module.exports = async (argv) => { + try { + if (argv._.length === 1) throw new Error('No operation specified') + const operation = argv._[1] + if (!functions[operation]) throw new Error(`Unknown operation: ${operation}`) + + await functions[operation](argv) + } catch (e) { + console.error(e.message || e) + process.exit(1) + } +} diff --git a/lib/api/setup.js b/lib/api/setup.js new file mode 100644 index 0000000..0569e93 --- /dev/null +++ b/lib/api/setup.js @@ -0,0 +1,65 @@ +const build = require('../utils/build.js'); +const fs = require('fs-extra'); +const path = require('path'); + +module.exports = async () => { + const isEvolutionInstalled = verifyEvolutionInstallation(); + if (!isEvolutionInstalled) return; + console.log('👍 Evolution-Api installation found'); + + await build({ VITE_BASE_URL: '/manager/' }); + + // copy dist folder to evolution-api/Extras/evolution-manager + console.time('📦 Copy dist folder to evolution-api/Extras/evolution-manager'); + + const distFolder = path.join(__dirname, '..', '..', 'dist'); + const extrasFolder = path.join(process.cwd(), 'Extras'); + const evolutionManagerFolder = path.join(extrasFolder, 'evolution-manager'); + + if (!fs.existsSync(evolutionManagerFolder)) fs.mkdirSync(evolutionManagerFolder); + fs.copySync(distFolder, evolutionManagerFolder); + + console.timeEnd('📦 Copy dist folder to evolution-api/Extras/evolution-manager'); + + + // Apply diff git patch + console.time('↘️ Apply diff git patch'); + const patchPath = path.join(__dirname, './view.router.ts.patch'); + const apiFile = path.join(process.cwd(), 'src', 'whatsapp', 'routers', 'view.router.ts'); + // copy/replace file with patch + fs.copySync(patchPath, apiFile); + console.timeEnd('↘️ Apply diff git patch'); + + + console.log('\n 🎉 Evolution-Api Manager installed successfully! 🎉'); + console.log('👉 Restart your Evolution-Api server to apply changes 👈') +}; + +function verifyEvolutionInstallation(version = "1.5.0") { + // load package.json current context + const packageJsonPath = path.join(process.cwd(), 'package.json'); + if (!fs.existsSync(packageJsonPath)) { + console.error("🚨 package.json not found. Certify you are in the root of the Evolution-Api installation") + return false + } + var packageJson = fs.readFileSync(packageJsonPath, 'utf8'); + packageJson = JSON.parse(packageJson); + + + // check if evolution is installed + if (packageJson.name !== "evolution-api") { + console.error("🚨 This is not a Evolution-API installation. Certify you are in the root of the Evolution-Api installation") + return false + } + + // verify if version is same or higher + if (version) { + const semver = require('semver'); + if (!semver.gte(packageJson.version, version)) { + console.error(`🚨 Evolution-Api version ${version} or higher is required. Please update your Evolution-Api installation`) + return false + } + } + + return true +} \ No newline at end of file diff --git a/lib/api/view.router.ts.patch b/lib/api/view.router.ts.patch new file mode 100644 index 0000000..8779516 --- /dev/null +++ b/lib/api/view.router.ts.patch @@ -0,0 +1,39 @@ +import { Router } from 'express'; +import fs from 'fs'; +import mime from 'mime-types'; +import path from 'path'; + +import { RouterBroker } from '../abstract/abstract.router'; + +export class ViewsRouter extends RouterBroker { + constructor() { + super(); + + const index = fs.readFileSync(path.join(__dirname, '../../../', 'Extras/evolution-manager', 'index.html')); + + this.router.get('/*', (req, res) => { + try { + const pathname = req.url.split('?')[0]; + + // verify if url is a file in dist folder + if (pathname === '/') throw {}; + const filePath = path.join(__dirname, '../../../', 'Extras/evolution-manager', pathname); + + if (fs.existsSync(filePath)) { + const contentType = mime.lookup(filePath) || 'text/plain'; + res.set('Content-Type', contentType); + res.end(fs.readFileSync(filePath)); + return; + } + + res.set('Content-Type', 'text/html'); + res.send(index); + } catch { + res.set('Content-Type', 'text/html'); + res.send(index); + } + }); + } + + public readonly router = Router(); +} diff --git a/lib/cli.js b/lib/cli.js index 291e81a..5a784ef 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -5,7 +5,8 @@ const operations = { // 'create': require('./create'), 'help': require('./help'), 'server': require('./server'), - 'pm2': require('./pm2'), + 'pm2': require('./pm2'), + 'api': require('./api'), } diff --git a/lib/help.js b/lib/help.js index 8fe683c..f6c5384 100644 --- a/lib/help.js +++ b/lib/help.js @@ -1,21 +1,31 @@ module.exports = () => { - // welcome message - console.log(`👋 Welcome to evolution-manager CLI!`) + // Welcome message + console.log(`👋 Welcome to evolution-manager CLI!`); - // help message - console.log(`📋 Available commands:`) - console.log(` help`) - console.log(` server`) - console.log(` - start [--port=9615]`) - console.log(` - build`) - console.log(` pm2`) - console.log(` - setup`) - console.log(` - start`) - console.log(` - stop`) - console.log(` - restart`) - console.log(` - delete`) + // Help message + console.log(`📋 Available commands:`); + // Server commands + console.log(`\nServer:`); + console.log(` help`); + console.log(` server`); + console.log(` - start [--port=9615]`); + console.log(` - build`); - // spacing - console.log(`\n`) -} \ No newline at end of file + // PM2 commands + console.log(`\nPM2:`); + console.log(` pm2`); + console.log(` - setup`); + console.log(` - start`); + console.log(` - stop`); + console.log(` - restart`); + console.log(` - delete`); + + // API commands + console.log(`\nAPI:`); + console.log(` api`); + console.log(` - setup (Install the manager inside the Evolution Manager in path /manager)`); + + // Spacing + console.log(`\n`); +}; diff --git a/lib/utils/build.js b/lib/utils/build.js index 6708216..8349c19 100644 --- a/lib/utils/build.js +++ b/lib/utils/build.js @@ -2,7 +2,7 @@ const { exec } = require('child_process') const fs = require('fs') const path = require('path') -module.exports = () => { +module.exports = (envs = {}) => { return new Promise((resolve, reject) => { console.log('📦 Build start') console.time('📦 Build complete') @@ -13,7 +13,8 @@ module.exports = () => { console.timeEnd('📦 Remove dist folder') } - exec('npm run build', { cwd: path.join(__dirname, '..', '..') }, (err, stdout) => { + // pass envs to build + exec(`npm run build`, { env: envs, cwd: path.join(__dirname, '..', '..') }, (err, stdout) => { if (err) { console.error(err) reject(err) diff --git a/package.json b/package.json index 3f230d6..31dca80 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-manager", - "version": "0.2.13", + "version": "0.3.0", "main": "dist", "scripts": { "dev": "vite", diff --git a/src/router/index.js b/src/router/index.js index 0dd88bd..05ee028 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,9 +1,12 @@ // Composables import { createRouter, createWebHistory } from 'vue-router' +// import from base from vite compiler +const BASE_URL = import.meta.env.BASE_URL + const routes = [ { - path: '/', + path: BASE_URL, component: () => import('@/layouts/default/Default.vue'), children: [ { diff --git a/src/views/Home.vue b/src/views/Home.vue index a5ca4c0..6cd2153 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -138,7 +138,10 @@ export default { this.$refs.createInstanceModal.open(); }, goToInstance(instance) { - this.$router.push(`/${instance.instanceName}`); + this.$router.push({ + name: "instance", + params: { id: instance.instanceName }, + }); }, async deleteInstance(instanceName) { try { diff --git a/vite.config.js b/vite.config.js index 3a9e7a5..f259fb0 100644 --- a/vite.config.js +++ b/vite.config.js @@ -4,47 +4,54 @@ import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' import ViteFonts from 'unplugin-fonts/vite' // Utilities -import { defineConfig } from 'vite' +import { defineConfig, loadEnv } from 'vite' import { fileURLToPath, URL } from 'node:url' // https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - vue({ - template: { transformAssetUrls } - }), - // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin - vuetify({ - autoImport: true, - styles: { - configFile: 'src/styles/settings.scss', - }, - }), - ViteFonts({ - google: { - families: [{ - name: 'Roboto', - styles: 'wght@100;300;400;500;700;900', - }], - }, - }), - ], - define: { 'process.env': {} }, - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - }, - extensions: [ - '.js', - '.json', - '.jsx', - '.mjs', - '.ts', - '.tsx', - '.vue', +export default defineConfig(({ command, mode }) => { + const env = loadEnv(mode, process.cwd(), '') + const BASE_URL = env.VITE_BASE_URL || '/' + + return { + plugins: [ + vue({ + template: { transformAssetUrls } + }), + // https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vite-plugin + vuetify({ + autoImport: true, + styles: { + configFile: 'src/styles/settings.scss', + }, + }), + ViteFonts({ + google: { + families: [{ + name: 'Roboto', + styles: 'wght@100;300;400;500;700;900', + }], + }, + }), ], - }, - server: { - port: 3000, - }, + define: { 'process.env': {} }, + base: BASE_URL, + + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + }, + extensions: [ + '.js', + '.json', + '.jsx', + '.mjs', + '.ts', + '.tsx', + '.vue', + ], + }, + server: { + port: 3000, + }, + } })