diff --git a/core/src/app.ts b/core/src/app.ts index 2b569d5c..cfdfa3f1 100644 --- a/core/src/app.ts +++ b/core/src/app.ts @@ -4,7 +4,7 @@ import { Middleware } from './middleware'; import { Plugin, PluginMap } from './plugin'; import { Bot, LogLevel } from './types'; import { loadModule } from './utils'; -import { remove } from '@zhinjs/shared'; +import { remove, sleep } from '@zhinjs/shared'; import { APP_KEY, CONFIG_DIR, REQUIRED_KEY, WORK_DIR } from './constans'; import path from 'path'; import { Adapter, AdapterBot, AdapterReceive } from './adapter'; @@ -348,8 +348,16 @@ export class App extends EventEmitter { if (!loaded) this.logger.warn(`load plugin "${name}" failed`, error); return this; } - - stop() {} + async stop() { + for (const [name, adapter] of this.adapters) { + adapter.emit('stop'); + this.logger.mark(`adapter: ${name} stopped`); + } + this.emit('stop'); + this.logger.info(`process exit after 3 seconds...`); + await sleep(3000); + process.exit(); + } } export interface App extends App.Services { @@ -430,6 +438,7 @@ export namespace App { } export interface Config { + has_init?: boolean; log_level: LogLevel | string; disable_adapters: string[]; disable_bots: string[]; diff --git a/package.json b/package.json index 9629f5b6..4972e378 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "https://github.com/zhinjs/zhin" }, "scripts": { - "start": "pnpm start -C test start", + "start": "pnpm -C test start", "dev": "pnpm -C test dev", "init": "pnpm -C test run init", "lint": "eslint packages --ext .ts", diff --git a/packages/adapters/kritor/src/client.ts b/packages/adapters/kritor/src/client.ts index ef635df1..48c922f6 100644 --- a/packages/adapters/kritor/src/client.ts +++ b/packages/adapters/kritor/src/client.ts @@ -7,7 +7,7 @@ import { Adapter, Dict, parseFromTemplate, valueMap } from 'zhin'; export class Client extends EventEmitter { services: Client.Services; - account?: kritor.core.GetCurrentAccountResponse; + account?: kritor.core.IGetCurrentAccountResponse; #credential: grpc.ChannelCredentials; constructor( public adapter: Adapter, @@ -15,20 +15,22 @@ export class Client extends EventEmitter { ) { super(); this.#credential = grpc.credentials.createInsecure(); - Reflect.set( - this.#credential, - 'callCredentials', - grpc.credentials.createFromMetadataGenerator((callOptions, callback) => { - callOptions.service_url; - const metadata = new grpc.Metadata(); - metadata.set('ticket', this.options.ticket || ''); - callback(null, metadata); - }), - ); + if (this.options.ticket) { + Reflect.set( + this.#credential, + 'callCredentials', + grpc.credentials.createFromMetadataGenerator((callOptions, callback) => { + callOptions.service_url; + const metadata = new grpc.Metadata(); + metadata.set('ticket', this.options.ticket || ''); + callback(null, metadata); + }), + ); + } this.services = this.#init(); } get logger() { - return this.adapter.getLogger(this.account?.account_name); + return this.adapter.getLogger(this.account?.account_name!); } #init() { return { @@ -133,7 +135,7 @@ export class Client extends EventEmitter { * @param ticket */ async authenticate(account?: string, ticket?: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.authentication.authenticate({ account, ticket }, (err, res) => { if (err) reject(err); resolve(res!); @@ -146,7 +148,7 @@ export class Client extends EventEmitter { * @param account */ async getAuthenticationState(account: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.authentication.getAuthenticationState({ account }, (err, res) => { if (err) reject(err); resolve(res!); @@ -160,7 +162,7 @@ export class Client extends EventEmitter { * @param super_ticket */ async getTicket(account: string, super_ticket: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.authentication.getTicket({ account, super_ticket }, (err, res) => { if (err) reject(err); resolve(res!); @@ -175,7 +177,7 @@ export class Client extends EventEmitter { * @param ticket */ async addTicket(account?: string, super_ticket?: string, ticket?: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.authentication.addTicket({ account, super_ticket, ticket }, (err, res) => { if (err) reject(err); resolve(res!); @@ -190,7 +192,7 @@ export class Client extends EventEmitter { * @param ticket */ async deleteTicket(account?: string, super_ticket?: string, ticket?: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.authentication.deleteTicket({ account, super_ticket, ticket }, (err, res) => { if (err) reject(err); resolve(res!); @@ -203,7 +205,7 @@ export class Client extends EventEmitter { * @param options */ async downloadFile(options: Parameters[0]) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.core.downloadFile(options, (err, res) => { if (err) reject(err); resolve(res!); @@ -215,7 +217,7 @@ export class Client extends EventEmitter { * 获取当前账户 */ async getCurrentAccount() { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.core.getCurrentAccount({}, (err, res) => { if (err) reject(err); resolve(res!); @@ -230,7 +232,7 @@ export class Client extends EventEmitter { * @param super_ticket */ async switchAccount(account_uid: string, account_uin: number, super_ticket: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.core.switchAccount({ account_uid, account_uin, super_ticket }, (err, res) => { if (err) reject(err); resolve(res!); @@ -243,7 +245,7 @@ export class Client extends EventEmitter { * @param options */ async callFunction(options: Parameters[0]) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.customization.callFunction(options, (err, res) => { if (err) reject(err); resolve(res); @@ -257,7 +259,7 @@ export class Client extends EventEmitter { * @param directory */ async shell(command: string[], directory: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.shell({ command, directory }, (err, res) => { if (err) reject(err); resolve(res!); @@ -271,7 +273,7 @@ export class Client extends EventEmitter { * @param recent */ async getLog(start: number, recent?: boolean) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.getLog({ start, recent }, (err, res) => { if (err) reject(err); resolve(res!); @@ -283,7 +285,7 @@ export class Client extends EventEmitter { * 清理缓存 */ async cleanCache() { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.clearCache({}, (err, res) => { if (err) reject(err); resolve(res!); @@ -295,7 +297,7 @@ export class Client extends EventEmitter { * 获取设备电量 */ async getDeviceBattery() { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.getDeviceBattery({}, (err, res) => { if (err) reject(err); resolve(res!); @@ -308,7 +310,7 @@ export class Client extends EventEmitter { * @param options */ async uploadImage(options: Parameters[0]) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.uploadImage(options, (err, res) => { if (err) reject(err); resolve(res!); @@ -324,7 +326,7 @@ export class Client extends EventEmitter { * @param attrs */ sendPacket(command: string, request_buffer: Buffer, is_protobuf?: boolean, attrs?: Record) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.developer.sendPacket({ command, request_buffer, is_protobuf, attrs }, (err, res) => { if (err) reject(err); resolve(res!); @@ -332,7 +334,7 @@ export class Client extends EventEmitter { }); } sign(uin: string, command: string, seq: number, buffer: Buffer, qua: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.qsign.sign({ uin, command, seq, buffer, qua }, (err, res) => { if (err) reject(err); resolve(res!); @@ -340,7 +342,7 @@ export class Client extends EventEmitter { }); } async energy(data: string, salt: Buffer) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.qsign.energy({ data, salt }, (err, res) => { if (err) reject(err); resolve(res!); @@ -352,7 +354,7 @@ export class Client extends EventEmitter { * 获取cmd白名单 */ async getCmdWhitelist() { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.qsign.getCmdWhitelist({}, (err, res) => { if (err) reject(err); resolve(res!); @@ -366,7 +368,7 @@ export class Client extends EventEmitter { * @param name */ async createFolder(group_id: number, name: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.createFolder({ group_id, name }, (err, res) => { if (err) reject(err); resolve(res!); @@ -381,7 +383,7 @@ export class Client extends EventEmitter { * @param name */ async renameFolder(group_id: number, folder_id: string, name: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.renameFolder({ group_id, folder_id, name }, (err, res) => { if (err) reject(err); resolve(res!); @@ -395,7 +397,7 @@ export class Client extends EventEmitter { * @param folder_id */ async deleteFolder(group_id: number, folder_id: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.deleteFolder({ group_id, folder_id }, (err, res) => { if (err) reject(err); resolve(res!); @@ -403,7 +405,7 @@ export class Client extends EventEmitter { }); } async deleteFile(group_id: number, file_id: string, bus_id: number) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.deleteFile({ group_id, file_id, bus_id }, (err, res) => { if (err) reject(err); resolve(res!); @@ -416,7 +418,7 @@ export class Client extends EventEmitter { * @param group_id */ async getFileSystemInfo(group_id: number) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.getFileSystemInfo({ group_id }, (err, res) => { if (err) reject(err); resolve(res!); @@ -430,7 +432,7 @@ export class Client extends EventEmitter { * @param folder_id */ async getFileList(group_id: number, folder_id: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.groupFile.getFileList({ group_id, folder_id }, (err, res) => { if (err) reject(err); resolve(res!); @@ -495,7 +497,7 @@ export class Client extends EventEmitter { * @param vote_count */ async voteUser(target_uid: string, vote_count = 10) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.friend.voteUser({ target_uid, vote_count }, (err, res) => { if (err) reject(err); resolve(res); @@ -547,8 +549,8 @@ export class Client extends EventEmitter { * @param elements * @param retry_count */ - async sendMessage(contact: kritor.common.IContact, elements: kritor.common.Element[], retry_count = 1) { - return new Promise((resolve, reject) => { + async sendMessage(contact: kritor.common.IContact, elements: kritor.common.IElement[], retry_count = 1) { + return new Promise((resolve, reject) => { this.services.message.sendMessage({ contact, elements, retry_count }, (err, res) => { if (err) reject(err); resolve(res); @@ -562,8 +564,8 @@ export class Client extends EventEmitter { * @param res_id * @param retry_count */ - async sendMessageByResId(contact: kritor.common.Contact, res_id: string, retry_count = 1) { - return new Promise(async (resolve, reject) => { + async sendMessageByResId(contact: kritor.common.IContact, res_id: string, retry_count = 1) { + return new Promise(async (resolve, reject) => { this.services.message.sendMessageByResId({ contact, res_id, retry_count }, (err, res) => { if (err) reject(err); resolve(res); @@ -575,8 +577,8 @@ export class Client extends EventEmitter { * 设置已读某个联系人的消息 * @param contact */ - async setMessageReaded(contact: kritor.common.Contact) { - return new Promise((resolve, reject) => { + async setMessageReaded(contact: kritor.common.IContact) { + return new Promise((resolve, reject) => { this.services.message.setMessageReaded({ contact }, (err, res) => { if (err) reject(err); resolve(res); @@ -589,8 +591,8 @@ export class Client extends EventEmitter { * @param contact * @param message_id */ - recallMessage(contact: kritor.common.Contact, message_id: string) { - return new Promise((resolve, reject) => { + recallMessage(contact: kritor.common.IContact, message_id: string) { + return new Promise((resolve, reject) => { this.services.message.recallMessage({ contact, message_id }, (err, res) => { if (err) reject(err); resolve(res); @@ -605,8 +607,8 @@ export class Client extends EventEmitter { * @param face_id * @param is_set */ - async reactMessageWithEmoji(contact: kritor.common.Contact, message_id: string, face_id: number, is_set?: boolean) { - return new Promise((resolve, reject) => { + async reactMessageWithEmoji(contact: kritor.common.IContact, message_id: string, face_id: number, is_set?: boolean) { + return new Promise((resolve, reject) => { this.services.message.reactMessageWithEmoji({ contact, message_id, face_id, is_set }, (err, res) => { if (err) reject(err); resolve(res); @@ -619,8 +621,8 @@ export class Client extends EventEmitter { * @param contact * @param message_id */ - async getMessage(contact: kritor.common.Contact, message_id: string) { - return new Promise((resolve, reject) => { + async getMessage(contact: kritor.common.IContact, message_id: string) { + return new Promise((resolve, reject) => { this.services.message.getMessage({ contact, message_id }, (err, res) => { if (err) reject(err); resolve(res); @@ -633,8 +635,8 @@ export class Client extends EventEmitter { * @param contact * @param message_seq */ - async getMessageBySeq(contact: kritor.common.Contact, message_seq: number) { - return new Promise((resolve, reject) => { + async getMessageBySeq(contact: kritor.common.IContact, message_seq: number) { + return new Promise((resolve, reject) => { this.services.message.getMessageBySeq({ contact, message_seq }, (err, res) => { if (err) reject(err); resolve(res); @@ -648,8 +650,8 @@ export class Client extends EventEmitter { * @param start_message_id * @param count */ - async getHistoryMessage(contact: kritor.common.Contact, start_message_id: string, count: number = 10) { - return new Promise((resolve, reject) => { + async getHistoryMessage(contact: kritor.common.IContact, start_message_id: string, count: number = 10) { + return new Promise((resolve, reject) => { this.services.message.getHistoryMessage({ contact, start_message_id, count }, (err, res) => { if (err) reject(err); resolve(res); @@ -663,8 +665,8 @@ export class Client extends EventEmitter { * @param start_message_seq * @param count */ - async getHistoryMessageBySeq(contact: kritor.common.Contact, start_message_seq: number, count = 10) { - return new Promise((resolve, reject) => { + async getHistoryMessageBySeq(contact: kritor.common.IContact, start_message_seq: number, count = 10) { + return new Promise((resolve, reject) => { this.services.message.getHistoryMessageBySeq({ contact, start_message_seq, count }, (err, res) => { if (err) reject(err); resolve(res); @@ -679,8 +681,8 @@ export class Client extends EventEmitter { * @param retry_count */ async uploadForwardMessage( - contact: kritor.common.Contact, - messages: kritor.common.ForwardMessageBody[], + contact: kritor.common.IContact, + messages: kritor.common.IForwardMessageBody[], retry_count = 1, ) { return new Promise((resolve, reject) => { @@ -698,7 +700,7 @@ export class Client extends EventEmitter { * @param res_id */ async downloadForwardMessage(res_id: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.message.downloadForwardMessage({ res_id }, (err, res) => { if (err) reject(err); resolve(res); @@ -713,7 +715,7 @@ export class Client extends EventEmitter { * @param page_size */ async getEssenceMessageList(group_id: number, page = 1, page_size = 10) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.message.getEssenceMessageList({ group_id, page, page_size }, (err, res) => { if (err) reject(err); resolve(res); @@ -727,7 +729,7 @@ export class Client extends EventEmitter { * @param message_id */ async setEssenceMessage(group_id: number, message_id: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.message.setEssenceMessage({ group_id, message_id }, (err, res) => { if (err) reject(err); resolve(res); @@ -741,7 +743,7 @@ export class Client extends EventEmitter { * @param message_id */ async deleteEssenceMessage(group_id: number, message_id: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.message.deleteEssenceMessage({ group_id, message_id }, (err, res) => { if (err) reject(err); resolve(res); @@ -757,7 +759,7 @@ export class Client extends EventEmitter { }); } async getCredentials(domain: string) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.services.web.getCredentials({ domain }, (err, res) => { if (err) reject(err); resolve(res); @@ -801,11 +803,11 @@ export namespace Client { qsign: kritor.developer.QsignService; web: kritor.web.WebService; }; - export function createElementsFromTemplate(template: string): kritor.common.Element[] { + export function createElementsFromTemplate(template: string): kritor.common.IElement[] { return parseFromTemplate(template).map(item => { const { type, data } = item; return Client.toKritorElement(type, data); - }) as kritor.common.Element[]; + }) as kritor.common.IElement[]; } export function eventMessageToString(event: kritor.common.IPushMessageBody) { return (event.elements || []) @@ -819,7 +821,7 @@ export namespace Client { .map(([key, value]) => { return `${key}='${encodeURIComponent(JSON.stringify(value))}'`; }) - .join(' ')}>`; + .join(' ')}/>`; }) .join(''); } diff --git a/packages/adapters/kritor/src/index.ts b/packages/adapters/kritor/src/index.ts index 984b6169..19218a7f 100644 --- a/packages/adapters/kritor/src/index.ts +++ b/packages/adapters/kritor/src/index.ts @@ -16,8 +16,9 @@ adapter.schema({ }); adapter.define('sendMsg', async (bot_id, target_id, target_type, message, source) => { const bot = adapter.pick(bot_id); + let template: string = await adapter.app!.renderMessage(message as string, source); const contact = bot.createContact(target_id, target_type as any); - await bot.sendMessage(contact, Client.createElementsFromTemplate(message)); + await bot.sendMessage(contact, Client.createElementsFromTemplate(template)); bot.logger.info(`send [${target_type} ${target_id}]:${decodeURIComponent(message)}`); }); const messageHandler = (bot: Adapter.Bot, event: kritor.common.IPushMessageBody) => { diff --git a/packages/adapters/mock/package.json b/packages/adapters/mock/package.json index 8ddc3fe4..a8ab65e3 100644 --- a/packages/adapters/mock/package.json +++ b/packages/adapters/mock/package.json @@ -16,7 +16,8 @@ "directory": "packages/adapters/mock" }, "peerDependencies": { - "zhin": "workspace:^" + "zhin": "workspace:^", + "@zhinjs/web": "workspace:^" }, "devDependencies": { "@types/node": "latest", diff --git a/packages/adapters/mock/src/index.ts b/packages/adapters/mock/src/index.ts index 6f16b035..b20fff8a 100644 --- a/packages/adapters/mock/src/index.ts +++ b/packages/adapters/mock/src/index.ts @@ -1,4 +1,11 @@ import { Adapter } from 'zhin'; +import type {} from '@zhinjs/web'; const adapter = new Adapter('console'); +const startBots = () => { + adapter.app!.web.ws.on('message', e => {}); +}; +const stopBots = () => {}; +adapter.on('start', startBots); +adapter.on('stop', stopBots); export default adapter; diff --git a/packages/plugins/qa/src/index.ts b/packages/plugins/qa/src/index.ts index 6f832ce2..82c8273b 100644 --- a/packages/plugins/qa/src/index.ts +++ b/packages/plugins/qa/src/index.ts @@ -72,7 +72,7 @@ const getAnswer = async (message: Message): Promise => { const qaPlugin = new Plugin('问答管理'); qaPlugin.required('database'); const qaCommand = qaPlugin - .command('问答 ') + .command('问答 ') .desc('添加问答') .option('-a 可用适配器,默认*', '*') .option('-b 可用机器人,默认*', '*') diff --git a/packages/services/web/src/index.ts b/packages/services/web/src/index.ts index b0287a1b..5bd3c69a 100644 --- a/packages/services/web/src/index.ts +++ b/packages/services/web/src/index.ts @@ -8,15 +8,16 @@ import * as path from 'path'; declare module 'zhin' { namespace App { interface Services { - viteServer: import('vite').ViteDevServer; - - addEntry(entry: string): () => void; - - wsServer: WebSocket.Server; - entries: Record; + web: WebServer; } } } +export type WebServer = { + vite: import('vite').ViteDevServer; + addEntry(entry: string): () => void; + ws: WebSocket.Server; + entries: Record; +}; export const name = 'Web端'; const plugin = new Plugin('Web端'); const createSyncMsg = (key: string, value: any) => { @@ -82,8 +83,8 @@ plugin.mounted(async () => { if (filename.endsWith('.ts')) ctx.type = 'text/javascript'; return (ctx.body = fs.createReadStream(filename)); }; - if (Object.keys(plugin.entries).includes(name)) { - return sendFile(path.resolve(process.env.PWD!, plugin.entries[name])); + if (Object.keys(plugin.web.entries).includes(name)) { + return sendFile(path.resolve(process.env.PWD!, plugin.web.entries[name])); } const filename = path.resolve(root, name); if (!filename.startsWith(root) && !filename.includes('node_modules')) { @@ -104,26 +105,26 @@ plugin.mounted(async () => { viteServer.middlewares(ctx.req, ctx.res, resolve); }), ); - plugin.service('viteServer', viteServer); - - plugin.service('entries', {}); - plugin.service('addEntry', entry => { - const hash = Date.now().toString(16); - plugin.entries[hash] = `/vite/@fs/${entry}`; - for (const ws of plugin.wsServer?.clients || []) { - ws.send(JSON.stringify(createAddMsg('entries', plugin.entries[hash]))); - } - return () => { - for (const ws of plugin.wsServer?.clients || []) { - ws.send(JSON.stringify(createDeleteMsg('entries', plugin.entries[hash]))); + plugin.service('web', { + vite: viteServer, + entries: {}, + addEntry(entry) { + const hash = Date.now().toString(16); + this.entries[hash] = `/vite/@fs/${entry}`; + for (const ws of this.ws.clients || []) { + ws.send(JSON.stringify(createAddMsg('entries', this.entries[hash]))); } - delete plugin.entries[hash]; - }; + return () => { + for (const ws of this.ws.clients || []) { + ws.send(JSON.stringify(createDeleteMsg('entries', this.entries[hash]))); + } + delete this.entries[hash]; + }; + }, + ws: plugin.router.ws('/server'), }); - const wss: WebSocket.Server = plugin.router.ws('/server'); - plugin.service('wsServer', wss); - wss.on('connection', (ws: WebSocket) => { - ws.send(JSON.stringify(createSyncMsg('entries', Object.values(plugin.entries)))); + plugin.web.ws.on('connection', (ws: WebSocket) => { + ws.send(JSON.stringify(createSyncMsg('entries', Object.values(plugin.web.entries)))); }); }); plugin.required('koa', 'router', 'server'); diff --git a/shared/tsconfig.dtsc.json b/shared/tsconfig.dtsc.json index 2014244f..7e218805 100644 --- a/shared/tsconfig.dtsc.json +++ b/shared/tsconfig.dtsc.json @@ -5,10 +5,5 @@ "declaration": true, "rootDir": "src", "outFile": "lib/index.d.ts" - }, - "dtsc": { - "inline": [ - "@zhinjs/core" - ], } } diff --git a/test/package.json b/test/package.json index 47625476..0c0e2768 100644 --- a/test/package.json +++ b/test/package.json @@ -3,7 +3,7 @@ "private": true, "version": "2.0.35", "scripts": { - "start": "zhin", + "start": "zhin init && zhin -m dev", "init": "zhin init", "dev": "zhin -m dev" }, diff --git a/zhin/src/cli.ts b/zhin/src/cli.ts index ed22668b..a55c622e 100644 --- a/zhin/src/cli.ts +++ b/zhin/src/cli.ts @@ -5,12 +5,6 @@ const getValue = (list: string[], key: string, defaultValue: string) => { list.splice(list.indexOf(key) + 1, 1); return value; }; -const paddingToLength = (str: string | Buffer, length: number) => { - if (str.length === length) return str.toString(); - if (typeof str === str) str = Buffer.from(str); - if (str.length > length) return str.slice(0, length).toString(); - return str.toString().padEnd(length, '0'); -}; const defaultArgv = { mode: 'prod', key: '', diff --git a/zhin/src/index.ts b/zhin/src/index.ts index effb3e3b..8f07aa18 100644 --- a/zhin/src/index.ts +++ b/zhin/src/index.ts @@ -82,6 +82,7 @@ export async function initialApp(this: App) { const userPluginDir = path.join(WORK_DIR, 'plugins'); if (!fs.existsSync(userAdapterDir)) fs.mkdirSync(userAdapterDir); if (!fs.existsSync(userPluginDir)) fs.mkdirSync(userPluginDir); + this.config.has_init = true; this.config.adapters.push('processAdapter'); this.config.db_driver = 'level'; this.config.db_init_args = [ diff --git a/zhin/src/start.ts b/zhin/src/start.ts index d02c1133..d74220be 100644 --- a/zhin/src/start.ts +++ b/zhin/src/start.ts @@ -1,5 +1,7 @@ -import { createApp } from '@zhinjs/core'; +import { CONFIG_DIR, createApp } from '@zhinjs/core'; import { initialApp } from '.'; +import { sleep } from '@zhinjs/shared'; +import process from 'process'; const errorHandler = (e: unknown) => console.error(e); (async () => { @@ -8,7 +10,16 @@ const errorHandler = (e: unknown) => console.error(e); process.on('uncaughtException', errorHandler); const app = createApp(); if (init === '1') { + if (app.config.has_init) { + app.logger.info('zhin app has already initialized, skipping initialization'); + return process.exit(); + } + app.logger.info('initializing'); await initialApp.apply(app); + app.logger.info('initialized,process will exit after 3 seconds'); + app.logger.info(`please run 'npm start' to start zhin app`); + await sleep(3000); + return process.exit(); } app.start(process.env.mode || 'prod'); })();