Compare commits

..

1 Commits

Author SHA1 Message Date
8d69488937 Update to 1.0.3 2023-11-13 18:12:49 +08:00
28 changed files with 211 additions and 691 deletions

View File

@ -92,9 +92,6 @@ module.exports = {
"one-var": [ "error", "never" ],
"max-statements-per-line": [ "error", { "max": 1 }],
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": [ "warn", {
"args": "none"
}],
"prefer-const" : "off",
},
};

View File

@ -1,60 +0,0 @@
name: Node.js CI - Dockge
on:
push:
branches: [master]
paths-ignore:
- '*.md'
pull_request:
branches: [master]
paths-ignore:
- '*.md'
jobs:
ci:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [20.x] # Can be changed
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- run: git config --global core.autocrlf false # Mainly for Windows
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{matrix.node}}
- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 8
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install
- name: Lint
run: pnpm run lint
- name: Check Typescript
run: pnpm run check-ts
# more things can be add later like tests etc..

View File

@ -68,6 +68,8 @@ Dockge is now running on http://localhost:5001
If you want to store your stacks in another directory, you can change the `DOCKGE_STACKS_DIR` environment variable and volumes.
For example, if you want to store your stacks in `/my-stacks`:
```yaml
version: "3.8"
services:
@ -84,14 +86,12 @@ services:
# If you want to use private registries, you need to share the auth file with Dockge:
# - /root/.docker/:/root/.docker
# Your stacks directory in the host (The paths inside container must be the same as the host)
# ⚠️⚠️ If you did it wrong, your data could end up be written into a wrong path.
# ✔️✔️✔️✔️ CORRECT EXAMPLE: - /my-stacks:/my-stacks (Both paths match)
# ❌❌❌❌ WRONG EXAMPLE: - /docker:/my-stacks (Both paths do not match)
- /opt/stacks:/opt/stacks
# Your stacks directory in the host
# (The paths inside container must be the same as the host)
- /my-stacks:/my-stacks
environment:
# Tell Dockge where is your stacks directory
- DOCKGE_STACKS_DIR=/opt/stacks
- DOCKGE_STACKS_DIR=/my-stacks
```
## How to Update

View File

