Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bec5460395 |
18 changed files with 97 additions and 556 deletions
|
@ -131,7 +131,7 @@ Be sure to read the [guide](https://github.com/louislam/dockge/blob/master/CONTR
|
|||
|
||||
#### "Dockge"?
|
||||
|
||||
"Dockge" is a coinage word which is created by myself. I hope it sounds like `Dodge`.
|
||||
"Dockge" is a coinage word which is created by myself. I originally hoped it sounds like `Dodge`, but apparently many people called it `Dockage`, it is also acceptable.
|
||||
|
||||
The naming idea came from Twitch emotes like `sadge`, `bedge` or `wokege`. They all end in `-ge`.
|
||||
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
import { DockgeSocket } from "./util-server";
|
||||
import { io, Socket as SocketClient } from "socket.io-client";
|
||||
import { log } from "./log";
|
||||
import { addEndpointToTerminalName, convertToRemoteStackID } from "./util-common";
|
||||
|
||||
/**
|
||||
* Dockge Instance Manager
|
||||
*/
|
||||
export class DockgeInstanceManager {
|
||||
|
||||
protected socket : DockgeSocket;
|
||||
protected instanceSocketList : Record<string, SocketClient> = {};
|
||||
|
||||
constructor(socket: DockgeSocket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
connect(endpoint : string, tls : boolean, username : string, password : string) {
|
||||
if (this.instanceSocketList[endpoint]) {
|
||||
log.debug("INSTANCEMANAGER", "Already connected to the socket server: " + endpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
let url = ((tls) ? "wss://" : "ws://") + endpoint;
|
||||
|
||||
log.info("INSTANCEMANAGER", "Connecting to the socket server: " + endpoint);
|
||||
let client = io(url, {
|
||||
transports: [ "websocket", "polling" ],
|
||||
});
|
||||
|
||||
client.on("connect", () => {
|
||||
log.info("INSTANCEMANAGER", "Connected to the socket server: " + endpoint);
|
||||
|
||||
client.emit("login", {
|
||||
username: username,
|
||||
password: password,
|
||||
}, (res) => {
|
||||
if (res.ok) {
|
||||
log.info("INSTANCEMANAGER", "Logged in to the socket server: " + endpoint);
|
||||
} else {
|
||||
log.error("INSTANCEMANAGER", "Failed to login to the socket server: " + endpoint);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
client.on("error", (err) => {
|
||||
log.error("INSTANCEMANAGER", "Error from the socket server: " + endpoint);
|
||||
log.error("INSTANCEMANAGER", err);
|
||||
});
|
||||
|
||||
client.on("disconnect", () => {
|
||||
log.info("INSTANCEMANAGER", "Disconnected from the socket server: " + endpoint);
|
||||
});
|
||||
|
||||
client.on("stackList", (res) => {
|
||||
if (res.endpoint) {
|
||||
log.debug("INSTANCEMANAGER", "Received stackList from endpoint, ignore: " + res.endpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
res.endpoint = endpoint;
|
||||
|
||||
let newStackList : Record<string, any> = {};
|
||||
|
||||
for (let stackName in res.stackList) {
|
||||
let stack = res.stackList[stackName];
|
||||
stack.endpoint = endpoint;
|
||||
stack.id = convertToRemoteStackID(stack.name, endpoint);
|
||||
newStackList[stack.name] = stack;
|
||||
}
|
||||
this.socket.emit("stackList", res);
|
||||
});
|
||||
|
||||
client.on("terminalWrite", (terminalName, data) => {
|
||||
this.socket.emit("terminalWrite", addEndpointToTerminalName(terminalName, endpoint), data);
|
||||
});
|
||||
|
||||
this.instanceSocketList[endpoint] = client;
|
||||
}
|
||||
|
||||
disconnect(endpoint : string) {
|
||||
let client = this.instanceSocketList[endpoint];
|
||||
client?.disconnect();
|
||||
}
|
||||
|
||||
connectAll() {
|
||||
let list : Record<string, {tls : boolean, username : string, password : string}> = {
|
||||
|
||||
};
|
||||
|
||||
if (process.env.DOCKGE_TEST_REMOTE_HOST) {
|
||||
list[process.env.DOCKGE_TEST_REMOTE_HOST] = {
|
||||
tls: false,
|
||||
username: "admin",
|
||||
password: process.env.DOCKGE_TEST_REMOTE_PW || "",
|
||||
};
|
||||
}
|
||||
|
||||
if (Object.keys(list).length !== 0) {
|
||||
log.info("INSTANCEMANAGER", "Connecting to all instance socket server(s)...");
|
||||
}
|
||||
|
||||
for (let endpoint in list) {
|
||||
let item = list[endpoint];
|
||||
this.connect(endpoint, item.tls, item.username, item.password);
|
||||
}
|
||||
}
|
||||
|
||||
disconnectAll() {
|
||||
for (let endpoint in this.instanceSocketList) {
|
||||
this.disconnect(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
emitToEndpoint(endpoint: string, eventName: string, ...args : unknown[]) {
|
||||
log.debug("INSTANCEMANAGER", "Emitting event to endpoint: " + endpoint);
|
||||
let client = this.instanceSocketList[endpoint];
|
||||
if (!client) {
|
||||
log.error("INSTANCEMANAGER", "Socket client not found for endpoint: " + endpoint);
|
||||
return;
|
||||
}
|
||||
client?.emit(eventName, ...args);
|
||||
}
|
||||
|
||||
}
|
|
@ -31,9 +31,6 @@ import gracefulShutdown from "http-graceful-shutdown";
|
|||
import User from "./models/user";
|
||||
import childProcessAsync from "promisify-child-process";
|
||||
import { Terminal } from "./terminal";
|
||||
import { DockgeInstanceManager } from "./dockge-instance-manager";
|
||||
|
||||
import "dotenv/config";
|
||||
|
||||
import "dotenv/config";
|
||||
|
||||
|
@ -74,7 +71,6 @@ export class DockgeServer {
|
|||
*
|
||||
*/
|
||||
constructor() {
|
||||
|
||||
// Catch unexpected errors here
|
||||
let unexpectedErrorHandler = (error : unknown) => {
|
||||
console.trace(error);
|
||||
|
@ -203,20 +199,16 @@ export class DockgeServer {
|
|||
this.io.on("connection", async (socket: Socket) => {
|
||||
log.info("server", "Socket connected!");
|
||||
|
||||
let dockgeSocket = socket as DockgeSocket;
|
||||
dockgeSocket.isAgentMode = false;
|
||||
dockgeSocket.instanceManager = new DockgeInstanceManager(dockgeSocket);
|
||||
|
||||
this.sendInfo(dockgeSocket, true);
|
||||
this.sendInfo(socket, true);
|
||||
|
||||
if (this.needSetup) {
|
||||
log.info("server", "Redirect to setup page");
|
||||
dockgeSocket.emit("setup");
|
||||
socket.emit("setup");
|
||||
}
|
||||
|
||||
// Create socket handlers
|
||||
for (const socketHandler of this.socketHandlerList) {
|
||||
socketHandler.create(dockgeSocket, this);
|
||||
socketHandler.create(socket as DockgeSocket, this);
|
||||
}
|
||||
|
||||
// ***************************
|
||||
|
@ -226,18 +218,12 @@ 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(dockgeSocket, await R.findOne("user") as User);
|
||||
dockgeSocket.emit("autoLogin");
|
||||
this.afterLogin(socket as DockgeSocket, await R.findOne("user") as User);
|
||||
socket.emit("autoLogin");
|
||||
} else {
|
||||
log.debug("auth", "need auth");
|
||||
}
|
||||
|
||||
// Socket disconnect
|
||||
dockgeSocket.on("disconnect", () => {
|
||||
log.info("server", "Socket disconnected!");
|
||||
dockgeSocket.instanceManager.disconnectAll();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this.io.on("disconnect", () => {
|
||||
|
@ -262,9 +248,6 @@ export class DockgeServer {
|
|||
} catch (e) {
|
||||
log.error("server", e);
|
||||
}
|
||||
|
||||
// Also connect to other dockge instances
|
||||
socket.instanceManager.connectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,22 +1,6 @@
|
|||
import { DockgeServer } from "./dockge-server";
|
||||
import { DockgeSocket } from "./util-server";
|
||||
import { log } from "./log";
|
||||
|
||||
export abstract class SocketHandler {
|
||||
abstract create(socket : DockgeSocket, server : DockgeServer): void;
|
||||
|
||||
event(eventName : string, socket : DockgeSocket, callback: (...args: any[]) => void) {
|
||||
socket.on(eventName, (...args) => {
|
||||
log.debug("SOCKET", "Received event: " + eventName);
|
||||
let req = args[0];
|
||||
if (req.endpoint) {
|
||||
let endpoint = req.endpoint;
|
||||
req.responseAsEndpoint = endpoint;
|
||||
req.endpoint = undefined;
|
||||
socket.instanceManager.emitToEndpoint(endpoint, eventName, ...args);
|
||||
} else {
|
||||
callback(...args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,6 @@ import { Stack } from "../stack";
|
|||
|
||||
// @ts-ignore
|
||||
import composerize from "composerize";
|
||||
import {
|
||||
convertToLocalStackName,
|
||||
convertToRemoteStackID,
|
||||
isRemoteStackName, isStackRequest,
|
||||
LooseObject,
|
||||
StackRequest
|
||||
} from "../util-common";
|
||||
|
||||
export class DockerSocketHandler extends SocketHandler {
|
||||
create(socket : DockgeSocket, server : DockgeServer) {
|
||||
|
@ -72,20 +65,15 @@ export class DockerSocketHandler extends SocketHandler {
|
|||
}
|
||||
});
|
||||
|
||||
this.event("getStack", socket, async (req : unknown, callback) => {
|
||||
console.log("here", req);
|
||||
socket.on("getStack", async (stackName : unknown, callback) => {
|
||||
try {
|
||||
checkLogin(socket);
|
||||
|
||||
if (!isStackRequest(req)) {
|
||||
throw new ValidationError("Invalid request");
|
||||
if (typeof(stackName) !== "string") {
|
||||
throw new ValidationError("Stack name must be a string");
|
||||
}
|
||||
|
||||
let stackName = req.stackName;
|
||||
let endpoint = req.responseAsEndpoint;
|
||||
const stack = await Stack.getStack(server, stackName, false, endpoint);
|
||||
|
||||
console.log(stack.toJSON());
|
||||
const stack = await Stack.getStack(server, stackName);
|
||||
|
||||
if (stack.isManagedByDockge) {
|
||||
stack.joinCombinedTerminal(socket);
|
||||
|
|
|
@ -260,6 +260,8 @@ export class MainSocketHandler extends SocketHandler {
|
|||
await doubleCheckPassword(socket, currentPassword);
|
||||
}
|
||||
|
||||
console.log(data);
|
||||
|
||||
await Settings.setSettings("general", data);
|
||||
|
||||
callback({
|
||||
|
|
|
@ -2,6 +2,16 @@ import { SocketHandler } from "../socket-handler.js";
|
|||
import { DockgeServer } from "../dockge-server";
|
||||
import { callbackError, checkLogin, DockgeSocket, ValidationError } from "../util-server";
|
||||
import { log } from "../log";
|
||||
import yaml from "yaml";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import {
|
||||
allowedCommandList,
|
||||
allowedRawKeys,
|
||||
getComposeTerminalName, getContainerExecTerminalName,
|
||||
isDev,
|
||||
PROGRESS_TERMINAL_ROWS
|
||||
} from "../util-common";
|
||||
import { InteractiveTerminal, MainTerminal, Terminal } from "../terminal";
|
||||
import { Stack } from "../stack";
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { DockgeSocket, fileExists, ValidationError } from "./util-server";
|
|||
import path from "path";
|
||||
import {
|
||||
COMBINED_TERMINAL_COLS,
|
||||
COMBINED_TERMINAL_ROWS, convertToRemoteStackID,
|
||||
COMBINED_TERMINAL_ROWS,
|
||||
CREATED_FILE,
|
||||
CREATED_STACK,
|
||||
EXITED, getCombinedTerminalName,
|
||||
|
@ -21,24 +21,22 @@ import childProcessAsync from "promisify-child-process";
|
|||
export class Stack {
|
||||
|
||||
name: string;
|
||||
|
||||
protected _status: number = UNKNOWN;
|
||||
protected _composeYAML?: string;
|
||||
protected _composeENV?: string;
|
||||
protected _configFilePath?: string;
|
||||
protected _composeFileName: string = "compose.yaml";
|
||||
protected server: DockgeServer;
|
||||
protected endpoint: string | undefined;
|
||||
|
||||
protected combinedTerminal? : Terminal;
|
||||
|
||||
protected static managedStackList: Map<string, Stack> = new Map();
|
||||
|
||||
constructor(server : DockgeServer, name : string, composeYAML? : string, composeENV? : string, skipFSOperations = false, endpoint : string | undefined = undefined) {
|
||||
constructor(server : DockgeServer, name : string, composeYAML? : string, composeENV? : string, skipFSOperations = false) {
|
||||
this.name = name;
|
||||
this.server = server;
|
||||
this._composeYAML = composeYAML;
|
||||
this._composeENV = composeENV;
|
||||
this.endpoint = endpoint;
|
||||
|
||||
if (!skipFSOperations) {
|
||||
// Check if compose file name is different from compose.yaml
|
||||
|
@ -52,14 +50,6 @@ export class Stack {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote stack ID
|
||||
* If endpoint is undefined, it will return the local stack ID
|
||||
*/
|
||||
getRemoteStackID() : string {
|
||||
return convertToRemoteStackID(this.name, this.endpoint);
|
||||
}
|
||||
|
||||
toJSON() : object {
|
||||
let obj = this.toSimpleJSON();
|
||||
return {
|
||||
|
@ -72,8 +62,6 @@ export class Stack {
|
|||
toSimpleJSON() : object {
|
||||
return {
|
||||
name: this.name,
|
||||
id: this.getRemoteStackID(),
|
||||
endpoint: undefined,
|
||||
status: this._status,
|
||||
tags: [],
|
||||
isManagedByDockge: this.isManagedByDockge,
|
||||
|
@ -342,12 +330,12 @@ export class Stack {
|
|||
}
|
||||
}
|
||||
|
||||
static async getStack(server: DockgeServer, stackName: string, skipFSOperations = false, endpoint : string | undefined = undefined) : Promise<Stack> {
|
||||
static async getStack(server: DockgeServer, stackName: string, skipFSOperations = false) : Promise<Stack> {
|
||||
let dir = path.join(server.stacksDir, stackName);
|
||||
|
||||
if (!skipFSOperations) {
|
||||
// Maybe it is a stack managed out of Dockge
|
||||
if (!await fileExists(dir) || !(await fsAsync.stat(dir)).isDirectory()) {
|
||||
// Maybe it is a stack managed by docker compose directly
|
||||
let stackList = await this.getStackList(server, true);
|
||||
let stack = stackList.get(stackName);
|
||||
|
||||
|
@ -358,14 +346,16 @@ export class Stack {
|
|||
throw new ValidationError("Stack not found");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//log.debug("getStack", "Skip FS operations");
|
||||
}
|
||||
|
||||
let stack : Stack;
|
||||
|
||||
if (!skipFSOperations) {
|
||||
stack = new Stack(server, stackName, undefined, undefined, false, endpoint);
|
||||
stack = new Stack(server, stackName);
|
||||
} else {
|
||||
stack = new Stack(server, stackName, undefined, undefined, true, endpoint);
|
||||
stack = new Stack(server, stackName, undefined, undefined, true);
|
||||
}
|
||||
|
||||
stack._status = UNKNOWN;
|
||||
|
|
|
@ -12,14 +12,9 @@ dayjs.extend(utc);
|
|||
dayjs.extend(timezone);
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
export interface StackRequest {
|
||||
stackName : string;
|
||||
endpoint? : string;
|
||||
responseAsEndpoint? : string;
|
||||
}
|
||||
|
||||
export function isStackRequest(obj : unknown) : obj is StackRequest {
|
||||
return (obj as StackRequest).stackName !== undefined;
|
||||
export interface LooseObject {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
let randomBytes : (numBytes: number) => Uint8Array;
|
||||
|
@ -195,34 +190,20 @@ export function getCryptoRandomInt(min: number, max: number):number {
|
|||
}
|
||||
}
|
||||
|
||||
export function getComposeTerminalName(stackID : string) {
|
||||
return "compose-" + stackID;
|
||||
export function getComposeTerminalName(stack : string) {
|
||||
return "compose-" + stack;
|
||||
}
|
||||
|
||||
export function getCombinedTerminalName(stackID : string) {
|
||||
return "combined-" + stackID;
|
||||
export function getCombinedTerminalName(stack : string) {
|
||||
return "combined-" + stack;
|
||||
}
|
||||
|
||||
export function getContainerTerminalName(container : string) {
|
||||
return "container-" + container;
|
||||
}
|
||||
|
||||
export function getContainerExecTerminalName(stackID : string, container : string, index : number) {
|
||||
return "containerExec-" + stackID + "-" + container + "-" + index;
|
||||
}
|
||||
|
||||
export function addEndpointToTerminalName(terminalName : string, endpoint : string) {
|
||||
if (
|
||||
terminalName.startsWith("compose-") ||
|
||||
terminalName.startsWith("combined-") ||
|
||||
terminalName.startsWith("containerExec-")
|
||||
) {
|
||||
let arr = terminalName.split("-");
|
||||
arr[1] = convertToRemoteStackID(arr[1], endpoint);
|
||||
return arr.join("-");
|
||||
} else {
|
||||
return terminalName;
|
||||
}
|
||||
export function getContainerExecTerminalName(stackName : string, container : string, index : number) {
|
||||
return "container-exec-" + stackName + "-" + container + "-" + index;
|
||||
}
|
||||
|
||||
export function copyYAMLComments(doc : Document, src : Document) {
|
||||
|
@ -359,43 +340,3 @@ export function parseDockerPort(input : string, defaultHostname : string = "loca
|
|||
display: display,
|
||||
};
|
||||
}
|
||||
|
||||
const remote = "remote";
|
||||
const splitChar : string = "::";
|
||||
|
||||
export function convertToRemoteStackID(stackName? : string, endpoint? : string) : string {
|
||||
if (!stackName) {
|
||||
return "";
|
||||
}
|
||||
if (!endpoint) {
|
||||
return stackName;
|
||||
}
|
||||
if (stackName.startsWith(remote + splitChar)) {
|
||||
return stackName;
|
||||
}
|
||||
return `${remote}${splitChar}${endpoint}${splitChar}${stackName}`;
|
||||
}
|
||||
|
||||
export function convertToLocalStackName(stackName? : string) {
|
||||
if (!stackName) {
|
||||
return {
|
||||
endpoint: undefined,
|
||||
stackName: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (!stackName.startsWith(remote + splitChar)) {
|
||||
return {
|
||||
endpoint: undefined,
|
||||
stackName,
|
||||
};
|
||||
}
|
||||
return {
|
||||
endpoint: stackName.split(splitChar)[1],
|
||||
stackName: stackName.split(splitChar).splice(2).join(splitChar)
|
||||
};
|
||||
}
|
||||
|
||||
export function isRemoteStackName(stackName : string) {
|
||||
return stackName.startsWith(remote + splitChar);
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { Socket } from "socket.io";
|
||||
import { Socket as SocketClient } from "socket.io-client";
|
||||
import { Terminal } from "./terminal";
|
||||
import { randomBytes } from "crypto";
|
||||
import { log } from "./log";
|
||||
import { ERROR_TYPE_VALIDATION } from "./util-common";
|
||||
import { R } from "redbean-node";
|
||||
import { verifyPassword } from "./password-hash";
|
||||
import fs from "fs";
|
||||
import { DockgeInstanceManager } from "./dockge-instance-manager";
|
||||
|
||||
export interface JWTDecoded {
|
||||
username : string;
|
||||
|
@ -16,8 +15,6 @@ export interface JWTDecoded {
|
|||
export interface DockgeSocket extends Socket {
|
||||
userID: number;
|
||||
consoleTerminal? : Terminal;
|
||||
instanceManager : DockgeInstanceManager;
|
||||
isAgentMode : boolean;
|
||||
}
|
||||
|
||||
// For command line arguments, so they are nullable
|
||||
|
|
|
@ -120,7 +120,7 @@ export default {
|
|||
* @returns {Array} The sorted list of stacks.
|
||||
*/
|
||||
sortedStackList() {
|
||||
let result = Object.values(this.$root.completeStackList);
|
||||
let result = Object.values(this.$root.stackList);
|
||||
|
||||
result = result.filter(stack => {
|
||||
// filter by search text
|
||||
|
@ -160,7 +160,6 @@ export default {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// sort by status
|
||||
if (m1.status !== m2.status) {
|
||||
if (m2.status === RUNNING) {
|
||||
return 1;
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
<template>
|
||||
<router-link :to="url" :class="{ 'dim' : !stack.isManagedByDockge }" class="item">
|
||||
<router-link :to="`/compose/${stack.name}`" :class="{ 'dim' : !stack.isManagedByDockge }" class="item">
|
||||
<Uptime :stack="stack" :fixed-width="true" class="me-2" />
|
||||
<div class="title">
|
||||
<span>{{ stackName }}</span>
|
||||
<div v-if="stack.endpoint" class="endpoint">{{ stack.endpoint }}</div>
|
||||
</div>
|
||||
<span class="title">{{ stackName }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import Uptime from "./Uptime.vue";
|
||||
import { convertToLocalStackName } from "../../../backend/util-common";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -55,16 +51,13 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
url() {
|
||||
return `/compose/${this.stack.id}`;
|
||||
},
|
||||
depthMargin() {
|
||||
return {
|
||||
marginLeft: `${31 * this.depth}px`,
|
||||
};
|
||||
},
|
||||
stackName() {
|
||||
return convertToLocalStackName(this.stack.name).stackName;
|
||||
return this.stack.name;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -124,36 +117,16 @@ export default {
|
|||
padding-right: 2px !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
text-decoration: none;
|
||||
// .stack-item {
|
||||
// width: 100%;
|
||||
// }
|
||||
|
||||
.tags {
|
||||
margin-top: 4px;
|
||||
padding-left: 67px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 52px;
|
||||
border-radius: 10px;
|
||||
transition: all ease-in-out 0.15s;
|
||||
width: 100%;
|
||||
padding: 5px 8px;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $highlight-white;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #cdf8f4;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
font-size: 12px;
|
||||
color: $dark-font-color3;
|
||||
}
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.collapsed {
|
||||
|
|
|
@ -28,24 +28,11 @@ export default defineComponent({
|
|||
loggedIn: false,
|
||||
allowLoginDialog: false,
|
||||
username: null,
|
||||
instanceList: {} as Record<string, any>,
|
||||
stackList: {},
|
||||
composeTemplate: "",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
||||
completeStackList() {
|
||||
let list : Record<string, any> = this.stackList;
|
||||
for (let endpoint in this.instanceList) {
|
||||
let instance = this.instanceList[endpoint];
|
||||
for (let stackName in instance.stackList) {
|
||||
list[stackName + "_" + endpoint] = instance.stackList[stackName];
|
||||
}
|
||||
}
|
||||
return list;
|
||||
},
|
||||
|
||||
usernameFirstChar() {
|
||||
if (typeof this.username == "string" && this.username.length >= 1) {
|
||||
return this.username.charAt(0).toUpperCase();
|
||||
|
@ -94,6 +81,7 @@ export default defineComponent({
|
|||
},
|
||||
mounted() {
|
||||
return;
|
||||
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
|
@ -200,23 +188,7 @@ export default defineComponent({
|
|||
|
||||
socket.on("stackList", (res) => {
|
||||
if (res.ok) {
|
||||
if (!res.endpoint) {
|
||||
this.stackList = res.stackList;
|
||||
} else {
|
||||
if (!this.instanceList[res.endpoint]) {
|
||||
this.instanceList[res.endpoint] = {
|
||||
stackList: {},
|
||||
};
|
||||
}
|
||||
|
||||
// Set endpoint for each stack
|
||||
for (let stackName in res.stackList) {
|
||||
const stackObj = res.stackList[stackName];
|
||||
stackObj.endpoint = res.endpoint;
|
||||
}
|
||||
|
||||
this.instanceList[res.endpoint].stackList = res.stackList;
|
||||
}
|
||||
this.stackList = res.stackList;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ import "vue-prism-editor/dist/prismeditor.min.css";
|
|||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import {
|
||||
COMBINED_TERMINAL_COLS,
|
||||
COMBINED_TERMINAL_ROWS, convertToLocalStackName,
|
||||
COMBINED_TERMINAL_ROWS,
|
||||
copyYAMLComments,
|
||||
getCombinedTerminalName,
|
||||
getComposeTerminalName,
|
||||
|
@ -344,17 +344,17 @@ export default {
|
|||
},
|
||||
|
||||
terminalName() {
|
||||
if (!this.stack.id) {
|
||||
if (!this.stack.name) {
|
||||
return "";
|
||||
}
|
||||
return getComposeTerminalName(this.stack.id);
|
||||
return getComposeTerminalName(this.stack.name);
|
||||
},
|
||||
|
||||
combinedTerminalName() {
|
||||
if (!this.stack.id) {
|
||||
if (!this.stack.name) {
|
||||
return "";
|
||||
}
|
||||
return getCombinedTerminalName(this.stack.id);
|
||||
return getCombinedTerminalName(this.stack.name);
|
||||
},
|
||||
|
||||
networks() {
|
||||
|
@ -393,7 +393,7 @@ export default {
|
|||
|
||||
$route(to, from) {
|
||||
// Leave Combined Terminal
|
||||
console.debug("leaveCombinedTerminal", from.params.stackID);
|
||||
console.debug("leaveCombinedTerminal", from.params.stackName);
|
||||
this.$root.getSocket().emit("leaveCombinedTerminal", this.stack.name, () => {});
|
||||
}
|
||||
},
|
||||
|
@ -429,10 +429,7 @@ export default {
|
|||
this.yamlCodeChange();
|
||||
|
||||
} else {
|
||||
this.stack.id = this.$route.params.stackID;
|
||||
let { endpoint, stackName } = convertToLocalStackName(this.stack.id);
|
||||
this.stack.name = stackName;
|
||||
this.stack.endpoint = endpoint;
|
||||
this.stack.name = this.$route.params.stackName;
|
||||
this.loadStack();
|
||||
}
|
||||
|
||||
|
@ -480,11 +477,7 @@ export default {
|
|||
|
||||
loadStack() {
|
||||
this.processing = true;
|
||||
|
||||
this.$root.getSocket().emit("getStack", {
|
||||
stackName: this.stack.name,
|
||||
endpoint: this.stack.endpoint,
|
||||
}, (res) => {
|
||||
this.$root.getSocket().emit("getStack", this.stack.name, (res) => {
|
||||
if (res.ok) {
|
||||
this.stack = res.stack;
|
||||
this.yamlCodeChange();
|
||||
|
|
|
@ -35,9 +35,10 @@ const routes = [
|
|||
component: Compose,
|
||||
},
|
||||
{
|
||||
path: "/compose/:stackID",
|
||||
path: "/compose/:stackName",
|
||||
name: "compose",
|
||||
component: Compose,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "/terminal/:stackName/:serviceName/:type",
|
||||
|
|
|
@ -490,7 +490,33 @@ optgroup {
|
|||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 52px;
|
||||
text-decoration: none;
|
||||
border-radius: 10px;
|
||||
transition: all ease-in-out 0.15s;
|
||||
width: 100%;
|
||||
padding: 0 8px;
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $highlight-white;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #cdf8f4;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
margin-top: -4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
"lint": "eslint \"**/*.{ts,vue}\"",
|
||||
"check-ts": "tsc --noEmit",
|
||||
"start": "tsx ./backend/index.ts",
|
||||
"dev": "concurrently -k -r \"wait-on tcp:5000 && pnpm run dev:backend \" \"pnpm run dev:frontend\"",
|
||||
"dev:backend": "cross-env NODE_ENV=development tsx watch --inspect ./backend/index.ts",
|
||||
"dev:frontend": "cross-env NODE_ENV=development vite --host --config ./frontend/vite.config.ts",
|
||||
"release-final": "tsx ./extra/test-docker.ts && tsx extra/update-version.ts && pnpm run build:frontend && npm run build:docker",
|
||||
|
@ -70,7 +69,6 @@
|
|||
"@vitejs/plugin-vue": "~4.5.0",
|
||||
"bootstrap": "5.3.2",
|
||||
"bootstrap-vue-next": "~0.14.10",
|
||||
"concurrently": "^8.2.2",
|
||||
"cross-env": "~7.0.3",
|
||||
"eslint": "~8.50.0",
|
||||
"eslint-plugin-jsdoc": "~46.8.2",
|
||||
|
@ -88,7 +86,6 @@
|
|||
"vue-qrcode": "~2.2.0",
|
||||
"vue-router": "~4.2.5",
|
||||
"vue-toastification": "2.0.0-rc.5",
|
||||
"wait-on": "^7.2.0",
|
||||
"xterm": "5.4.0-beta.37",
|
||||
"xterm-addon-web-links": "~0.9.0"
|
||||
}
|
||||
|
|
200
pnpm-lock.yaml
generated
200
pnpm-lock.yaml
generated
|
@ -136,9 +136,6 @@ devDependencies:
|
|||
bootstrap-vue-next:
|
||||
specifier: ~0.14.10
|
||||
version: 0.14.10(vue@3.3.8)
|
||||
concurrently:
|
||||
specifier: ^8.2.2
|
||||
version: 8.2.2
|
||||
cross-env:
|
||||
specifier: ~7.0.3
|
||||
version: 7.0.3
|
||||
|
@ -190,9 +187,6 @@ devDependencies:
|
|||
vue-toastification:
|
||||
specifier: 2.0.0-rc.5
|
||||
version: 2.0.0-rc.5(vue@3.3.8)
|
||||
wait-on:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
xterm:
|
||||
specifier: 5.4.0-beta.37
|
||||
version: 5.4.0-beta.37
|
||||
|
@ -245,13 +239,6 @@ packages:
|
|||
'@babel/types': 7.23.3
|
||||
dev: true
|
||||
|
||||
/@babel/runtime@7.23.5:
|
||||
resolution: {integrity: sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.0
|
||||
dev: true
|
||||
|
||||
/@babel/types@7.23.3:
|
||||
resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
@ -785,16 +772,6 @@ packages:
|
|||
dev: false
|
||||
optional: true
|
||||
|
||||
/@hapi/hoek@9.3.0:
|
||||
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
|
||||
dev: true
|
||||
|
||||
/@hapi/topo@5.1.0:
|
||||
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
dev: true
|
||||
|
||||
/@homebridge/node-pty-prebuilt-multiarch@0.11.11:
|
||||
resolution: {integrity: sha512-g7XB2DxGXUuJV4ZS5+8BbztaeqKyihK1zowPL2EeLRp4wfew1qZ3Xw1FWYncpiuRbRvjXrEzXDkcTiYe/XC/ZA==}
|
||||
requiresBuild: true
|
||||
|
@ -1144,20 +1121,6 @@ packages:
|
|||
dev: true
|
||||
optional: true
|
||||
|
||||
/@sideway/address@4.1.4:
|
||||
resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
dev: true
|
||||
|
||||
/@sideway/formula@3.0.1:
|
||||
resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==}
|
||||
dev: true
|
||||
|
||||
/@sideway/pinpoint@2.0.0:
|
||||
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
|
||||
dev: true
|
||||
|
||||
/@socket.io/component-emitter@3.1.0:
|
||||
resolution: {integrity: sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==}
|
||||
dev: false
|
||||
|
@ -1700,24 +1663,10 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: true
|
||||
|
||||
/await-lock@2.2.2:
|
||||
resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==}
|
||||
dev: false
|
||||
|
||||
/axios@1.6.2:
|
||||
resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.3
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
|
@ -1942,15 +1891,6 @@ packages:
|
|||
wrap-ansi: 6.2.0
|
||||
dev: true
|
||||
|
||||
/cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
dev: true
|
||||
|
||||
/color-convert@1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
dependencies:
|
||||
|
@ -1979,13 +1919,6 @@ packages:
|
|||
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
|
||||
dev: false
|
||||
|
||||
/combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: true
|
||||
|
||||
/command-exists@1.2.9:
|
||||
resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==}
|
||||
dev: false
|
||||
|
@ -2043,22 +1976,6 @@ packages:
|
|||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
|
||||
|
||||
/concurrently@8.2.2:
|
||||
resolution: {integrity: sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==}
|
||||
engines: {node: ^14.13.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
date-fns: 2.30.0
|
||||
lodash: 4.17.21
|
||||
rxjs: 7.8.1
|
||||
shell-quote: 1.8.1
|
||||
spawn-command: 0.0.2
|
||||
supports-color: 8.1.1
|
||||
tree-kill: 1.2.2
|
||||
yargs: 17.7.2
|
||||
dev: true
|
||||
|
||||
/console-control-strings@1.1.0:
|
||||
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
|
||||
dev: false
|
||||
|
@ -2134,13 +2051,6 @@ packages:
|
|||
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
|
||||
dev: true
|
||||
|
||||
/date-fns@2.30.0:
|
||||
resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
|
||||
engines: {node: '>=0.11'}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.5
|
||||
dev: true
|
||||
|
||||
/dayjs@1.11.10:
|
||||
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||
dev: false
|
||||
|
@ -2201,11 +2111,6 @@ packages:
|
|||
has-property-descriptors: 1.0.1
|
||||
dev: false
|
||||
|
||||
/delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: true
|
||||
|
||||
/delegates@1.0.0:
|
||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||
dev: false
|
||||
|
@ -2417,6 +2322,7 @@ packages:
|
|||
/escalade@3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
|
@ -2722,16 +2628,6 @@ packages:
|
|||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
||||
dev: true
|
||||
|
||||
/follow-redirects@1.15.3:
|
||||
resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: true
|
||||
|
||||
/foreground-child@3.1.1:
|
||||
resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
|
||||
engines: {node: '>=14'}
|
||||
|
@ -2740,15 +2636,6 @@ packages:
|
|||
signal-exit: 4.1.0
|
||||
dev: false
|
||||
|
||||
/form-data@4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: true
|
||||
|
||||
/forwarded@0.2.0:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
@ -3188,16 +3075,6 @@ packages:
|
|||
'@pkgjs/parseargs': 0.11.0
|
||||
dev: false
|
||||
|
||||
/joi@17.11.0:
|
||||
resolution: {integrity: sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==}
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
'@hapi/topo': 5.1.0
|
||||
'@sideway/address': 4.1.4
|
||||
'@sideway/formula': 3.0.1
|
||||
'@sideway/pinpoint': 2.0.0
|
||||
dev: true
|
||||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: false
|
||||
|
@ -3550,12 +3427,14 @@ packages:
|
|||
/mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
dev: false
|
||||
|
||||
/mime@1.6.0:
|
||||
resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
|
||||
|
@ -3581,6 +3460,7 @@ packages:
|
|||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
dev: false
|
||||
|
||||
/minipass-collect@1.0.2:
|
||||
resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
|
||||
|
@ -4031,10 +3911,6 @@ packages:
|
|||
ipaddr.js: 1.9.1
|
||||
dev: false
|
||||
|
||||
/proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: true
|
||||
|
||||
/pump@3.0.0:
|
||||
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
|
||||
dependencies:
|
||||
|
@ -4142,10 +4018,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/regenerator-runtime@0.14.0:
|
||||
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
|
||||
dev: true
|
||||
|
||||
/require-directory@2.1.1:
|
||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -4221,12 +4093,6 @@ packages:
|
|||
queue-microtask: 1.2.3
|
||||
dev: true
|
||||
|
||||
/rxjs@7.8.1:
|
||||
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: true
|
||||
|
||||
/safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
dev: false
|
||||
|
@ -4321,10 +4187,6 @@ packages:
|
|||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
/shell-quote@1.8.1:
|
||||
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
|
||||
dev: true
|
||||
|
||||
/side-channel@1.0.4:
|
||||
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
|
||||
dependencies:
|
||||
|
@ -4456,10 +4318,6 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/spawn-command@0.0.2:
|
||||
resolution: {integrity: sha1-lUThpDygRfhTGqwaSMspva5iM44=}
|
||||
dev: true
|
||||
|
||||
/spdx-exceptions@2.3.0:
|
||||
resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
|
||||
dev: true
|
||||
|
@ -4563,13 +4421,6 @@ packages:
|
|||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
/supports-color@8.1.1:
|
||||
resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
dev: true
|
||||
|
||||
/supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
@ -4655,11 +4506,6 @@ packages:
|
|||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
dev: false
|
||||
|
||||
/tree-kill@1.2.2:
|
||||
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ts-api-utils@1.0.3(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
|
||||
engines: {node: '>=16.13.0'}
|
||||
|
@ -4991,20 +4837,6 @@ packages:
|
|||
typescript: 5.2.2
|
||||
dev: true
|
||||
|
||||
/wait-on@7.2.0:
|
||||
resolution: {integrity: sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
axios: 1.6.2
|
||||
joi: 17.11.0
|
||||
lodash: 4.17.21
|
||||
minimist: 1.2.8
|
||||
rxjs: 7.8.1
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: true
|
||||
|
||||
/webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
dev: false
|
||||
|
@ -5066,6 +4898,7 @@ packages:
|
|||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
dev: false
|
||||
|
||||
/wrap-ansi@8.1.0:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
|
@ -5119,11 +4952,6 @@ packages:
|
|||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||
dev: true
|
||||
|
||||
/y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/yallist@4.0.0:
|
||||
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
|
||||
|
||||
|
@ -5156,11 +4984,6 @@ packages:
|
|||
decamelize: 1.2.0
|
||||
dev: true
|
||||
|
||||
/yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/yargs@15.4.1:
|
||||
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -5178,19 +5001,6 @@ packages:
|
|||
yargs-parser: 18.1.3
|
||||
dev: true
|
||||
|
||||
/yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
escalade: 3.1.1
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.3
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 21.1.1
|
||||
dev: true
|
||||
|
||||
/yocto-queue@0.1.0:
|
||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
Loading…
Add table
Reference in a new issue