mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
improve gateway
This commit is contained in:
parent
82b7bc579b
commit
f6c7ebd468
@ -17,7 +17,9 @@ import ServiceManager from "./services/manager"
|
|||||||
import Service from "./services/service"
|
import Service from "./services/service"
|
||||||
import * as Managers from "./managers"
|
import * as Managers from "./managers"
|
||||||
|
|
||||||
|
global.debugFlag = process.env.DEBUG === "true"
|
||||||
const isProduction = process.env.NODE_ENV === "production"
|
const isProduction = process.env.NODE_ENV === "production"
|
||||||
|
|
||||||
const sslKey = path.resolve(process.cwd(), ".ssl", "privkey.pem")
|
const sslKey = path.resolve(process.cwd(), ".ssl", "privkey.pem")
|
||||||
const sslCert = path.resolve(process.cwd(), ".ssl", "cert.pem")
|
const sslCert = path.resolve(process.cwd(), ".ssl", "cert.pem")
|
||||||
|
|
||||||
@ -71,6 +73,10 @@ export default class Gateway {
|
|||||||
* Creates and initializes all service instances
|
* Creates and initializes all service instances
|
||||||
*/
|
*/
|
||||||
async createServiceInstances() {
|
async createServiceInstances() {
|
||||||
|
if (!debugFlag) {
|
||||||
|
console.log(`🔰 Starting all services, please wait...`)
|
||||||
|
}
|
||||||
|
|
||||||
for await (const servicePath of this.services) {
|
for await (const servicePath of this.services) {
|
||||||
const instanceBasePath = path.dirname(servicePath)
|
const instanceBasePath = path.dirname(servicePath)
|
||||||
const servicePkg = require(
|
const servicePkg = require(
|
||||||
@ -99,8 +105,6 @@ export default class Gateway {
|
|||||||
|
|
||||||
// Initialize service
|
// Initialize service
|
||||||
await service.initialize()
|
await service.initialize()
|
||||||
|
|
||||||
console.log(`📦 [${serviceId}] Service initialized`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,10 +117,6 @@ export default class Gateway {
|
|||||||
this.serviceRegistry[serviceId].initialized = true
|
this.serviceRegistry[serviceId].initialized = true
|
||||||
this.serviceRegistry[serviceId].ready = true
|
this.serviceRegistry[serviceId].ready = true
|
||||||
|
|
||||||
console.log(
|
|
||||||
`✅ [${serviceId}][${this.serviceRegistry[serviceId].index}] Ready`,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Check if all services are ready
|
// Check if all services are ready
|
||||||
this.checkAllServicesReady()
|
this.checkAllServicesReady()
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ export default class Gateway {
|
|||||||
const id = service.id
|
const id = service.id
|
||||||
|
|
||||||
if (data.type === "log") {
|
if (data.type === "log") {
|
||||||
console.log(`[${id}] ${data.message}`)
|
console.log(`[ipc:${id}] ${data.message}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.status === "ready") {
|
if (data.status === "ready") {
|
||||||
@ -234,9 +234,9 @@ export default class Gateway {
|
|||||||
//console.clear()
|
//console.clear()
|
||||||
//console.log(comtyAscii)
|
//console.log(comtyAscii)
|
||||||
|
|
||||||
console.log("\n\n\n")
|
console.log("\n")
|
||||||
console.log(`🎉 All services[${this.services.length}] ready!\n`)
|
console.log(`🎉 All services[${this.services.length}] ready!\n`)
|
||||||
console.log(`USE: select <service>, reload, exit`)
|
console.log(`USE: select <service>, reload, exit\n`)
|
||||||
|
|
||||||
if (typeof this.gateway.applyConfiguration === "function") {
|
if (typeof this.gateway.applyConfiguration === "function") {
|
||||||
await this.gateway.applyConfiguration()
|
await this.gateway.applyConfiguration()
|
||||||
@ -285,11 +285,21 @@ export default class Gateway {
|
|||||||
this.services = await scanServices()
|
this.services = await scanServices()
|
||||||
this.ipcRouter = new IPCRouter()
|
this.ipcRouter = new IPCRouter()
|
||||||
|
|
||||||
|
global.eventBus = this.eventBus
|
||||||
|
global.ipcRouter = this.ipcRouter
|
||||||
|
|
||||||
if (this.services.length === 0) {
|
if (this.services.length === 0) {
|
||||||
console.error("❌ No services found")
|
console.error("❌ No services found")
|
||||||
return process.exit(1)
|
return process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(comtyAscii)
|
||||||
|
console.log(
|
||||||
|
`\nRunning ${chalk.bgBlue(`${pkg.name}`)} | ${chalk.bgMagenta(`[v${pkg.version}]`)} | ${this.state.internalIp} | ${isProduction ? "production" : "development"} | ${this.constructor.gatewayMode} |\n`,
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(`📦 Found ${this.services.length} service(s)`)
|
||||||
|
|
||||||
// Initialize gateway
|
// Initialize gateway
|
||||||
this.gateway = new Managers[this.constructor.gatewayMode]({
|
this.gateway = new Managers[this.constructor.gatewayMode]({
|
||||||
port: this.state.proxyPort,
|
port: this.state.proxyPort,
|
||||||
@ -302,19 +312,6 @@ export default class Gateway {
|
|||||||
await this.gateway.initialize()
|
await this.gateway.initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make key components available globally
|
|
||||||
global.eventBus = this.eventBus
|
|
||||||
global.ipcRouter = this.ipcRouter
|
|
||||||
global.proxy = this.proxy
|
|
||||||
|
|
||||||
//console.clear()
|
|
||||||
console.log(comtyAscii)
|
|
||||||
console.log(
|
|
||||||
`\nRunning ${chalk.bgBlue(`${pkg.name}`)} | ${chalk.bgMagenta(`[v${pkg.version}]`)} | ${this.state.internalIp} | ${isProduction ? "production" : "development"} \n\n\n`,
|
|
||||||
)
|
|
||||||
|
|
||||||
console.log(`📦 Found ${this.services.length} service(s)`)
|
|
||||||
|
|
||||||
// Watch for service state changes
|
// Watch for service state changes
|
||||||
Observable.observe(this.serviceRegistry, (changes) => {
|
Observable.observe(this.serviceRegistry, (changes) => {
|
||||||
this.checkAllServicesReady()
|
this.checkAllServicesReady()
|
||||||
@ -325,7 +322,7 @@ export default class Gateway {
|
|||||||
|
|
||||||
// WARNING: Starting relp makes uwebsockets unable to work properly, surging some bugs from nodejs (domain.enter)
|
// WARNING: Starting relp makes uwebsockets unable to work properly, surging some bugs from nodejs (domain.enter)
|
||||||
// use another alternative to parse commands, like stdin reading or something...
|
// use another alternative to parse commands, like stdin reading or something...
|
||||||
//this.startRELP()
|
this.startRELP()
|
||||||
}
|
}
|
||||||
|
|
||||||
startRELP() {
|
startRELP() {
|
||||||
|
@ -123,7 +123,7 @@ export default class Proxy {
|
|||||||
return reject(err)
|
return reject(err)
|
||||||
}
|
}
|
||||||
console.log(
|
console.log(
|
||||||
`🚀 Gateway listening on ${this.config.port}:${this.config.internalIp}`,
|
`🚀 Gateway listening on ${this.config.internalIp}:${this.config.port}`,
|
||||||
)
|
)
|
||||||
resolve()
|
resolve()
|
||||||
},
|
},
|
||||||
@ -205,6 +205,7 @@ export default class Proxy {
|
|||||||
name: pkg.name,
|
name: pkg.name,
|
||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
lb_version: defaults?.version || "unknown",
|
lb_version: defaults?.version || "unknown",
|
||||||
|
gateway: "standard",
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
@ -2,7 +2,8 @@ import fs from "node:fs/promises"
|
|||||||
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { execSync, spawn } from "node:child_process"
|
import { execSync, spawn } from "node:child_process"
|
||||||
import { platform } from "node:os"
|
import defaults from "linebridge/dist/defaults"
|
||||||
|
import pkg from "../../../package.json"
|
||||||
|
|
||||||
const localNginxBinary = path.resolve(process.cwd(), "nginx-bin")
|
const localNginxBinary = path.resolve(process.cwd(), "nginx-bin")
|
||||||
|
|
||||||
@ -43,9 +44,6 @@ export default class NginxManager {
|
|||||||
this.nginxProcess = null
|
this.nginxProcess = null
|
||||||
this.isNginxRunning = false
|
this.isNginxRunning = false
|
||||||
|
|
||||||
// Debug mode
|
|
||||||
this.debug = options.debug || false
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
existsSync(this.options.cert_file_name) &&
|
existsSync(this.options.cert_file_name) &&
|
||||||
existsSync(this.options.key_file_name)
|
existsSync(this.options.key_file_name)
|
||||||
@ -128,12 +126,19 @@ export default class NginxManager {
|
|||||||
.join(this.tempDir, "cache")
|
.join(this.tempDir, "cache")
|
||||||
.replace(/\\/g, "/")
|
.replace(/\\/g, "/")
|
||||||
|
|
||||||
|
const mainEndpointJSON = JSON.stringify({
|
||||||
|
name: pkg.name,
|
||||||
|
version: "1.21.6",
|
||||||
|
lb_version: defaults?.version ?? "unknown",
|
||||||
|
gateway: "nginx",
|
||||||
|
})
|
||||||
|
|
||||||
const config = `
|
const config = `
|
||||||
# Nginx configuration for Comty API Gateway
|
# Nginx configuration for Comty API Gateway
|
||||||
# Auto-generated - Do not edit manually
|
# Auto-generated - Do not edit manually
|
||||||
|
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
error_log ${normalizedLogsDir}/error.log ${this.debug ? "debug" : "error"};
|
error_log ${normalizedLogsDir}/error.log ${debugFlag ? "debug" : "error"};
|
||||||
pid ${normalizedTempDir}/nginx.pid;
|
pid ${normalizedTempDir}/nginx.pid;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
@ -155,7 +160,7 @@ http {
|
|||||||
'request_time: $request_time '
|
'request_time: $request_time '
|
||||||
'http_version: $server_protocol';
|
'http_version: $server_protocol';
|
||||||
|
|
||||||
access_log ${normalizedLogsDir}/access.log ${this.debug ? "debug" : "main"};
|
access_log ${normalizedLogsDir}/access.log ${debugFlag ? "debug" : "main"};
|
||||||
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
tcp_nodelay on;
|
tcp_nodelay on;
|
||||||
@ -190,7 +195,7 @@ http {
|
|||||||
add_header 'Access-Control-Allow-Headers' '*' always;
|
add_header 'Access-Control-Allow-Headers' '*' always;
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET,HEAD,PUT,PATCH,POST,DELETE' always;
|
add_header 'Access-Control-Allow-Methods' 'GET,HEAD,PUT,PATCH,POST,DELETE' always;
|
||||||
|
|
||||||
return 200 '{"ok":1}';
|
return 200 '${mainEndpointJSON}';
|
||||||
}
|
}
|
||||||
|
|
||||||
# Include service-specific configurations
|
# Include service-specific configurations
|
||||||
@ -247,7 +252,7 @@ http {
|
|||||||
? routePath
|
? routePath
|
||||||
: `/${routePath}`
|
: `/${routePath}`
|
||||||
|
|
||||||
if (this.debug) {
|
if (debugFlag) {
|
||||||
console.log(
|
console.log(
|
||||||
`🔍 Registering route for [${serviceId}]: ${normalizedPath} -> ${target} (${websocket ? "WebSocket" : "HTTP"})`,
|
`🔍 Registering route for [${serviceId}]: ${normalizedPath} -> ${target} (${websocket ? "WebSocket" : "HTTP"})`,
|
||||||
)
|
)
|
||||||
@ -349,7 +354,7 @@ http {
|
|||||||
// Write the config
|
// Write the config
|
||||||
await fs.writeFile(this.servicesConfigPath, config)
|
await fs.writeFile(this.servicesConfigPath, config)
|
||||||
|
|
||||||
if (this.debug) {
|
if (debugFlag) {
|
||||||
console.log(`📄 Writted [${this.routes.size}] service routes`)
|
console.log(`📄 Writted [${this.routes.size}] service routes`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,7 +499,7 @@ ${locationDirective} {
|
|||||||
|
|
||||||
const cmdString = `"${this.nginxBinary}" ${allArgs.join(" ")}`
|
const cmdString = `"${this.nginxBinary}" ${allArgs.join(" ")}`
|
||||||
|
|
||||||
if (this.debug) {
|
if (debugFlag) {
|
||||||
console.log(`🔍 Executing: ${cmdString}`)
|
console.log(`🔍 Executing: ${cmdString}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +571,7 @@ ${locationDirective} {
|
|||||||
* Stop the Nginx server
|
* Stop the Nginx server
|
||||||
* @returns {Boolean} - Success status
|
* @returns {Boolean} - Success status
|
||||||
*/
|
*/
|
||||||
async close() {
|
async stop() {
|
||||||
try {
|
try {
|
||||||
if (this.nginxProcess) {
|
if (this.nginxProcess) {
|
||||||
// Try graceful shutdown first
|
// Try graceful shutdown first
|
||||||
|
@ -1,68 +1,162 @@
|
|||||||
import repl from "node:repl"
|
|
||||||
|
|
||||||
export default class RELP {
|
export default class RELP {
|
||||||
constructor(handlers) {
|
constructor(handlers) {
|
||||||
this.handlers = handlers
|
this.handlers = handlers
|
||||||
|
this.initCommandLine()
|
||||||
|
}
|
||||||
|
|
||||||
repl.start({
|
initCommandLine() {
|
||||||
prompt: "> ",
|
// Configure line-by-line input mode
|
||||||
useGlobal: true,
|
process.stdin.setEncoding("utf8")
|
||||||
eval: (input, context, filename, callback) => {
|
process.stdin.resume()
|
||||||
let inputs = input.split(" ")
|
process.stdin.setRawMode(true)
|
||||||
|
|
||||||
// remove last \n from input
|
// Buffer to store user input
|
||||||
inputs[inputs.length - 1] = inputs[inputs.length - 1].replace(/\n/g, "")
|
this.inputBuffer = ""
|
||||||
|
|
||||||
// find relp command
|
// Show initial prompt
|
||||||
const command = inputs[0]
|
this.showPrompt()
|
||||||
const args = inputs.slice(1)
|
|
||||||
|
|
||||||
const command_fn = this.commands.find((relp_command) => {
|
// Handle user input
|
||||||
let exising = false
|
process.stdin.on("data", (data) => {
|
||||||
|
const key = data.toString()
|
||||||
|
|
||||||
if (Array.isArray(relp_command.aliases)) {
|
// Ctrl+C to exit
|
||||||
exising = relp_command.aliases.includes(command)
|
if (key === "\u0003") {
|
||||||
}
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
if (relp_command.cmd === command) {
|
// Enter key
|
||||||
exising = true
|
if (key === "\r" || key === "\n") {
|
||||||
}
|
// Move to a new line
|
||||||
|
console.log()
|
||||||
|
|
||||||
return exising
|
// Process the command
|
||||||
})
|
const command = this.inputBuffer.trim()
|
||||||
|
if (command) {
|
||||||
|
this.processCommand(command)
|
||||||
|
}
|
||||||
|
|
||||||
if (!command_fn) {
|
// Clear the buffer
|
||||||
return callback(`Command not found: ${command}`)
|
this.inputBuffer = ""
|
||||||
}
|
|
||||||
|
|
||||||
return command_fn.fn(callback, ...args)
|
// Show the prompt again
|
||||||
}
|
this.showPrompt()
|
||||||
})
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commands = [
|
// Backspace/Delete
|
||||||
{
|
if (key === "\b" || key === "\x7f") {
|
||||||
cmd: "select",
|
if (this.inputBuffer.length > 0) {
|
||||||
aliases: ["s", "sel"],
|
// Delete a character from the buffer
|
||||||
fn: (cb, service) => {
|
this.inputBuffer = this.inputBuffer.slice(0, -1)
|
||||||
this.handlers.detachAllServicesSTD()
|
|
||||||
|
|
||||||
return this.handlers.attachServiceSTD(service)
|
// Update the line in the terminal
|
||||||
}
|
process.stdout.write("\r\x1b[K> " + this.inputBuffer)
|
||||||
},
|
}
|
||||||
{
|
return
|
||||||
cmd: "reload",
|
}
|
||||||
aliases: ["r"],
|
|
||||||
fn: () => {
|
// Normal characters
|
||||||
this.handlers.reloadService()
|
if (key.length === 1 && key >= " ") {
|
||||||
}
|
this.inputBuffer += key
|
||||||
},
|
process.stdout.write(key)
|
||||||
{
|
}
|
||||||
cmd: "exit",
|
})
|
||||||
aliases: ["e"],
|
|
||||||
fn: () => {
|
// Intercept console.log to keep the prompt visible
|
||||||
process.exit(0)
|
const originalConsoleLog = console.log
|
||||||
}
|
console.log = (...args) => {
|
||||||
}
|
// Clear the current line
|
||||||
]
|
process.stdout.write("\r\x1b[K")
|
||||||
}
|
|
||||||
|
// Print the message
|
||||||
|
originalConsoleLog(...args)
|
||||||
|
|
||||||
|
// Reprint the prompt and current buffer
|
||||||
|
this.showPrompt(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the same with console.error
|
||||||
|
const originalConsoleError = console.error
|
||||||
|
console.error = (...args) => {
|
||||||
|
// Clear the current line
|
||||||
|
process.stdout.write("\r\x1b[K")
|
||||||
|
|
||||||
|
// Print the error message
|
||||||
|
originalConsoleError(...args)
|
||||||
|
|
||||||
|
// Reprint the prompt and current buffer
|
||||||
|
this.showPrompt(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showPrompt(newLine = true) {
|
||||||
|
if (newLine) {
|
||||||
|
process.stdout.write("\r")
|
||||||
|
}
|
||||||
|
process.stdout.write("> " + this.inputBuffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
processCommand(input) {
|
||||||
|
const inputs = input.split(" ")
|
||||||
|
const command = inputs[0]
|
||||||
|
const args = inputs.slice(1)
|
||||||
|
|
||||||
|
this.inputBuffer = ""
|
||||||
|
|
||||||
|
const commandFn = this.commands.find((relpCommand) => {
|
||||||
|
if (relpCommand.cmd === command) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(relpCommand.aliases)) {
|
||||||
|
return relpCommand.aliases.includes(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!commandFn) {
|
||||||
|
console.error(`Command not found: ${command}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapter to maintain compatibility with the original API
|
||||||
|
const callback = (result) => {
|
||||||
|
if (result) {
|
||||||
|
console.log(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
commandFn.fn(callback, ...args)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error executing command: ${error.message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands = [
|
||||||
|
{
|
||||||
|
cmd: "select",
|
||||||
|
aliases: ["s", "sel"],
|
||||||
|
fn: (cb, service) => {
|
||||||
|
this.handlers.detachAllServicesSTD()
|
||||||
|
return this.handlers.attachServiceSTD(service)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cmd: "reload",
|
||||||
|
aliases: ["r"],
|
||||||
|
fn: () => {
|
||||||
|
this.handlers.reloadService()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cmd: "exit",
|
||||||
|
aliases: ["e"],
|
||||||
|
fn: () => {
|
||||||
|
process.exit(0)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -51,6 +51,7 @@ export default class ServiceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const service = this.getService(id)
|
const service = this.getService(id)
|
||||||
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
console.error(`Service [${id}] not found`)
|
console.error(`Service [${id}] not found`)
|
||||||
return false
|
return false
|
||||||
@ -64,8 +65,6 @@ export default class ServiceManager {
|
|||||||
* Reload all services
|
* Reload all services
|
||||||
*/
|
*/
|
||||||
reloadAllServices() {
|
reloadAllServices() {
|
||||||
console.log("Reloading all services...")
|
|
||||||
|
|
||||||
for (const service of this.services) {
|
for (const service of this.services) {
|
||||||
service.reload()
|
service.reload()
|
||||||
}
|
}
|
||||||
@ -75,8 +74,6 @@ export default class ServiceManager {
|
|||||||
* Stop all services
|
* Stop all services
|
||||||
*/
|
*/
|
||||||
stopAllServices() {
|
stopAllServices() {
|
||||||
console.log("Stopping all services...")
|
|
||||||
|
|
||||||
for (const service of this.services) {
|
for (const service of this.services) {
|
||||||
service.stop()
|
service.stop()
|
||||||
}
|
}
|
||||||
@ -88,8 +85,6 @@ export default class ServiceManager {
|
|||||||
* @returns {boolean} True if attachment was successful
|
* @returns {boolean} True if attachment was successful
|
||||||
*/
|
*/
|
||||||
attachServiceStd(id) {
|
attachServiceStd(id) {
|
||||||
console.log(`Attaching to service [${id}]`)
|
|
||||||
|
|
||||||
if (id === "all") {
|
if (id === "all") {
|
||||||
this.selectedService = "all"
|
this.selectedService = "all"
|
||||||
this.attachAllServicesStd()
|
this.attachAllServicesStd()
|
||||||
|
@ -51,6 +51,8 @@ export default class Service {
|
|||||||
* Start the service process
|
* Start the service process
|
||||||
*/
|
*/
|
||||||
async startProcess() {
|
async startProcess() {
|
||||||
|
console.log(`🔰 [${this.id}] Starting service...`)
|
||||||
|
|
||||||
this.instance = await spawnService({
|
this.instance = await spawnService({
|
||||||
id: this.id,
|
id: this.id,
|
||||||
service: this.path,
|
service: this.path,
|
||||||
@ -60,7 +62,9 @@ export default class Service {
|
|||||||
onIPCData: this.handleIPCData.bind(this),
|
onIPCData: this.handleIPCData.bind(this),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// if debug flag is enabled, attach logs on start
|
||||||
this.instance.logs.attach()
|
this.instance.logs.attach()
|
||||||
|
|
||||||
return this.instance
|
return this.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,19 +23,16 @@ export default async ({ id, service, cwd, onClose, onError, onIPCData }) => {
|
|||||||
instance.logs = {
|
instance.logs = {
|
||||||
stdout: createServiceLogTransformer({ id }),
|
stdout: createServiceLogTransformer({ id }),
|
||||||
stderr: createServiceLogTransformer({ id, color: "bgRed" }),
|
stderr: createServiceLogTransformer({ id, color: "bgRed" }),
|
||||||
attach: () => {
|
attach: (withBuffer = false) => {
|
||||||
instance.logs.stdout.pipe(process.stdout)
|
instance.logs.stdout.pipe(process.stdout)
|
||||||
instance.logs.stderr.pipe(process.stderr)
|
instance.logs.stderr.pipe(process.stderr)
|
||||||
},
|
},
|
||||||
detach: () => {
|
detach: (withBuffer = false) => {
|
||||||
instance.logs.stdout.unpipe(process.stdout)
|
instance.logs.stdout.unpipe(process.stdout)
|
||||||
instance.logs.stderr.unpipe(process.stderr)
|
instance.logs.stderr.unpipe(process.stderr)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.logs.stdout.history = []
|
|
||||||
instance.logs.stderr.history = []
|
|
||||||
|
|
||||||
// push to buffer history
|
// push to buffer history
|
||||||
instance.stdout.pipe(instance.logs.stdout)
|
instance.stdout.pipe(instance.logs.stdout)
|
||||||
instance.stderr.pipe(instance.logs.stderr)
|
instance.stderr.pipe(instance.logs.stderr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user