@ -5,7 +5,6 @@ import fs from "fs";
import path from "path";
import knex from "knex";
// @ts-ignore
import Dialect from "knex/lib/dialects/sqlite3/index.js";
import sqlite from "@louislam/sqlite3";
@ -13,11 +12,6 @@ import { sleep } from "./util-common";
interface DBConfig {
type?: "sqlite" | "mysql";
hostname?: string;
port?: string;
database?: string;
username?: string;
password?: string;
}
export class Database {
@ -25,7 +19,7 @@ export class Database {
* SQLite file path (Default: ./data/dockge.db)
* @type {string}
*/
static sqlitePath : string;
static sqlitePath;
static noReject = true;
@ -57,7 +51,7 @@ export class Database {
* @typedef {string|undefined} envString
* @returns {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString}} Database config
*/
static readDBConfig() : DBConfig {
static readDBConfig() {
const dbConfigString = fs.readFileSync(path.join(this.server.config.dataDir, "db-config.json")).toString("utf-8");
const dbConfig = JSON.parse(dbConfigString);
@ -73,10 +67,10 @@ export class Database {
/**
* @typedef {string|undefined} envString
* @param dbConfig the database configuration that should be written
* @param {{type: "sqlite"} | {type:envString, hostname:envString, port:envString, database:envString, username:envString, password:envString}} dbConfig the database configuration that should be written
* @returns {void}
*/
static writeDBConfig(dbConfig : DBConfig) {
static writeDBConfig(dbConfig) {
fs.writeFileSync(path.join(this.server.config.dataDir, "db-config.json"), JSON.stringify(dbConfig, null, 4));
}
@ -86,17 +80,14 @@ export class Database {
* @param {boolean} noLog Should logs not be output?
* @returns {Promise<void>}
*/
static async connect(autoloadModels = true) {
static async connect(autoloadModels = true, noLog = false) {
const acquireConnectionTimeout = 120 * 1000;
let dbConfig : DBConfig;
let dbConfig;
try {
dbConfig = this.readDBConfig();
Database.dbConfig = dbConfig;
} catch (err) {
if (err instanceof Error) {
log.warn("db", err.message);
}
dbConfig = {
type: "sqlite",
};
@ -185,7 +176,6 @@ export class Database {
directory: Database.knexMigrationsPath,
});
} catch (e) {
if (e instanceof Error) {
// Allow missing patch files for downgrade or testing pr.
if (e.message.includes("the following files are missing:")) {
log.warn("db", e.message);
@ -196,7 +186,6 @@ export class Database {
}
}
}
}
/**
* Special handle, because tarn.js throw a promise reject that cannot be caught

View File

@ -60,7 +60,7 @@ export class DockgeServer {
*/
needSetup = false;
jwtSecret : string = "";
jwtSecret? : string;
stacksDir : string = "";
@ -129,7 +129,7 @@ export class DockgeServer {
this.config.sslKey = args.sslKey || process.env.DOCKGE_SSL_KEY || undefined;
this.config.sslCert = args.sslCert || process.env.DOCKGE_SSL_CERT || undefined;
this.config.sslKeyPassphrase = args.sslKeyPassphrase || process.env.DOCKGE_SSL_KEY_PASSPHRASE || undefined;
this.config.port = args.port || Number(process.env.DOCKGE_PORT) || 5001;
this.config.port = args.port || parseInt(process.env.DOCKGE_PORT) || 5001;
this.config.hostname = args.hostname || process.env.DOCKGE_HOSTNAME || undefined;
this.config.dataDir = args.dataDir || process.env.DOCKGE_DATA_DIR || "./data/";
this.config.stacksDir = args.stacksDir || process.env.DOCKGE_STACKS_DIR || defaultStacksDir;
@ -218,7 +218,7 @@ export class DockgeServer {
log.debug("auth", "check auto login");
if (await Settings.get("disableAuth")) {
log.info("auth", "Disabled Auth: auto login to admin");
this.afterLogin(socket as DockgeSocket, await R.findOne("user") as User);
this.afterLogin(socket as DockgeSocket, await R.findOne("user"));
socket.emit("autoLogin");
} else {
log.debug("auth", "need auth");
@ -253,9 +253,7 @@ export class DockgeServer {
try {
await Database.init(this);
} catch (e) {
if (e instanceof Error) {
log.error("server", "Failed to prepare your database: " + e.message);
}
process.exit(1);
}
@ -293,7 +291,7 @@ export class DockgeServer {
}
// Run every 5 seconds
Cron("*/2 * * * * *", {
const job = Cron("*/2 * * * * *", {
protect: true, // Enabled over-run protection.
}, () => {
log.debug("server", "Cron job running");
@ -378,10 +376,8 @@ export class DockgeServer {
return process.env.TZ;
}
} catch (e) {
if (e instanceof Error) {
log.warn("timezone", e.message + " in process.env.TZ");
}
}
const timezone = await Settings.get("serverTimezone");
@ -393,10 +389,8 @@ export class DockgeServer {
return timezone;
}
} catch (e) {
if (e instanceof Error) {
log.warn("timezone", e.message + " in settings");
}
}
// Guess
try {

View File

@ -17,7 +17,7 @@ export function generatePasswordHash(password : string) {
* @param {string} hash Hash to verify against
* @returns {boolean} Does the password match the hash?
*/
export function verifyPassword(password : string, hash : string) {
export function verifyPassword(password, hash) {
return bcrypt.compareSync(password, hash);
}
@ -37,7 +37,7 @@ export const SHAKE256_LENGTH = 16;
* @param {number} len Output length of the hash
* @returns {string} The hashed data in hex format
*/
export function shake256(data : string, len : number) {
export function shake256(data, len) {
if (!data) {
return "";
}

View File

@ -1,14 +1,8 @@
// "limit" is bugged in Typescript, use "limiter-es6-compat" instead
// See https://github.com/jhurliman/node-rate-limiter/issues/80
import { RateLimiter, RateLimiterOpts } from "limiter-es6-compat";
import { RateLimiter } from "limiter-es6-compat";
import { log } from "./log";
export interface KumaRateLimiterOpts extends RateLimiterOpts {
errorMessage : string;
}
export type KumaRateLimiterCallback = (err : object) => void;
class KumaRateLimiter {
errorMessage : string;
@ -17,7 +11,7 @@ class KumaRateLimiter {
/**
* @param {object} config Rate limiter configuration object
*/
constructor(config : KumaRateLimiterOpts) {
constructor(config) {
this.errorMessage = config.errorMessage;
this.rateLimiter = new RateLimiter(config);
}
@ -30,11 +24,11 @@ class KumaRateLimiter {
/**
* Should the request be passed through
* @param callback Callback function to call with decision
* @param {passCB} callback Callback function to call with decision
* @param {number} num Number of tokens to remove
* @returns {Promise<boolean>} Should the request be allowed?
*/
async pass(callback : KumaRateLimiterCallback, num = 1) {
async pass(callback, num = 1) {
const remainingRequests = await this.removeTokens(num);
log.info("rate-limit", "remaining requests: " + remainingRequests);
if (remainingRequests < 0) {

View File

@ -1,4 +1,4 @@
import { DockgeServer } from "../dockge-server";
import { DockgeServer } from "../dockgeServer";
import { Router } from "../router";
import express, { Express, Router as ExpressRouter } from "express";

View File

@ -1,6 +1,5 @@
import { R } from "redbean-node";
import { log } from "./log";
import { LooseObject } from "./util-common";
export class Settings {
@ -16,19 +15,20 @@ export class Settings {
* timestamp: 12345678
* },
* }
* @type {{}}
*/
static cacheList : LooseObject = {
static cacheList = {
};
static cacheCleaner? : NodeJS.Timeout;
static cacheCleaner = null;
/**
* Retrieve value of setting based on key
* @param key Key of setting to retrieve
* @returns Value
* @param {string} key Key of setting to retrieve
* @returns {Promise<any>} Value
*/
static async get(key : string) {
static async get(key) {
// Start cache clear if not started yet
if (!Settings.cacheCleaner) {
@ -72,12 +72,12 @@ export class Settings {
/**
* Sets the specified setting to specified value
* @param key Key of setting to set
* @param value Value to set to
* @param {string} key Key of setting to set
* @param {any} value Value to set to
* @param {?string} type Type of setting
* @returns {Promise<void>}
*/
static async set(key : string, value : object | string | number | boolean, type : string | null = null) {
static async set(key, value, type = null) {
let bean = await R.findOne("setting", " `key` = ? ", [
key,
@ -95,15 +95,15 @@ export class Settings {
/**
* Get settings based on type
* @param type The type of setting
* @returns Settings
* @param {string} type The type of setting
* @returns {Promise<Bean>} Settings
*/
static async getSettings(type : string) {
static async getSettings(type) {
const list = await R.getAll("SELECT `key`, `value` FROM setting WHERE `type` = ? ", [
type,
]);
const result : LooseObject = {};
const result = {};
for (const row of list) {
try {
@ -118,11 +118,11 @@ export class Settings {
/**
* Set settings based on type
* @param type Type of settings to set
* @param data Values of settings
* @param {string} type Type of settings to set
* @param {object} data Values of settings
* @returns {Promise<void>}
*/
static async setSettings(type : string, data : LooseObject) {
static async setSettings(type, data) {
const keyList = Object.keys(data);
const promiseList = [];
@ -154,7 +154,7 @@ export class Settings {
* @param {string[]} keyList Keys to remove
* @returns {void}
*/
static deleteCache(keyList : string[]) {
static deleteCache(keyList) {
for (const key of keyList) {
delete Settings.cacheList[key];
}
@ -167,7 +167,7 @@ export class Settings {
static stopCacheCleaner() {
if (Settings.cacheCleaner) {
clearInterval(Settings.cacheCleaner);
Settings.cacheCleaner = undefined;
Settings.cacheCleaner = null;
}
}
}

View File

@ -1,11 +1,12 @@
import { SocketHandler } from "../socket-handler.js";
import { Socket } from "socket.io";
import { DockgeServer } from "../dockge-server";
import { log } from "../log";
import { R } from "redbean-node";
import { loginRateLimiter, twoFaRateLimiter } from "../rate-limiter";
import { generatePasswordHash, needRehashPassword, shake256, SHAKE256_LENGTH, verifyPassword } from "../password-hash";
import { User } from "../models/user";
import { checkLogin, DockgeSocket, doubleCheckPassword, JWTDecoded } from "../util-server";
import { checkLogin, DockgeSocket, doubleCheckPassword } from "../util-server";
import { passwordStrength } from "check-password-strength";
import jwt from "jsonwebtoken";
import { Settings } from "../settings";
@ -42,13 +43,11 @@ export class MainSocketHandler extends SocketHandler {
});
} catch (e) {
if (e instanceof Error) {
callback({
ok: false,
msg: e.message,
});
}
}
});
// Login by token
@ -58,7 +57,7 @@ export class MainSocketHandler extends SocketHandler {
log.info("auth", `Login by token. IP=${clientIP}`);
try {
const decoded = jwt.verify(token, server.jwtSecret) as JWTDecoded;
const decoded = jwt.verify(token, server.jwtSecret);
log.info("auth", "Username from JWT: " + decoded.username);
@ -92,13 +91,9 @@ export class MainSocketHandler extends SocketHandler {
});
}
} catch (error) {
if (!(error instanceof Error)) {
console.error("Unknown error:", error);
return;
}
log.error("auth", `Invalid token. IP=${clientIP}`);
if (error.message) {
log.error("auth", error.message + ` IP=${clientIP}`);
log.error("auth", error.message, `IP=${clientIP}`);
}
callback({
ok: false,
@ -154,7 +149,6 @@ export class MainSocketHandler extends SocketHandler {
}
if (data.token) {
// @ts-ignore
const verify = notp.totp.verify(data.token, user.twofa_secret, twoFAVerifyOptions);
if (user.twofa_last_token !== data.token && verify) {
@ -217,13 +211,11 @@ export class MainSocketHandler extends SocketHandler {
});
} catch (e) {
if (e instanceof Error) {
callback({
ok: false,
msg: e.message,
});
}
}
});
socket.on("getSettings", async (callback) => {
@ -237,13 +229,11 @@ export class MainSocketHandler extends SocketHandler {
});
} catch (e) {
if (e instanceof Error) {
callback({
ok: false,
msg: e.message,
});
}
}
});
socket.on("setSettings", async (data, currentPassword, callback) => {
@ -272,24 +262,22 @@ export class MainSocketHandler extends SocketHandler {
server.sendInfo(socket);
} catch (e) {
if (e instanceof Error) {
callback({
ok: false,
msg: e.message,
});
}
}
});
}
async login(username : string, password : string) : Promise<User | null> {
async login(username : string, password : string) {
if (typeof username !== "string" || typeof password !== "string") {
return null;
}
const user = await R.findOne("user", " username = ? AND active = 1 ", [
username,
]) as User;
]);
if (user && verifyPassword(password, user.password)) {
// Upgrade the hash to bcrypt

View File

@ -38,13 +38,11 @@ export class TerminalSocketHandler extends SocketHandler {
throw new Error("Terminal not found or it is not a Interactive Terminal.");
}
} catch (e) {
if (e instanceof Error) {
errorCallback({
ok: false,
msg: e.message,
});
}
}
});
// Main Terminal

View File

@ -24,7 +24,6 @@ export class Stack {
protected _status: number = UNKNOWN;
protected _composeYAML?: string;
protected _configFilePath?: string;
protected _composeFileName: string = "compose.yaml";
protected server: DockgeServer;
protected combinedTerminal? : Terminal;
@ -35,15 +34,6 @@ export class Stack {
this.name = name;
this.server = server;
this._composeYAML = composeYAML;
// Check if compose file name is different from compose.yaml
const supportedFileNames = [ "compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml" ];
for (const filename of supportedFileNames) {
if (fs.existsSync(path.join(this.path, filename))) {
this._composeFileName = filename;
break;
}
}
}
toJSON() : object {
@ -60,7 +50,6 @@ export class Stack {
status: this._status,
tags: [],
isManagedByDockge: this.isManagedByDockge,
composeFileName: this._composeFileName,
};
}
@ -95,7 +84,7 @@ export class Stack {
get composeYAML() : string {
if (this._composeYAML === undefined) {
try {
this._composeYAML = fs.readFileSync(path.join(this.path, this._composeFileName), "utf-8");
this._composeYAML = fs.readFileSync(path.join(this.path, "compose.yaml"), "utf-8");
} catch (e) {
this._composeYAML = "";
}
@ -146,7 +135,7 @@ export class Stack {
}
// Write or overwrite the compose.yaml
fs.writeFileSync(path.join(dir, this._composeFileName), this.composeYAML);
fs.writeFileSync(path.join(dir, "compose.yaml"), this.composeYAML);
}
async deploy(socket? : DockgeSocket) : Promise<number> {
@ -160,7 +149,7 @@ export class Stack {
async delete(socket?: DockgeSocket) : Promise<number> {
const terminalName = getComposeTerminalName(this.name);
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "down", "--remove-orphans" ], this.path);
let exitCode = await Terminal.exec(this.server, socket, terminalName, "docker", [ "compose", "down", "--remove-orphans", "all" ], this.path);
if (exitCode !== 0) {
throw new Error("Failed to delete, please check the terminal output for more information.");
}
@ -197,11 +186,9 @@ export class Stack {
stack._status = CREATED_FILE;
stackList.set(filename, stack);
} catch (e) {
if (e instanceof Error) {
log.warn("getStackList", `Failed to get stack ${filename}, error: ${e.message}`);
}
}
}
// Cache by copying
this.managedStackList = new Map(stackList);
@ -364,11 +351,7 @@ export class Stack {
for (let line of lines) {
try {
let obj = JSON.parse(line);
if (obj.Health === "") {
statusList.set(obj.Service, obj.State);
} else {
statusList.set(obj.Service, obj.Health);
}
} catch (e) {
}
}

View File

@ -54,11 +54,9 @@ export class Terminal {
try {
this.ptyProcess?.resize(this.cols, this.rows);
} catch (e) {
if (e instanceof Error) {
log.debug("Terminal", "Failed to resize terminal: " + e.message);
}
}
}
get cols() {
return this._cols;
@ -69,11 +67,9 @@ export class Terminal {
try {
this.ptyProcess?.resize(this.cols, this.rows);
} catch (e) {
if (e instanceof Error) {
log.debug("Terminal", "Failed to resize terminal: " + e.message);
}
}
}
public start() {
if (this._ptyProcess) {
@ -89,7 +85,7 @@ export class Terminal {
// On Data
this._ptyProcess.onData((data) => {
this.buffer.pushItem(data);
this.buffer.push(data);
if (this.server.io) {
this.server.io.to(this.name).emit("terminalWrite", this.name, data);
}

View File

@ -12,11 +12,6 @@ dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(relativeTime);
export interface LooseObject {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any
}
let randomBytes : (numBytes: number) => Uint8Array;
initRandomBytes();

View File

@ -6,11 +6,6 @@ import { ERROR_TYPE_VALIDATION } from "./util-common";
import { R } from "redbean-node";
import { verifyPassword } from "./password-hash";
export interface JWTDecoded {
username : string;
h? : string;
}
export interface DockgeSocket extends Socket {
userID: number;
consoleTerminal? : Terminal;

View File

@ -4,14 +4,14 @@
*/
export class LimitQueue<T> extends Array<T> {
__limit;
__onExceed? : (item : T | undefined) => void;
__onExceed = null;
constructor(limit: number) {
super();
this.__limit = limit;
}
pushItem(value : T) {
push(value : T) {
super.push(value);
if (this.length > this.__limit) {
const item = this.shift();

View File

@ -7,16 +7,14 @@ services:
# Host Port : Container Port
- 5001:5001
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/app/data
# If you want to use private registries, you need to share the auth file with Dockge:
# - /root/.docker/:/root/.docker
# Docker Socket
- /var/run/docker.sock:/var/run/docker.sock
# Dockge Config
- ./data:/app/data
# Your stacks directory in the host (The paths inside container must be the same as the host)
# ⚠️⚠️ If you did it wrong, your data could end up be written into a wrong path.
# ✔️✔️✔️✔️ CORRECT: - /my-stacks:/my-stacks (Both paths match)
# ❌❌❌❌ WRONG: - /docker:/my-stacks (Both paths do not match)
- /opt/stacks:/opt/stacks
environment:
# Tell Dockge where is your stacks directory

View File

@ -5,7 +5,7 @@
<li v-for="(value, index) in array" :key="index" class="list-group-item">
<select v-model="array[index]" class="no-bg domain-input">
<option value="">Select a network...</option>
<option v-for="option in options" :key="option" :value="option">{{ option }}</option>
<option v-for="option in options" :value="option">{{ option }}</option>
</select>
<font-awesome-icon icon="times" class="action remove ms-2 me-3 text-danger" @click="remove(index)" />

View File

@ -9,7 +9,7 @@
<div v-if="!isEditMode">
<span class="badge me-1" :class="bgStyle">{{ status }}</span>
<a v-for="port in service.ports" :key="port" :href="parsePort(port).url" target="_blank">
<a v-for="port in service.ports" :href="parsePort(port).url" target="_blank">
<span class="badge me-1 bg-secondary">{{ parsePort(port).display }}</span>
</a>
</div>
@ -179,10 +179,8 @@ export default defineComponent({
},
bgStyle() {
if (this.status === "running" || this.status === "healthy") {
if (this.status === "running") {
return "bg-primary";
} else if (this.status === "unhealthy") {
return "bg-danger";
} else {
return "bg-secondary";
}

View File

@ -32,7 +32,7 @@
class="form-control"
@keyup.enter="createExternelNetwork"
/>
<button class="btn btn-normal btn-sm me-2" type="button">
<button class="btn btn-normal btn-sm me-2" type="button" @click="">
{{ $t("createExternalNetwork") }}
</button>
</div>

View File

@ -19,6 +19,7 @@ export default {
computed: {
uptime() {
return "0.00%";
return this.$t("notAvailableShort");
},

View File

@ -68,13 +68,13 @@
</template>
<script>
import HiddenInput from "../../components/HiddenInput.vue";
import dayjs from "dayjs";
import { timezoneList } from "../../util-frontend";
export default {
components: {
HiddenInput,
},
data() {

View File

@ -118,7 +118,7 @@
</div>
</div>
<div class="col-lg-6">
<h4 class="mb-3">{{ stack.composeFileName }}</h4>
<h4 class="mb-3">compose.yaml</h4>
<!-- YAML editor -->
<div class="shadow-box mb-3 editor-box" :class="{'edit-mode' : isEditMode}">

View File

@ -10,7 +10,7 @@ import { POSITION } from "vue-toastification";
*
* Generated by Trelent
*/
function getTimezoneOffset(timeZone : string) {
function getTimezoneOffset(timeZone) {
const now = new Date();
const tzString = now.toLocaleString("en-US", {
timeZone,
@ -124,6 +124,33 @@ export function hostNameRegexPattern(mqtt = false) {
return `${ipRegexPattern}|${hostNameRegexPattern}`;
}
/**
* Get the tag color options
* Shared between components
* @param {any} self Component
* @returns {object[]} Colour options
*/
export function colorOptions(self) {
return [
{ name: self.$t("Gray"),
color: "#4B5563" },
{ name: self.$t("Red"),
color: "#DC2626" },
{ name: self.$t("Orange"),
color: "#D97706" },
{ name: self.$t("Green"),
color: "#059669" },
{ name: self.$t("Blue"),
color: "#2563EB" },
{ name: self.$t("Indigo"),
color: "#4F46E5" },
{ name: self.$t("Purple"),
color: "#7C3AED" },
{ name: self.$t("Pink"),
color: "#DB2777" },
];
}
/**
* Loads the toast timeout settings from storage.
* @returns {object} The toast plugin options object.

View File

@ -1,4 +1,3 @@
/* eslint-disable */
/// <reference types="vite/client" />
declare module "*.vue" {

View File

@ -1,11 +1,10 @@
{
"name": "dockge",
"version": "1.0.4",
"version": "1.0.3",
"type": "module",
"scripts": {
"fmt": "eslint \"**/*.{ts,vue}\" --fix",
"lint": "eslint \"**/*.{ts,vue}\"",
"check-ts": "tsc --noEmit",
"start": "tsx ./backend/index.ts",
"dev:backend": "cross-env NODE_ENV=development tsx watch ./backend/index.ts",
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
@ -18,7 +17,8 @@
"mark-as-nightly": "tsx ./extra/mark-as-nightly.ts"
},
"dependencies": {
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.11",
"@fontsource/jetbrains-mono": "^5.0.17",
"@homebridge/node-pty-prebuilt-multiarch": "~0.11.10",
"@louislam/sqlite3": "~15.1.6",
"bcryptjs": "~2.4.3",
"check-password-strength": "~2.0.7",
@ -34,8 +34,8 @@
"jwt-decode": "~3.1.2",
"knex": "~2.5.1",
"limiter-es6-compat": "~2.1.2",
"mysql2": "~3.6.3",
"redbean-node": "~0.3.3",
"mysql2": "^3.6.3",
"redbean-node": "0.3.2",
"socket.io": "~4.7.2",
"socket.io-client": "~4.7.2",
"timezones-list": "~3.0.2",
@ -45,19 +45,17 @@
"yaml": "~2.3.4"
},
"devDependencies": {
"@fontsource/jetbrains-mono": "^5.0.17",
"@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-regular-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/vue-fontawesome": "3.0.3",
"@types/bcryptjs": "^2.4.6",
"@types/bootstrap": "~5.2.9",
"@types/command-exists": "~1.2.3",
"@types/express": "~4.17.21",
"@types/jsonwebtoken": "~9.0.5",
"@typescript-eslint/eslint-plugin": "~6.8.0",
"@typescript-eslint/parser": "~6.8.0",
"@vitejs/plugin-vue": "~4.5.0",
"@vitejs/plugin-vue": "~4.3.4",
"bootstrap": "5.3.2",
"bootstrap-vue-next": "~0.14.10",
"cross-env": "~7.0.3",
@ -68,7 +66,7 @@
"sass": "~1.68.0",
"typescript": "~5.2.2",
"unplugin-vue-components": "~0.25.2",
"vite": "~5.0.0",
"vite": "~4.5.0",
"vite-plugin-compression": "~0.5.1",
"vue": "~3.3.8",
"vue-eslint-parser": "~9.3.2",

514
pnpm-lock.yaml generated
View File

@ -5,9 +5,12 @@ settings:
excludeLinksFromLockfile: false
dependencies:
'@fontsource/jetbrains-mono':
specifier: ^5.0.17
version: 5.0.17
'@homebridge/node-pty-prebuilt-multiarch':
specifier: ~0.11.11
version: 0.11.11
specifier: ~0.11.10
version: 0.11.10
'@louislam/sqlite3':
specifier: ~15.1.6
version: 15.1.6
@ -54,11 +57,11 @@ dependencies:
specifier: ~2.1.2
version: 2.1.2
mysql2:
specifier: ~3.6.3
specifier: ^3.6.3
version: 3.6.3
redbean-node:
specifier: ~0.3.3
version: 0.3.3(mysql2@3.6.3)
specifier: 0.3.2
version: 0.3.2(mysql2@3.6.3)
socket.io:
specifier: ~4.7.2
version: 4.7.2
@ -82,9 +85,6 @@ dependencies:
version: 2.3.4
devDependencies:
'@fontsource/jetbrains-mono':
specifier: ^5.0.17
version: 5.0.17
'@fortawesome/fontawesome-svg-core':
specifier: 6.4.2
version: 6.4.2
@ -97,9 +97,6 @@ devDependencies:
'@fortawesome/vue-fontawesome':
specifier: 3.0.3
version: 3.0.3(@fortawesome/fontawesome-svg-core@6.4.2)(vue@3.3.8)
'@types/bcryptjs':
specifier: ^2.4.6
version: 2.4.6
'@types/bootstrap':
specifier: ~5.2.9
version: 5.2.9
@ -119,8 +116,8 @@ devDependencies:
specifier: ~6.8.0
version: 6.8.0(eslint@8.50.0)(typescript@5.2.2)
'@vitejs/plugin-vue':
specifier: ~4.5.0
version: 4.5.0(vite@5.0.0)(vue@3.3.8)
specifier: ~4.3.4
version: 4.3.4(vite@4.5.0)(vue@3.3.8)
bootstrap:
specifier: 5.3.2
version: 5.3.2(@popperjs/core@2.11.8)
@ -152,11 +149,11 @@ devDependencies:
specifier: ~0.25.2
version: 0.25.2(vue@3.3.8)
vite:
specifier: ~5.0.0
version: 5.0.0(sass@1.68.0)
specifier: ~4.5.0
version: 4.5.0(sass@1.68.0)
vite-plugin-compression:
specifier: ~0.5.1
version: 0.5.1(vite@5.0.0)
version: 0.5.1(vite@4.5.0)
vue:
specifier: ~3.3.8
version: 3.3.8(typescript@5.2.2)
@ -238,16 +235,6 @@ packages:
cpu: [arm64]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/android-arm64@0.19.5:
resolution: {integrity: sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm@0.18.20:
@ -256,16 +243,6 @@ packages:
cpu: [arm]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/android-arm@0.19.5:
resolution: {integrity: sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64@0.18.20:
@ -274,16 +251,6 @@ packages:
cpu: [x64]
os: [android]
requiresBuild: true
dev: false
optional: true
/@esbuild/android-x64@0.19.5:
resolution: {integrity: sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64@0.18.20:
@ -292,16 +259,6 @@ packages:
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@esbuild/darwin-arm64@0.19.5:
resolution: {integrity: sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64@0.18.20:
@ -310,16 +267,6 @@ packages:
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: false
optional: true
/@esbuild/darwin-x64@0.19.5:
resolution: {integrity: sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64@0.18.20:
@ -328,16 +275,6 @@ packages:
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/freebsd-arm64@0.19.5:
resolution: {integrity: sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64@0.18.20:
@ -346,16 +283,6 @@ packages:
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/freebsd-x64@0.19.5:
resolution: {integrity: sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64@0.18.20:
@ -364,16 +291,6 @@ packages:
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-arm64@0.19.5:
resolution: {integrity: sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm@0.18.20:
@ -382,16 +299,6 @@ packages:
cpu: [arm]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-arm@0.19.5:
resolution: {integrity: sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32@0.18.20:
@ -400,16 +307,6 @@ packages:
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-ia32@0.19.5:
resolution: {integrity: sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64@0.18.20:
@ -418,16 +315,6 @@ packages:
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-loong64@0.19.5:
resolution: {integrity: sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el@0.18.20:
@ -436,16 +323,6 @@ packages:
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-mips64el@0.19.5:
resolution: {integrity: sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64@0.18.20:
@ -454,16 +331,6 @@ packages:
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-ppc64@0.19.5:
resolution: {integrity: sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64@0.18.20:
@ -472,16 +339,6 @@ packages:
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-riscv64@0.19.5:
resolution: {integrity: sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x@0.18.20:
@ -490,16 +347,6 @@ packages:
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-s390x@0.19.5:
resolution: {integrity: sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64@0.18.20:
@ -508,16 +355,6 @@ packages:
cpu: [x64]
os: [linux]
requiresBuild: true
dev: false
optional: true
/@esbuild/linux-x64@0.19.5:
resolution: {integrity: sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64@0.18.20:
@ -526,16 +363,6 @@ packages:
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/netbsd-x64@0.19.5:
resolution: {integrity: sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64@0.18.20:
@ -544,16 +371,6 @@ packages:
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: false
optional: true
/@esbuild/openbsd-x64@0.19.5:
resolution: {integrity: sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64@0.18.20:
@ -562,16 +379,6 @@ packages:
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: false
optional: true
/@esbuild/sunos-x64@0.19.5:
resolution: {integrity: sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64@0.18.20:
@ -580,16 +387,6 @@ packages:
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-arm64@0.19.5:
resolution: {integrity: sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32@0.18.20:
@ -598,16 +395,6 @@ packages:
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-ia32@0.19.5:
resolution: {integrity: sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64@0.18.20:
@ -616,16 +403,6 @@ packages:
cpu: [x64]
os: [win32]
requiresBuild: true
dev: false
optional: true
/@esbuild/win32-x64@0.19.5:
resolution: {integrity: sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@eslint-community/eslint-utils@4.4.0(eslint@8.50.0):
@ -651,7 +428,7 @@ packages:
debug: 4.3.4
espree: 9.6.1
globals: 13.23.0
ignore: 5.3.0
ignore: 5.2.4
import-fresh: 3.3.0
js-yaml: 4.1.0
minimatch: 3.1.2
@ -694,7 +471,7 @@ packages:
/@fontsource/jetbrains-mono@5.0.17:
resolution: {integrity: sha512-Y/EtdbwKwNQTGpnMrexX8SVW6Jqlh0nX2bNHI9Z9m6FsyjbocZIFNJqwSY9bDUoi7irGtz8nuidAN7FF8wYuJA==}
dev: true
dev: false
/@fortawesome/fontawesome-common-types@6.4.2:
resolution: {integrity: sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==}
@ -742,8 +519,8 @@ packages:
dev: false
optional: true
/@homebridge/node-pty-prebuilt-multiarch@0.11.11:
resolution: {integrity: sha512-g7XB2DxGXUuJV4ZS5+8BbztaeqKyihK1zowPL2EeLRp4wfew1qZ3Xw1FWYncpiuRbRvjXrEzXDkcTiYe/XC/ZA==}
/@homebridge/node-pty-prebuilt-multiarch@0.11.10:
resolution: {integrity: sha512-ttOE8QQRq/aRXDoKD2rfYEF50AiDLM9LPTohqCog1Z78g8k3Zqk15R/EHfTl/8cfw4l0fxt3y0dWL56wq79p2A==}
requiresBuild: true
dependencies:
nan: 2.18.0
@ -909,102 +686,6 @@ packages:
picomatch: 2.3.1
dev: true
/@rollup/rollup-android-arm-eabi@4.4.1:
resolution: {integrity: sha512-Ss4suS/sd+6xLRu+MLCkED2mUrAyqHmmvZB+zpzZ9Znn9S8wCkTQCJaQ8P8aHofnvG5L16u9MVnJjCqioPErwQ==}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-android-arm64@4.4.1:
resolution: {integrity: sha512-sRSkGTvGsARwWd7TzC8LKRf8FiPn7257vd/edzmvG4RIr9x68KBN0/Ek48CkuUJ5Pj/Dp9vKWv6PEupjKWjTYA==}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-darwin-arm64@4.4.1:
resolution: {integrity: sha512-nz0AiGrrXyaWpsmBXUGOBiRDU0wyfSXbFuF98pPvIO8O6auQsPG6riWsfQqmCCC5FNd8zKQ4JhgugRNAkBJ8mQ==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-darwin-x64@4.4.1:
resolution: {integrity: sha512-Ogqvf4/Ve/faMaiPRvzsJEqajbqs00LO+8vtrPBVvLgdw4wBg6ZDXdkDAZO+4MLnrc8mhGV6VJAzYScZdPLtJg==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm-gnueabihf@4.4.1:
resolution: {integrity: sha512-9zc2tqlr6HfO+hx9+wktUlWTRdje7Ub15iJqKcqg5uJZ+iKqmd2CMxlgPpXi7+bU7bjfDIuvCvnGk7wewFEhCg==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm64-gnu@4.4.1:
resolution: {integrity: sha512-phLb1fN3rq2o1j1v+nKxXUTSJnAhzhU0hLrl7Qzb0fLpwkGMHDem+o6d+ZI8+/BlTXfMU4kVWGvy6g9k/B8L6Q==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm64-musl@4.4.1:
resolution: {integrity: sha512-M2sDtw4tf57VPSjbTAN/lz1doWUqO2CbQuX3L9K6GWIR5uw9j+ROKCvvUNBY8WUbMxwaoc8mH9HmmBKsLht7+w==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-x64-gnu@4.4.1:
resolution: {integrity: sha512-mHIlRLX+hx+30cD6c4BaBOsSqdnCE4ok7/KDvjHYAHoSuveoMMxIisZFvcLhUnyZcPBXDGZTuBoalcuh43UfQQ==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-x64-musl@4.4.1:
resolution: {integrity: sha512-tB+RZuDi3zxFx7vDrjTNGVLu2KNyzYv+UY8jz7e4TMEoAj7iEt8Qk6xVu6mo3pgjnsHj6jnq3uuRsHp97DLwOA==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-arm64-msvc@4.4.1:
resolution: {integrity: sha512-Hdn39PzOQowK/HZzYpCuZdJC91PE6EaGbTe2VCA9oq2u18evkisQfws0Smh9QQGNNRa/T7MOuGNQoLeXhhE3PQ==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-ia32-msvc@4.4.1:
resolution: {integrity: sha512-tLpKb1Elm9fM8c5w3nl4N1eLTP4bCqTYw9tqUBxX8/hsxqHO3dxc2qPbZ9PNkdK4tg4iLEYn0pOUnVByRd2CbA==}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-x64-msvc@4.4.1:
resolution: {integrity: sha512-eAhItDX9yQtZVM3yvXS/VR3qPqcnXvnLyx1pLXl4JzyNMBNO3KC986t/iAg2zcMzpAp9JSvxB5VZGnBiNoA98w==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@socket.io/component-emitter@3.1.0:
resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==}
dev: false
@ -1016,15 +697,11 @@ packages:
dev: false
optional: true
/@types/bcryptjs@2.4.6:
resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
dev: true
/@types/body-parser@1.19.5:
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
dependencies:
'@types/connect': 3.4.38
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: true
/@types/bootstrap@5.2.9:
@ -1040,7 +717,7 @@ packages:
/@types/connect@3.4.38:
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
dependencies:
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: true
/@types/cookie@0.4.1:
@ -1050,7 +727,7 @@ packages:
/@types/cors@2.8.16:
resolution: {integrity: sha512-Trx5or1Nyg1Fq138PCuWqoApzvoSLWzZ25ORBiHMbbUT42g578lH1GT4TwYDbiUOLFuDsCkfLneT2105fsFWGg==}
dependencies:
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: false
/@types/estree@1.0.5:
@ -1060,7 +737,7 @@ packages:
/@types/express-serve-static-core@4.17.41:
resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==}
dependencies:
'@types/node': 20.9.1
'@types/node': 20.9.0
'@types/qs': 6.9.10
'@types/range-parser': 1.2.7
'@types/send': 0.17.4
@ -1086,7 +763,7 @@ packages:
/@types/jsonwebtoken@9.0.5:
resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==}
dependencies:
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: true
/@types/mime@1.3.5:
@ -1101,8 +778,8 @@ packages:
resolution: {integrity: sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==}
dev: false
/@types/node@20.9.1:
resolution: {integrity: sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==}
/@types/node@20.9.0:
resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==}
dependencies:
undici-types: 5.26.5
@ -1122,7 +799,7 @@ packages:
resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
dependencies:
'@types/mime': 1.3.5
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: true
/@types/serve-static@1.15.5:
@ -1130,7 +807,7 @@ packages:
dependencies:
'@types/http-errors': 2.0.4
'@types/mime': 3.0.4
'@types/node': 20.9.1
'@types/node': 20.9.0
dev: true
/@types/web-bluetooth@0.0.20:
@ -1157,7 +834,7 @@ packages:
debug: 4.3.4
eslint: 8.50.0
graphemer: 1.4.0
ignore: 5.3.0
ignore: 5.2.4
natural-compare: 1.4.0
semver: 7.5.4
ts-api-utils: 1.0.3(typescript@5.2.2)
@ -1268,14 +945,14 @@ packages:
eslint-visitor-keys: 3.4.3
dev: true
/@vitejs/plugin-vue@4.5.0(vite@5.0.0)(vue@3.3.8):
resolution: {integrity: sha512-a2WSpP8X8HTEww/U00bU4mX1QpLINNuz/2KMNpLsdu3BzOpak3AGI1CJYBTXcc4SPhaD0eNRUp7IyQK405L5dQ==}
/@vitejs/plugin-vue@4.3.4(vite@4.5.0)(vue@3.3.8):
resolution: {integrity: sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.0.0 || ^5.0.0
vite: ^4.0.0
vue: ^3.2.25
dependencies:
vite: 5.0.0(sass@1.68.0)
vite: 4.5.0(sass@1.68.0)
vue: 3.3.8(typescript@5.2.2)
dev: true
@ -1366,24 +1043,24 @@ packages:
resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==}
dev: true
/@vueuse/core@10.6.1(vue@3.3.8):
resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==}
/@vueuse/core@10.6.0(vue@3.3.8):
resolution: {integrity: sha512-+Yee+g9+9BEbvkyGdn4Bf4yZx9EfocAytpV2ZlrlP7xcz+qznLmZIDqDroTvc5vtMkWZicisgEv8dt3+jL+HQg==}
dependencies:
'@types/web-bluetooth': 0.0.20
'@vueuse/metadata': 10.6.1
'@vueuse/shared': 10.6.1(vue@3.3.8)
'@vueuse/metadata': 10.6.0
'@vueuse/shared': 10.6.0(vue@3.3.8)
vue-demi: 0.14.6(vue@3.3.8)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: true
/@vueuse/metadata@10.6.1:
resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==}
/@vueuse/metadata@10.6.0:
resolution: {integrity: sha512-mzKHkHoiK6xVz01VzQjM2l6ofUanEaofgEGPgDHcAzlvOTccPRTIdEuzneOUTYxgfm1vkDikS6rtrEw/NYlaTQ==}
dev: true
/@vueuse/shared@10.6.1(vue@3.3.8):
resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==}
/@vueuse/shared@10.6.0(vue@3.3.8):
resolution: {integrity: sha512-0t4MVE18sO+/4Gh0jfeOXBTjKeV4606N9kIrDOLPjFl8Rwnlodn+QC5A4LfJuysK7aOsTMjF3KnzNeueaI0xlQ==}
dependencies:
vue-demi: 0.14.6(vue@3.3.8)
transitivePeerDependencies:
@ -1539,7 +1216,7 @@ packages:
dev: false
/array-flatten@1.1.1:
resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=}
resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
dev: false
/array-union@2.1.0:
@ -1610,7 +1287,7 @@ packages:
vue: ^3.3.4
dependencies:
'@floating-ui/vue': 1.0.2(vue@3.3.8)
'@vueuse/core': 10.6.1(vue@3.3.8)
'@vueuse/core': 10.6.0(vue@3.3.8)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
@ -1643,7 +1320,7 @@ packages:
dev: true
/buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=}
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
dev: false
/buffer-from@1.1.2:
@ -1854,7 +1531,7 @@ packages:
dev: false
/concat-map@0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
@ -1873,7 +1550,7 @@ packages:
dev: false
/cookie-signature@1.0.6:
resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
dev: false
/cookie@0.4.2:
@ -2044,7 +1721,7 @@ packages:
dev: false
/ee-first@1.1.1:
resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: false
/emoji-regex@8.0.0:
@ -2103,7 +1780,7 @@ packages:
dependencies:
'@types/cookie': 0.4.1
'@types/cors': 2.8.16
'@types/node': 20.9.1
'@types/node': 20.9.0
accepts: 1.3.8
base64id: 2.0.0
cookie: 0.4.2
@ -2158,37 +1835,6 @@ packages:
'@esbuild/win32-arm64': 0.18.20
'@esbuild/win32-ia32': 0.18.20
'@esbuild/win32-x64': 0.18.20
dev: false
/esbuild@0.19.5:
resolution: {integrity: sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.19.5
'@esbuild/android-arm64': 0.19.5
'@esbuild/android-x64': 0.19.5
'@esbuild/darwin-arm64': 0.19.5
'@esbuild/darwin-x64': 0.19.5
'@esbuild/freebsd-arm64': 0.19.5
'@esbuild/freebsd-x64': 0.19.5
'@esbuild/linux-arm': 0.19.5
'@esbuild/linux-arm64': 0.19.5
'@esbuild/linux-ia32': 0.19.5
'@esbuild/linux-loong64': 0.19.5
'@esbuild/linux-mips64el': 0.19.5
'@esbuild/linux-ppc64': 0.19.5
'@esbuild/linux-riscv64': 0.19.5
'@esbuild/linux-s390x': 0.19.5
'@esbuild/linux-x64': 0.19.5
'@esbuild/netbsd-x64': 0.19.5
'@esbuild/openbsd-x64': 0.19.5
'@esbuild/sunos-x64': 0.19.5
'@esbuild/win32-arm64': 0.19.5
'@esbuild/win32-ia32': 0.19.5
'@esbuild/win32-x64': 0.19.5
dev: true
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
@ -2289,7 +1935,7 @@ packages:
glob-parent: 6.0.2
globals: 13.23.0
graphemer: 1.4.0
ignore: 5.3.0
ignore: 5.2.4
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
@ -2513,7 +2159,7 @@ packages:
dev: false
/fresh@0.5.2:
resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
dev: false
@ -2672,7 +2318,7 @@ packages:
array-union: 2.1.0
dir-glob: 3.0.1
fast-glob: 3.3.2
ignore: 5.3.0
ignore: 5.2.4
merge2: 1.4.1
slash: 3.0.0
dev: true
@ -2801,8 +2447,8 @@ packages:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
/ignore@5.3.0:
resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==}
/ignore@5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'}
dev: true
@ -3264,12 +2910,12 @@ packages:
optional: true
/media-typer@0.3.0:
resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
dev: false
/merge-descriptors@1.0.1:
resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
dev: false
/merge2@1.4.1:
@ -3667,7 +3313,7 @@ packages:
dev: false
/path-to-regexp@0.1.7:
resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=}
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
dev: false
/path-type@4.0.0:
@ -3854,8 +3500,8 @@ packages:
resolve: 1.22.8
dev: false
/redbean-node@0.3.3(mysql2@3.6.3):
resolution: {integrity: sha512-0J59/QlShdWs1h0lsFHRfb8NwjvgIYTQKwYrvq6FykRmeX1cG2u8AgHEIRVBrm56mtKLRASVy/8ykk6fSntLdw==}
/redbean-node@0.3.2(mysql2@3.6.3):
resolution: {integrity: sha512-39VMxPWPpPicRlU4FSJJnJuUMoxw5/4envFthHtKnLe+3qWTBje3RMrJTFZcQGLruWQ/s2LgeYzdd+d0O+p+uQ==}
dependencies:
'@types/node': 20.3.3
await-lock: 2.2.2
@ -3928,23 +3574,11 @@ packages:
dependencies:
glob: 7.2.3
/rollup@4.4.1:
resolution: {integrity: sha512-idZzrUpWSblPJX66i+GzrpjKE3vbYrlWirUHteoAbjKReZwa0cohAErOYA5efoMmNCdvG9yrJS+w9Kl6csaH4w==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
/rollup@3.29.4:
resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.4.1
'@rollup/rollup-android-arm64': 4.4.1
'@rollup/rollup-darwin-arm64': 4.4.1
'@rollup/rollup-darwin-x64': 4.4.1
'@rollup/rollup-linux-arm-gnueabihf': 4.4.1
'@rollup/rollup-linux-arm64-gnu': 4.4.1
'@rollup/rollup-linux-arm64-musl': 4.4.1
'@rollup/rollup-linux-x64-gnu': 4.4.1
'@rollup/rollup-linux-x64-musl': 4.4.1
'@rollup/rollup-win32-arm64-msvc': 4.4.1
'@rollup/rollup-win32-ia32-msvc': 4.4.1
'@rollup/rollup-win32-x64-msvc': 4.4.1
fsevents: 2.3.3
dev: true
@ -4500,20 +4134,20 @@ packages:
magic-string: 0.30.5
minimatch: 9.0.3
resolve: 1.22.8
unplugin: 1.5.1
unplugin: 1.5.0
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- rollup
- supports-color
dev: true
/unplugin@1.5.1:
resolution: {integrity: sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==}
/unplugin@1.5.0:
resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
dependencies:
acorn: 8.11.2
chokidar: 3.5.3
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.0
webpack-virtual-modules: 0.5.0
dev: true
/uri-js@4.4.1:
@ -4526,7 +4160,7 @@ packages:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
/utils-merge@1.0.1:
resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=}
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
engines: {node: '>= 0.4.0'}
dev: false
@ -4535,7 +4169,7 @@ packages:
engines: {node: '>= 0.8'}
dev: false
/vite-plugin-compression@0.5.1(vite@5.0.0):
/vite-plugin-compression@0.5.1(vite@4.5.0):
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
peerDependencies:
vite: '>=2.0.0'
@ -4543,17 +4177,17 @@ packages:
chalk: 4.1.2
debug: 4.3.4
fs-extra: 10.1.0
vite: 5.0.0(sass@1.68.0)
vite: 4.5.0(sass@1.68.0)
transitivePeerDependencies:
- supports-color
dev: true
/vite@5.0.0(sass@1.68.0):
resolution: {integrity: sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==}
engines: {node: ^18.0.0 || >=20.0.0}
/vite@4.5.0(sass@1.68.0):
resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': ^18.0.0 || >=20.0.0
'@types/node': '>= 14'
less: '*'
lightningcss: ^1.21.0
sass: '*'
@ -4576,9 +4210,9 @@ packages:
terser:
optional: true
dependencies:
esbuild: 0.19.5
esbuild: 0.18.20
postcss: 8.4.31
rollup: 4.4.1
rollup: 3.29.4
sass: 1.68.0
optionalDependencies:
fsevents: 2.3.3
@ -4691,8 +4325,8 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/webpack-virtual-modules@0.6.0:
resolution: {integrity: sha512-KnaMTE6EItz/f2q4Gwg5/rmeKVi79OR58NoYnwDJqCk9ywMtTGbBnBcfoBtN4QbYu0lWXvyMoH2Owxuhe4qI6Q==}
/webpack-virtual-modules@0.5.0:
resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
dev: true
/whatwg-url@5.0.0:

View File

@ -3,10 +3,6 @@
"module": "ESNext",
"target": "ESNext",
"strict": true,
"moduleResolution": "bundler",
"skipLibCheck": true
},
"include": [
"backend/**/*"
],
"moduleResolution": "bundler"
}
}