mirror of
https://github.com/sergeyyarkov/modbus-logger.git
synced 2026-10-11 02:18:51 +03:00
progress
This commit is contained in:
parent
8e1481016e
commit
1cdf164fba
@ -13,9 +13,12 @@ export function validateBodyMiddleware(schema) {
|
|||||||
await schema.validate(req.body);
|
await schema.validate(req.body);
|
||||||
next();
|
next();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return res.status(400).json({ error: {
|
return res.status(400).json({
|
||||||
message: error.errors[0]
|
error: {
|
||||||
}});
|
status: 400,
|
||||||
|
message: error.errors[0],
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,8 +21,8 @@ CREATE TABLE IF NOT EXISTS "app_config" (
|
|||||||
CREATE TABLE IF NOT EXISTS "modbus_slaves" (
|
CREATE TABLE IF NOT EXISTS "modbus_slaves" (
|
||||||
"id" INTEGER CHECK (id >= 1 AND id <= 255),
|
"id" INTEGER CHECK (id >= 1 AND id <= 255),
|
||||||
"name" VARCHAR(256) NOT NULL,
|
"name" VARCHAR(256) NOT NULL,
|
||||||
"display_addr" INTEGER CHECK(display_addr >= 0 AND display_addr <= 65534),
|
"display_reg_addr" INTEGER CHECK(display_reg_addr >= 0 AND display_reg_addr <= 65534),
|
||||||
-- "display_val_format" INTEGER CHECK IN(16, 32) NOT NULL,
|
"display_reg_format" INTEGER CHECK(display_reg_format IN(16, 32)),
|
||||||
"is_logging" BOOLEAN NOT NULL,
|
"is_logging" BOOLEAN NOT NULL,
|
||||||
PRIMARY KEY("id")
|
PRIMARY KEY("id")
|
||||||
);
|
);
|
||||||
|
|||||||
@ -603,15 +603,21 @@ video {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-2 {
|
|
||||||
margin: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx-auto {
|
.mx-auto {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.my-4 {
|
||||||
|
margin-top: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-2 {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.ml-auto {
|
.ml-auto {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
@ -640,6 +646,10 @@ video {
|
|||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-10 {
|
||||||
|
margin-top: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -664,10 +674,18 @@ video {
|
|||||||
height: 5rem;
|
height: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.h-full {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.h-screen {
|
.h-screen {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-h-\[520px\] {
|
||||||
|
max-height: 520px;
|
||||||
|
}
|
||||||
|
|
||||||
.w-1 {
|
.w-1 {
|
||||||
width: 0.25rem;
|
width: 0.25rem;
|
||||||
}
|
}
|
||||||
@ -676,32 +694,12 @@ video {
|
|||||||
width: 5rem;
|
width: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-48 {
|
|
||||||
width: 12rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-72 {
|
|
||||||
width: 18rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-full {
|
.w-full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-24 {
|
.min-w-\[256px\] {
|
||||||
width: 6rem;
|
min-width: 256px;
|
||||||
}
|
|
||||||
|
|
||||||
.w-16 {
|
|
||||||
width: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-12 {
|
|
||||||
width: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-64 {
|
|
||||||
width: 16rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.max-w-2xl {
|
.max-w-2xl {
|
||||||
@ -712,6 +710,14 @@ video {
|
|||||||
max-width: 72rem;
|
max-width: 72rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.max-w-5xl {
|
||||||
|
max-width: 64rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-auto {
|
.flex-auto {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
@ -730,6 +736,16 @@ video {
|
|||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cursor-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-none {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
.resize {
|
.resize {
|
||||||
resize: both;
|
resize: both;
|
||||||
}
|
}
|
||||||
@ -756,12 +772,22 @@ video {
|
|||||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
||||||
|
--tw-space-y-reverse: 0;
|
||||||
|
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
|
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
|
||||||
|
}
|
||||||
|
|
||||||
.space-y-3 > :not([hidden]) ~ :not([hidden]) {
|
.space-y-3 > :not([hidden]) ~ :not([hidden]) {
|
||||||
--tw-space-y-reverse: 0;
|
--tw-space-y-reverse: 0;
|
||||||
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
|
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
|
||||||
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overflow-y-auto {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.rounded-sm {
|
.rounded-sm {
|
||||||
border-radius: 0.125rem;
|
border-radius: 0.125rem;
|
||||||
}
|
}
|
||||||
@ -770,6 +796,14 @@ video {
|
|||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.border-2 {
|
||||||
|
border-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-b {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.border-l {
|
.border-l {
|
||||||
border-left-width: 1px;
|
border-left-width: 1px;
|
||||||
}
|
}
|
||||||
@ -778,6 +812,10 @@ video {
|
|||||||
border-right-width: 1px;
|
border-right-width: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.border-dashed {
|
||||||
|
border-style: dashed;
|
||||||
|
}
|
||||||
|
|
||||||
.fill-blue-600 {
|
.fill-blue-600 {
|
||||||
fill: #2563eb;
|
fill: #2563eb;
|
||||||
}
|
}
|
||||||
@ -786,6 +824,14 @@ video {
|
|||||||
padding: 2.5rem;
|
padding: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-2 {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-2\.5 {
|
||||||
|
padding: 0.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
.p-20 {
|
.p-20 {
|
||||||
padding: 5rem;
|
padding: 5rem;
|
||||||
}
|
}
|
||||||
@ -816,19 +862,13 @@ video {
|
|||||||
padding-right: 0.625rem;
|
padding-right: 0.625rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.py-1 {
|
.py-3 {
|
||||||
padding-top: 0.25rem;
|
padding-top: 0.75rem;
|
||||||
padding-bottom: 0.25rem;
|
padding-bottom: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.py-1\.5 {
|
.pt-5 {
|
||||||
padding-top: 0.375rem;
|
padding-top: 1.25rem;
|
||||||
padding-bottom: 0.375rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.py-8 {
|
|
||||||
padding-top: 2rem;
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-center {
|
.text-center {
|
||||||
@ -845,6 +885,11 @@ video {
|
|||||||
line-height: 2.25rem;
|
line-height: 2.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-5xl {
|
||||||
|
font-size: 3rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.text-sm {
|
.text-sm {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
line-height: 1.25rem;
|
line-height: 1.25rem;
|
||||||
@ -863,6 +908,11 @@ video {
|
|||||||
color: rgb(229 231 235 / var(--tw-text-opacity));
|
color: rgb(229 231 235 / var(--tw-text-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-gray-400 {
|
||||||
|
--tw-text-opacity: 1;
|
||||||
|
color: rgb(156 163 175 / var(--tw-text-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.text-gray-700 {
|
.text-gray-700 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
color: rgb(55 65 81 / var(--tw-text-opacity));
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
||||||
@ -921,6 +971,11 @@ button:disabled {
|
|||||||
pointer-events: all !important;
|
pointer-events: all !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hover\:bg-gray-50:hover {
|
||||||
|
--tw-bg-opacity: 1;
|
||||||
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.dark\:text-gray-600 {
|
.dark\:text-gray-600 {
|
||||||
--tw-text-opacity: 1;
|
--tw-text-opacity: 1;
|
||||||
|
|||||||
@ -5,34 +5,55 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Modbus Logger App</title>
|
<title>Modbus Logger App</title>
|
||||||
<link rel="stylesheet" href="/css/dist.css" />
|
<link rel="stylesheet" href="/css/dist.css" />
|
||||||
|
<script defer src="/js/dygraphs.min.js"></script>
|
||||||
<script defer type="module" src="/js/app.js"></script>
|
<script defer type="module" src="/js/app.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="m-2">
|
<body>
|
||||||
<!-- <div class="border p-4" x-data>
|
<!-- <div class="border p-4" x-data>
|
||||||
<span>app state:</span>
|
<span>app state:</span>
|
||||||
<pre x-text="JSON.stringify($store.app, undefined, 2)"></pre>
|
<pre x-text="JSON.stringify($store.app, undefined, 2)"></pre>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<!-- Root element -->
|
<!-- Root element -->
|
||||||
<div x-data x-cloak class="mx-auto max-w-6xl m-2 py-8">
|
<div x-data x-cloak class="mx-auto max-w-5xl flex flex-col h-screen">
|
||||||
<!-- Monitoring content -->
|
<!-- Monitoring content -->
|
||||||
<main x-bind:hidden="$store.app.currentPage !== 'monitoring'">
|
<main class="flex-1" x-bind:hidden="$store.app.currentPage !== 'monitoring'">
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
<h1 class="text-3xl font-bold">Monitoring page</h1>
|
<h1 class="text-3xl font-bold">Monitoring page</h1>
|
||||||
<button @click="$store.app.setPage('configuration')" class="btn">Config</button>
|
<button @click="$store.app.setPage('configuration')" class="btn">Config</button>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="flex flex-auto flex-row h-screen space-x-2">
|
<div class="flex h-full flex-row space-x-2">
|
||||||
<div class="border-r w-64 p-4">
|
<div class="border-r min-w-[256px] p-2.5 pt-5">
|
||||||
<div class="w-full border px-2.5 py-1.5 rounded-sm">
|
<div class="flex flex-col space-y-2">
|
||||||
<h2 class="text-sm">Modbus slave #1</h2>
|
<span class="italic text-sm">Devices list:</span>
|
||||||
|
<div class="flex flex-col max-h-[520px] overflow-y-auto space-y-2">
|
||||||
|
<div class="w-full select-none border px-2.5 py-3 rounded-sm hover:bg-gray-50 cursor-pointer">
|
||||||
|
<h2 class="text-md font-bold">Device #1</h2>
|
||||||
|
</div>
|
||||||
|
<div class="w-full select-none border px-2.5 py-3 rounded-sm hover:bg-gray-50 cursor-pointer">
|
||||||
|
<h2 class="text-md font-bold">Device #2</h2>
|
||||||
|
</div>
|
||||||
|
<div class="w-full select-none border px-2.5 py-3 rounded-sm hover:bg-gray-50 cursor-pointer">
|
||||||
|
<h2 class="text-md font-bold">Device #3</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full">
|
<div class="w-full text-center border-2 border-dashed rounded-sm hover:bg-gray-50 cursor-pointer">
|
||||||
graph...
|
<span class="text-5xl text-gray-400 select-none">+</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-l w-48 p-4">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<hr class="my-4" />
|
||||||
|
<div><span class="italic text-sm">Connection:</span><br /></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex-auto">
|
||||||
|
<div class="pt-5 border-b">
|
||||||
|
<h2 class="font-bold text-3xl my-2">Device #1</h2>
|
||||||
|
</div>
|
||||||
|
<div class="mt-4">
|
||||||
|
<div id="div_g" style="width: 720px; height: 300px"></div>
|
||||||
|
</div>
|
||||||
|
<hr class="mt-10" />
|
||||||
|
</div>
|
||||||
|
<!-- <div class="border-l"></div> -->
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@ -222,8 +243,7 @@
|
|||||||
<p>Refresh page to try again.</p>
|
<p>Refresh page to try again.</p>
|
||||||
<br />
|
<br />
|
||||||
<div class="border p-4">
|
<div class="border p-4">
|
||||||
<pre x-text="JSON.stringify($store.app.error, undefined, 2)" x-show="$store.app.error">
|
<pre x-text="JSON.stringify($store.app.error, undefined, 2)" x-show="$store.app.error"></pre>
|
||||||
</pre>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@ -1,9 +1,33 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import "./alpine.js";
|
import "./alpine.js";
|
||||||
import api from "./api.js";
|
import api from "./api.js";
|
||||||
import * as utils from './utils/index.js'
|
import * as utils from "./utils/index.js";
|
||||||
|
|
||||||
const pages = ['loading', 'monitoring', 'configuration', '404']
|
const pages = ["loading", "monitoring", "configuration", "404"];
|
||||||
|
|
||||||
|
var data = [];
|
||||||
|
var t = new Date();
|
||||||
|
|
||||||
|
for (var i = 10; i >= 0; i--) {
|
||||||
|
var x = new Date(t.getTime() - i * 1000);
|
||||||
|
data.push([x, Math.random()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
var g = new Dygraph(document.getElementById("div_g"), data, {
|
||||||
|
drawPoints: false,
|
||||||
|
showRoller: false,
|
||||||
|
// valueRange: [0.0, 6.8],
|
||||||
|
labels: ["Time", "Random"],
|
||||||
|
});
|
||||||
|
|
||||||
|
window.intervalId = setInterval(function () {
|
||||||
|
var x = new Date(); // current time
|
||||||
|
var y = Math.random();
|
||||||
|
data.push([x, y]);
|
||||||
|
g.updateOptions({ file: data });
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener("alpine:init", async () => {
|
document.addEventListener("alpine:init", async () => {
|
||||||
Alpine.store("app", {
|
Alpine.store("app", {
|
||||||
@ -31,7 +55,7 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
|
|
||||||
if (config) this.config = config;
|
if (config) this.config = config;
|
||||||
if (is_configured) {
|
if (is_configured) {
|
||||||
const devices = await api.get('/modbus/devices');
|
const devices = await api.get("/modbus/devices");
|
||||||
this.devices = devices;
|
this.devices = devices;
|
||||||
this.currentPage = "monitoring";
|
this.currentPage = "monitoring";
|
||||||
return;
|
return;
|
||||||
@ -39,19 +63,19 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
|
|
||||||
this.currentPage = "configuration";
|
this.currentPage = "configuration";
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.currentPage = 'error'
|
this.currentPage = "error";
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setPage(page) {
|
setPage(page) {
|
||||||
if (!pages.includes(page)) {
|
if (!pages.includes(page)) {
|
||||||
this.currentPage = '404'
|
this.currentPage = "404";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentPage = page;
|
this.currentPage = page;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Alpine.data("configAppPage", () => ({
|
Alpine.data("configAppPage", () => ({
|
||||||
@ -64,9 +88,15 @@ document.addEventListener("alpine:init", async () => {
|
|||||||
this.errorMessage = "";
|
this.errorMessage = "";
|
||||||
const data = { ...this.$store.app.config };
|
const data = { ...this.$store.app.config };
|
||||||
const body = {
|
const body = {
|
||||||
RTU: utils.objKeysExclude(data, ['mb_tcp_ip', 'mb_tcp_port']),
|
RTU: utils.objKeysExclude(data, ["mb_tcp_ip", "mb_tcp_port"]),
|
||||||
TCP: utils.objKeysExclude(data, ['mb_rtu_path', 'mb_rtu_baud', 'mb_rtu_parity', 'mb_rtu_data_bits', 'mb_rtu_stop_bits'])
|
TCP: utils.objKeysExclude(data, [
|
||||||
}
|
"mb_rtu_path",
|
||||||
|
"mb_rtu_baud",
|
||||||
|
"mb_rtu_parity",
|
||||||
|
"mb_rtu_data_bits",
|
||||||
|
"mb_rtu_stop_bits",
|
||||||
|
]),
|
||||||
|
};
|
||||||
await api.patch("/app/config", body[data.mb_connection_type]);
|
await api.patch("/app/config", body[data.mb_connection_type]);
|
||||||
await api.post("/modbus/connect");
|
await api.post("/modbus/connect");
|
||||||
this.$store.app.currentPage = "monitoring";
|
this.$store.app.currentPage = "monitoring";
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import modbusClient from "#root/config/modbus-client.config.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validators
|
* Validators
|
||||||
@ -9,7 +8,7 @@ import { appConfigSchema } from "#root/validators/index.js";
|
|||||||
/**
|
/**
|
||||||
* Controllers
|
* Controllers
|
||||||
*/
|
*/
|
||||||
import { appController, modbusController } from '#root/controllers/index.js'
|
import { appController, modbusController } from "#root/controllers/index.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middlewares
|
* Middlewares
|
||||||
@ -22,7 +21,7 @@ apiRouter.get("/app/config", appController.getConfig);
|
|||||||
apiRouter.patch("/app/config", validateBodyMiddleware(appConfigSchema), appController.updateConfig);
|
apiRouter.patch("/app/config", validateBodyMiddleware(appConfigSchema), appController.updateConfig);
|
||||||
apiRouter.get("/app/is_configured", appController.isConfigured);
|
apiRouter.get("/app/is_configured", appController.isConfigured);
|
||||||
|
|
||||||
apiRouter.get('/modbus/devices', modbusController.list);
|
apiRouter.get("/modbus/devices", modbusController.list);
|
||||||
apiRouter.post("/modbus/connect", modbusController.connect);
|
apiRouter.post("/modbus/connect", modbusController.connect);
|
||||||
apiRouter.post("/modbus/close", modbusController.close);
|
apiRouter.post("/modbus/close", modbusController.close);
|
||||||
apiRouter.get("/modbus/data_stream", modbusController.streamData);
|
apiRouter.get("/modbus/data_stream", modbusController.streamData);
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import db from '#root/config/database.config.js'
|
import db from "#root/config/database.config.js";
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
await db.migrate({ force: false })
|
await db.migrate({ force: false });
|
||||||
console.log('Database initialized.');
|
console.log("Database initialized.");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user