mioki 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_package = require('./package-Cs8cEndC.cjs');
2
+ const require_package = require('./package-Bryo1nSK.cjs');
3
3
  let node_fs = require("node:fs");
4
4
  node_fs = require_package.__toESM(node_fs);
5
5
  let node_path = require("node:path");
@@ -107,7 +107,6 @@ const args = process.argv.slice(2);
107
107
  "error_push": true,
108
108
  "napcat": [
109
109
  {
110
- "name": "bot1",
111
110
  "protocol": "${protocol}",
112
111
  "port": ${port},
113
112
  "host": "${host}",
package/dist/cli.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.cjs","names":["version","fs","path"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport mri from 'mri'\nimport path from 'node:path'\nimport dedent from 'dedent'\nimport consola from 'consola'\nimport { version } from '../package.json'\n\nimport type { ConfirmPromptOptions, TextPromptOptions } from 'consola'\n\nconst args = process.argv.slice(2)\n\ninterface CliOptions {\n name?: string\n protocol?: string\n host?: string\n port?: number\n token?: string\n prefix?: string\n owners?: string\n admins?: string\n help?: boolean\n version?: boolean\n 'use-npm-mirror'?: boolean\n}\n\n;(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: 'version',\n h: 'help',\n },\n })\n\n const helpInfo = dedent(\n `\n mioki 命令行工具 v${version}\n \n 用法: mioki <命令> [选项]\n \n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n\n --name <name> 指定项目/文件夹名称,默认 bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n`,\n )\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`)\n process.exit(0)\n\n case cli.help:\n console.log(helpInfo)\n process.exit(0)\n }\n\n let {\n name = await input('请输入项目名称', { default: 'bot', placeholder: 'bot', required: true }),\n owners = await input('请输入主人 QQ (最高权限,英文逗号分隔,必填)', {\n placeholder: '请输入',\n default: '',\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n 'use-npm-mirror': useNpmMirror,\n } = cli\n\n if (name && owners) {\n protocol ||= 'ws'\n host ||= 'localhost'\n port ||= 3001\n token ||= ''\n prefix ||= '#'\n admins ||= ''\n useNpmMirror ??= false\n } else {\n token ||= await input('请输入 NapCat WS Token', { default: '', placeholder: '请输入' })\n protocol ||= await input('请输入 NapCat WS 协议', { default: 'ws', placeholder: 'ws', required: true })\n host ||= await input('请输入 NapCat WS 主机', { default: 'localhost', placeholder: 'localhost', required: true })\n port ||= parseInt(await input('请输入 NapCat WS 端口', { default: '3001', placeholder: '3001', required: true }))\n prefix ||= await input('请输入消息命令前缀', { default: '#', placeholder: '#', required: true })\n admins ||= (await input('请输入管理员 QQ (插件权限,英文逗号分隔,可空)', { placeholder: '可空' })) || ''\n useNpmMirror ??= await confirm('是否使用 npm 镜像源加速依赖安装?', { initial: false })\n }\n\n const pkgJson = dedent(`\n {\n \"name\": \"mioki-bot\",\n \"private\": true,\n \"dependencies\": {\n \"mioki\": \"^${version}\"\n },\n \"mioki\": {\n \"prefix\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(',')\n .map((o) => o.trim())\n .join(', ')}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(',')\n .map((o) => `\"${o.trim()}\"`)\n .join(', ')\n : ''\n }],\n \"plugins\": [],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"name\": \"bot1\",\n \"protocol\": \"${protocol}\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"node app.ts\"\n }\n }\n`)\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioki'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n // ctx.bot.nickname;\n // ctx.bot.uin;\n // ctx.bot.api('xxx', params);\n\n // ctx.bot.sendGroupMsg(123456789, 'Hello Group!') // 发送群消息\n\n // const group = await ctx.bot.pickGroup(123456789) // 使用群号选择一个群实例\n // group?.sign() // 调用群实例方法\n\n // const friend = await ctx.bot.pickFriend(987654321) // 使用好友号选择一个好友实例\n // friend?.delete() // 调用好友实例方法\n\n // 处理所有消息:群、好友\n ctx.handle('message', async (e) => {\n // 收到 hello 消息时回复 world\n if (e.raw_message === 'hello') {\n // 第二个参数表示是否回复原消息\n e.reply('world', true)\n }\n\n // 收到 love 消息时回复\"爱你哟\"和一个爱心 QQ 表情\n if (e.raw_message === 'love') {\n // 复杂消息消息可以使用数组组合\n e.reply(['爱你哟 ', ctx.segment.face(66)])\n }\n\n // 收到 壁纸 消息时回复今天的 bing 壁纸\n if (e.raw_message === '壁纸') {\n e.reply(ctx.segment.image('https://60s.viki.moe/v2/bing?encoding=image'))\n }\n\n // 收到 一言 消息时回复一言\n if (e.raw_message === '一言') {\n const data = await (await fetch('https://v1.hitokoto.cn/')).json()\n e.reply(data.hitokoto, true)\n }\n })\n\n ctx.handle('message.group', (e) => {\n // 处理群消息\n // 调用消息实例上挂载的快速方法\n // e.reply('这是群消息的回复') // 回复消息\n // e.recall() // 撤回消息\n // e.getQuoteMsg() // 获取引用的消息\n // e.group.getInfo(); // 也可以通过群消息事件获取群实例,并调用群实例方法获取群信息\n })\n\n ctx.handle('message.private', (e) => {\n // 处理好友消息\n })\n\n // 处理所有请求:好友、群,添加好友、邀请入群等等\n ctx.handle('request', (e) => {\n e.approve() // 同意请求\n // e.reject() // 拒绝请求\n })\n\n // 处理所有通知,好友、群的数量增加与减少、戳一戳、撤回等等\n ctx.handle('notice', (e) => {\n ctx.logger.info('Notice', e)\n })\n\n // 注册定时任务\n ctx.cron('*/3 * * * * *', async (ctx, task) => {\n ctx.logger.info('Cron', task)\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n\n`)\n\n const npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\n`)\n\n const fileTree = {\n 'app.ts': \"require('mioki').start({ cwd: __dirname })\",\n 'package.json': pkgJson,\n plugins: { demo: { 'index.ts': pluginCode } },\n ...(useNpmMirror ? { '.npmrc': npmrc } : {}),\n }\n\n createNewProject(name, fileTree)\n})()\n\nasync function createNewProject(name: string, fileTree: Record<string, any>) {\n const projectName = name\n const projectPath = withRoot(`./${projectName}`)\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`)\n\n if (!overwrite) {\n gracefullyExit()\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm('项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?')\n if (!confirmOver) {\n gracefullyExit()\n }\n }\n }\n\n fs.rmSync(projectPath, { recursive: true })\n }\n\n fs.mkdirSync(projectPath)\n\n makeFileTree(fileTree, projectPath)\n\n console.log(`项目 ${projectName} 创建成功!根据下面的引导启动 mioki。`)\n console.log(`\\ncd ${projectPath} && npm install && npm start\\n`)\n}\n\nfunction gracefullyExit() {\n console.log('Bye!')\n process.exit(0)\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path)\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, 'type' | 'required'> & { required?: boolean }\n\nasync function confirm(message: string, options?: OmitTypeWithRequired<ConfirmPromptOptions>) {\n return consola.prompt(message, { type: 'confirm', cancel: 'reject', ...options })\n}\n\nasync function input(message: string, options?: OmitTypeWithRequired<TextPromptOptions>) {\n const result = await consola.prompt(message, { type: 'text', cancel: 'reject', ...options })\n if (options?.required && !result) return input(message, options)\n return result\n}\n\nfunction makeFileTree(\n fileTree: Record<string, string | Record<string, string | Record<string, string>>>,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === 'object' && content !== null) {\n const subPath = `${base}/${name}`\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath)\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === 'object') {\n makeFileTree(content, subPath)\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent)\n }\n }\n } else {\n const filePath = `${base}/${name}`\n const dirname = path.dirname(filePath)\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname)\n }\n fs.writeFileSync(filePath, content)\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.cjs","names":["version","fs","path"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport mri from 'mri'\nimport path from 'node:path'\nimport dedent from 'dedent'\nimport consola from 'consola'\nimport { version } from '../package.json'\n\nimport type { ConfirmPromptOptions, TextPromptOptions } from 'consola'\n\nconst args = process.argv.slice(2)\n\ninterface CliOptions {\n name?: string\n protocol?: string\n host?: string\n port?: number\n token?: string\n prefix?: string\n owners?: string\n admins?: string\n help?: boolean\n version?: boolean\n 'use-npm-mirror'?: boolean\n}\n\n;(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: 'version',\n h: 'help',\n },\n })\n\n const helpInfo = dedent(\n `\n mioki 命令行工具 v${version}\n \n 用法: mioki <命令> [选项]\n \n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n\n --name <name> 指定项目/文件夹名称,默认 bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n`,\n )\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`)\n process.exit(0)\n\n case cli.help:\n console.log(helpInfo)\n process.exit(0)\n }\n\n let {\n name = await input('请输入项目名称', { default: 'bot', placeholder: 'bot', required: true }),\n owners = await input('请输入主人 QQ (最高权限,英文逗号分隔,必填)', {\n placeholder: '请输入',\n default: '',\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n 'use-npm-mirror': useNpmMirror,\n } = cli\n\n if (name && owners) {\n protocol ||= 'ws'\n host ||= 'localhost'\n port ||= 3001\n token ||= ''\n prefix ||= '#'\n admins ||= ''\n useNpmMirror ??= false\n } else {\n token ||= await input('请输入 NapCat WS Token', { default: '', placeholder: '请输入' })\n protocol ||= await input('请输入 NapCat WS 协议', { default: 'ws', placeholder: 'ws', required: true })\n host ||= await input('请输入 NapCat WS 主机', { default: 'localhost', placeholder: 'localhost', required: true })\n port ||= parseInt(await input('请输入 NapCat WS 端口', { default: '3001', placeholder: '3001', required: true }))\n prefix ||= await input('请输入消息命令前缀', { default: '#', placeholder: '#', required: true })\n admins ||= (await input('请输入管理员 QQ (插件权限,英文逗号分隔,可空)', { placeholder: '可空' })) || ''\n useNpmMirror ??= await confirm('是否使用 npm 镜像源加速依赖安装?', { initial: false })\n }\n\n const pkgJson = dedent(`\n {\n \"name\": \"mioki-bot\",\n \"private\": true,\n \"dependencies\": {\n \"mioki\": \"^${version}\"\n },\n \"mioki\": {\n \"prefix\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(',')\n .map((o) => o.trim())\n .join(', ')}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(',')\n .map((o) => `\"${o.trim()}\"`)\n .join(', ')\n : ''\n }],\n \"plugins\": [],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"node app.ts\"\n }\n }\n`)\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioki'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n // ctx.bot.nickname;\n // ctx.bot.uin;\n // ctx.bot.api('xxx', params);\n\n // ctx.bot.sendGroupMsg(123456789, 'Hello Group!') // 发送群消息\n\n // const group = await ctx.bot.pickGroup(123456789) // 使用群号选择一个群实例\n // group?.sign() // 调用群实例方法\n\n // const friend = await ctx.bot.pickFriend(987654321) // 使用好友号选择一个好友实例\n // friend?.delete() // 调用好友实例方法\n\n // 处理所有消息:群、好友\n ctx.handle('message', async (e) => {\n // 收到 hello 消息时回复 world\n if (e.raw_message === 'hello') {\n // 第二个参数表示是否回复原消息\n e.reply('world', true)\n }\n\n // 收到 love 消息时回复\"爱你哟\"和一个爱心 QQ 表情\n if (e.raw_message === 'love') {\n // 复杂消息消息可以使用数组组合\n e.reply(['爱你哟 ', ctx.segment.face(66)])\n }\n\n // 收到 壁纸 消息时回复今天的 bing 壁纸\n if (e.raw_message === '壁纸') {\n e.reply(ctx.segment.image('https://60s.viki.moe/v2/bing?encoding=image'))\n }\n\n // 收到 一言 消息时回复一言\n if (e.raw_message === '一言') {\n const data = await (await fetch('https://v1.hitokoto.cn/')).json()\n e.reply(data.hitokoto, true)\n }\n })\n\n ctx.handle('message.group', (e) => {\n // 处理群消息\n // 调用消息实例上挂载的快速方法\n // e.reply('这是群消息的回复') // 回复消息\n // e.recall() // 撤回消息\n // e.getQuoteMsg() // 获取引用的消息\n // e.group.getInfo(); // 也可以通过群消息事件获取群实例,并调用群实例方法获取群信息\n })\n\n ctx.handle('message.private', (e) => {\n // 处理好友消息\n })\n\n // 处理所有请求:好友、群,添加好友、邀请入群等等\n ctx.handle('request', (e) => {\n e.approve() // 同意请求\n // e.reject() // 拒绝请求\n })\n\n // 处理所有通知,好友、群的数量增加与减少、戳一戳、撤回等等\n ctx.handle('notice', (e) => {\n ctx.logger.info('Notice', e)\n })\n\n // 注册定时任务\n ctx.cron('*/3 * * * * *', async (ctx, task) => {\n ctx.logger.info('Cron', task)\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n\n`)\n\n const npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\n`)\n\n const fileTree = {\n 'app.ts': \"require('mioki').start({ cwd: __dirname })\",\n 'package.json': pkgJson,\n plugins: { demo: { 'index.ts': pluginCode } },\n ...(useNpmMirror ? { '.npmrc': npmrc } : {}),\n }\n\n createNewProject(name, fileTree)\n})()\n\nasync function createNewProject(name: string, fileTree: Record<string, any>) {\n const projectName = name\n const projectPath = withRoot(`./${projectName}`)\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`)\n\n if (!overwrite) {\n gracefullyExit()\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm('项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?')\n if (!confirmOver) {\n gracefullyExit()\n }\n }\n }\n\n fs.rmSync(projectPath, { recursive: true })\n }\n\n fs.mkdirSync(projectPath)\n\n makeFileTree(fileTree, projectPath)\n\n console.log(`项目 ${projectName} 创建成功!根据下面的引导启动 mioki。`)\n console.log(`\\ncd ${projectPath} && npm install && npm start\\n`)\n}\n\nfunction gracefullyExit() {\n console.log('Bye!')\n process.exit(0)\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path)\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, 'type' | 'required'> & { required?: boolean }\n\nasync function confirm(message: string, options?: OmitTypeWithRequired<ConfirmPromptOptions>) {\n return consola.prompt(message, { type: 'confirm', cancel: 'reject', ...options })\n}\n\nasync function input(message: string, options?: OmitTypeWithRequired<TextPromptOptions>) {\n const result = await consola.prompt(message, { type: 'text', cancel: 'reject', ...options })\n if (options?.required && !result) return input(message, options)\n return result\n}\n\nfunction makeFileTree(\n fileTree: Record<string, string | Record<string, string | Record<string, string>>>,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === 'object' && content !== null) {\n const subPath = `${base}/${name}`\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath)\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === 'object') {\n makeFileTree(content, subPath)\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent)\n }\n }\n } else {\n const filePath = `${base}/${name}`\n const dirname = path.dirname(filePath)\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname)\n }\n fs.writeFileSync(filePath, content)\n }\n }\n}\n"],"mappings":"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"}
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "./package-UYRX612w.mjs";
2
+ import { t as version } from "./package-Bvcr71Zp.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import mri from "mri";
@@ -102,7 +102,6 @@ const args = process.argv.slice(2);
102
102
  "error_push": true,
103
103
  "napcat": [
104
104
  {
105
- "name": "bot1",
106
105
  "protocol": "${protocol}",
107
106
  "port": ${port},
108
107
  "host": "${host}",
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport mri from 'mri'\nimport path from 'node:path'\nimport dedent from 'dedent'\nimport consola from 'consola'\nimport { version } from '../package.json'\n\nimport type { ConfirmPromptOptions, TextPromptOptions } from 'consola'\n\nconst args = process.argv.slice(2)\n\ninterface CliOptions {\n name?: string\n protocol?: string\n host?: string\n port?: number\n token?: string\n prefix?: string\n owners?: string\n admins?: string\n help?: boolean\n version?: boolean\n 'use-npm-mirror'?: boolean\n}\n\n;(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: 'version',\n h: 'help',\n },\n })\n\n const helpInfo = dedent(\n `\n mioki 命令行工具 v${version}\n \n 用法: mioki <命令> [选项]\n \n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n\n --name <name> 指定项目/文件夹名称,默认 bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n`,\n )\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`)\n process.exit(0)\n\n case cli.help:\n console.log(helpInfo)\n process.exit(0)\n }\n\n let {\n name = await input('请输入项目名称', { default: 'bot', placeholder: 'bot', required: true }),\n owners = await input('请输入主人 QQ (最高权限,英文逗号分隔,必填)', {\n placeholder: '请输入',\n default: '',\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n 'use-npm-mirror': useNpmMirror,\n } = cli\n\n if (name && owners) {\n protocol ||= 'ws'\n host ||= 'localhost'\n port ||= 3001\n token ||= ''\n prefix ||= '#'\n admins ||= ''\n useNpmMirror ??= false\n } else {\n token ||= await input('请输入 NapCat WS Token', { default: '', placeholder: '请输入' })\n protocol ||= await input('请输入 NapCat WS 协议', { default: 'ws', placeholder: 'ws', required: true })\n host ||= await input('请输入 NapCat WS 主机', { default: 'localhost', placeholder: 'localhost', required: true })\n port ||= parseInt(await input('请输入 NapCat WS 端口', { default: '3001', placeholder: '3001', required: true }))\n prefix ||= await input('请输入消息命令前缀', { default: '#', placeholder: '#', required: true })\n admins ||= (await input('请输入管理员 QQ (插件权限,英文逗号分隔,可空)', { placeholder: '可空' })) || ''\n useNpmMirror ??= await confirm('是否使用 npm 镜像源加速依赖安装?', { initial: false })\n }\n\n const pkgJson = dedent(`\n {\n \"name\": \"mioki-bot\",\n \"private\": true,\n \"dependencies\": {\n \"mioki\": \"^${version}\"\n },\n \"mioki\": {\n \"prefix\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(',')\n .map((o) => o.trim())\n .join(', ')}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(',')\n .map((o) => `\"${o.trim()}\"`)\n .join(', ')\n : ''\n }],\n \"plugins\": [],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"name\": \"bot1\",\n \"protocol\": \"${protocol}\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"node app.ts\"\n }\n }\n`)\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioki'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n // ctx.bot.nickname;\n // ctx.bot.uin;\n // ctx.bot.api('xxx', params);\n\n // ctx.bot.sendGroupMsg(123456789, 'Hello Group!') // 发送群消息\n\n // const group = await ctx.bot.pickGroup(123456789) // 使用群号选择一个群实例\n // group?.sign() // 调用群实例方法\n\n // const friend = await ctx.bot.pickFriend(987654321) // 使用好友号选择一个好友实例\n // friend?.delete() // 调用好友实例方法\n\n // 处理所有消息:群、好友\n ctx.handle('message', async (e) => {\n // 收到 hello 消息时回复 world\n if (e.raw_message === 'hello') {\n // 第二个参数表示是否回复原消息\n e.reply('world', true)\n }\n\n // 收到 love 消息时回复\"爱你哟\"和一个爱心 QQ 表情\n if (e.raw_message === 'love') {\n // 复杂消息消息可以使用数组组合\n e.reply(['爱你哟 ', ctx.segment.face(66)])\n }\n\n // 收到 壁纸 消息时回复今天的 bing 壁纸\n if (e.raw_message === '壁纸') {\n e.reply(ctx.segment.image('https://60s.viki.moe/v2/bing?encoding=image'))\n }\n\n // 收到 一言 消息时回复一言\n if (e.raw_message === '一言') {\n const data = await (await fetch('https://v1.hitokoto.cn/')).json()\n e.reply(data.hitokoto, true)\n }\n })\n\n ctx.handle('message.group', (e) => {\n // 处理群消息\n // 调用消息实例上挂载的快速方法\n // e.reply('这是群消息的回复') // 回复消息\n // e.recall() // 撤回消息\n // e.getQuoteMsg() // 获取引用的消息\n // e.group.getInfo(); // 也可以通过群消息事件获取群实例,并调用群实例方法获取群信息\n })\n\n ctx.handle('message.private', (e) => {\n // 处理好友消息\n })\n\n // 处理所有请求:好友、群,添加好友、邀请入群等等\n ctx.handle('request', (e) => {\n e.approve() // 同意请求\n // e.reject() // 拒绝请求\n })\n\n // 处理所有通知,好友、群的数量增加与减少、戳一戳、撤回等等\n ctx.handle('notice', (e) => {\n ctx.logger.info('Notice', e)\n })\n\n // 注册定时任务\n ctx.cron('*/3 * * * * *', async (ctx, task) => {\n ctx.logger.info('Cron', task)\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n\n`)\n\n const npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\n`)\n\n const fileTree = {\n 'app.ts': \"require('mioki').start({ cwd: __dirname })\",\n 'package.json': pkgJson,\n plugins: { demo: { 'index.ts': pluginCode } },\n ...(useNpmMirror ? { '.npmrc': npmrc } : {}),\n }\n\n createNewProject(name, fileTree)\n})()\n\nasync function createNewProject(name: string, fileTree: Record<string, any>) {\n const projectName = name\n const projectPath = withRoot(`./${projectName}`)\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`)\n\n if (!overwrite) {\n gracefullyExit()\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm('项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?')\n if (!confirmOver) {\n gracefullyExit()\n }\n }\n }\n\n fs.rmSync(projectPath, { recursive: true })\n }\n\n fs.mkdirSync(projectPath)\n\n makeFileTree(fileTree, projectPath)\n\n console.log(`项目 ${projectName} 创建成功!根据下面的引导启动 mioki。`)\n console.log(`\\ncd ${projectPath} && npm install && npm start\\n`)\n}\n\nfunction gracefullyExit() {\n console.log('Bye!')\n process.exit(0)\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path)\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, 'type' | 'required'> & { required?: boolean }\n\nasync function confirm(message: string, options?: OmitTypeWithRequired<ConfirmPromptOptions>) {\n return consola.prompt(message, { type: 'confirm', cancel: 'reject', ...options })\n}\n\nasync function input(message: string, options?: OmitTypeWithRequired<TextPromptOptions>) {\n const result = await consola.prompt(message, { type: 'text', cancel: 'reject', ...options })\n if (options?.required && !result) return input(message, options)\n return result\n}\n\nfunction makeFileTree(\n fileTree: Record<string, string | Record<string, string | Record<string, string>>>,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === 'object' && content !== null) {\n const subPath = `${base}/${name}`\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath)\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === 'object') {\n makeFileTree(content, subPath)\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent)\n }\n }\n } else {\n const filePath = `${base}/${name}`\n const dirname = path.dirname(filePath)\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname)\n }\n fs.writeFileSync(filePath, content)\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport fs from 'node:fs'\nimport mri from 'mri'\nimport path from 'node:path'\nimport dedent from 'dedent'\nimport consola from 'consola'\nimport { version } from '../package.json'\n\nimport type { ConfirmPromptOptions, TextPromptOptions } from 'consola'\n\nconst args = process.argv.slice(2)\n\ninterface CliOptions {\n name?: string\n protocol?: string\n host?: string\n port?: number\n token?: string\n prefix?: string\n owners?: string\n admins?: string\n help?: boolean\n version?: boolean\n 'use-npm-mirror'?: boolean\n}\n\n;(async () => {\n const cli = mri<CliOptions>(args, {\n alias: {\n v: 'version',\n h: 'help',\n },\n })\n\n const helpInfo = dedent(\n `\n mioki 命令行工具 v${version}\n \n 用法: mioki <命令> [选项]\n \n 选项:\n -h, --help 显示帮助信息\n -v, --version 显示版本号\n\n --name <name> 指定项目/文件夹名称,默认 bot\n --protocol <protocol> 指定 NapCat 协议,默认 ws\n --host <host> 指定 NapCat 主机,默认 localhost\n --port <port> 指定 NapCat 端口,默认 3001\n --token <token> 指定 NapCat 连接 Token,默认空\n --prefix <prefix> 指定命令前缀,默认 #\n --owners <owners> 指定主人 QQ,英文逗号分隔,必填\n --admins <admins> 指定管理员 QQ,英文逗号分隔,可空\n --use-npm-mirror 使用 npm 镜像源加速依赖安装,默认否\n`,\n )\n\n switch (true) {\n case cli.version:\n console.log(`v${version}`)\n process.exit(0)\n\n case cli.help:\n console.log(helpInfo)\n process.exit(0)\n }\n\n let {\n name = await input('请输入项目名称', { default: 'bot', placeholder: 'bot', required: true }),\n owners = await input('请输入主人 QQ (最高权限,英文逗号分隔,必填)', {\n placeholder: '请输入',\n default: '',\n required: true,\n }),\n token,\n protocol,\n host,\n port,\n prefix,\n admins,\n 'use-npm-mirror': useNpmMirror,\n } = cli\n\n if (name && owners) {\n protocol ||= 'ws'\n host ||= 'localhost'\n port ||= 3001\n token ||= ''\n prefix ||= '#'\n admins ||= ''\n useNpmMirror ??= false\n } else {\n token ||= await input('请输入 NapCat WS Token', { default: '', placeholder: '请输入' })\n protocol ||= await input('请输入 NapCat WS 协议', { default: 'ws', placeholder: 'ws', required: true })\n host ||= await input('请输入 NapCat WS 主机', { default: 'localhost', placeholder: 'localhost', required: true })\n port ||= parseInt(await input('请输入 NapCat WS 端口', { default: '3001', placeholder: '3001', required: true }))\n prefix ||= await input('请输入消息命令前缀', { default: '#', placeholder: '#', required: true })\n admins ||= (await input('请输入管理员 QQ (插件权限,英文逗号分隔,可空)', { placeholder: '可空' })) || ''\n useNpmMirror ??= await confirm('是否使用 npm 镜像源加速依赖安装?', { initial: false })\n }\n\n const pkgJson = dedent(`\n {\n \"name\": \"mioki-bot\",\n \"private\": true,\n \"dependencies\": {\n \"mioki\": \"^${version}\"\n },\n \"mioki\": {\n \"prefix\": \"${prefix}\",\n \"owners\": [${String(owners)\n .split(',')\n .map((o) => o.trim())\n .join(', ')}],\n \"admins\": [${\n admins\n ? String(admins)\n .split(',')\n .map((o) => `\"${o.trim()}\"`)\n .join(', ')\n : ''\n }],\n \"plugins\": [],\n \"log_level\": \"info\",\n \"online_push\": true,\n \"error_push\": true,\n \"napcat\": [\n {\n \"protocol\": \"${protocol}\",\n \"port\": ${port},\n \"host\": \"${host}\",\n \"token\": \"${token}\"\n }\n ]\n },\n \"scripts\": {\n \"start\": \"node app.ts\"\n }\n }\n`)\n\n const pluginCode = dedent(`\n import { definePlugin } from 'mioki'\n\n export default definePlugin({\n name: 'demo',\n version: '${version}',\n async setup(ctx) {\n ctx.logger.info('Demo 插件已加载')\n\n // ctx.bot.nickname;\n // ctx.bot.uin;\n // ctx.bot.api('xxx', params);\n\n // ctx.bot.sendGroupMsg(123456789, 'Hello Group!') // 发送群消息\n\n // const group = await ctx.bot.pickGroup(123456789) // 使用群号选择一个群实例\n // group?.sign() // 调用群实例方法\n\n // const friend = await ctx.bot.pickFriend(987654321) // 使用好友号选择一个好友实例\n // friend?.delete() // 调用好友实例方法\n\n // 处理所有消息:群、好友\n ctx.handle('message', async (e) => {\n // 收到 hello 消息时回复 world\n if (e.raw_message === 'hello') {\n // 第二个参数表示是否回复原消息\n e.reply('world', true)\n }\n\n // 收到 love 消息时回复\"爱你哟\"和一个爱心 QQ 表情\n if (e.raw_message === 'love') {\n // 复杂消息消息可以使用数组组合\n e.reply(['爱你哟 ', ctx.segment.face(66)])\n }\n\n // 收到 壁纸 消息时回复今天的 bing 壁纸\n if (e.raw_message === '壁纸') {\n e.reply(ctx.segment.image('https://60s.viki.moe/v2/bing?encoding=image'))\n }\n\n // 收到 一言 消息时回复一言\n if (e.raw_message === '一言') {\n const data = await (await fetch('https://v1.hitokoto.cn/')).json()\n e.reply(data.hitokoto, true)\n }\n })\n\n ctx.handle('message.group', (e) => {\n // 处理群消息\n // 调用消息实例上挂载的快速方法\n // e.reply('这是群消息的回复') // 回复消息\n // e.recall() // 撤回消息\n // e.getQuoteMsg() // 获取引用的消息\n // e.group.getInfo(); // 也可以通过群消息事件获取群实例,并调用群实例方法获取群信息\n })\n\n ctx.handle('message.private', (e) => {\n // 处理好友消息\n })\n\n // 处理所有请求:好友、群,添加好友、邀请入群等等\n ctx.handle('request', (e) => {\n e.approve() // 同意请求\n // e.reject() // 拒绝请求\n })\n\n // 处理所有通知,好友、群的数量增加与减少、戳一戳、撤回等等\n ctx.handle('notice', (e) => {\n ctx.logger.info('Notice', e)\n })\n\n // 注册定时任务\n ctx.cron('*/3 * * * * *', async (ctx, task) => {\n ctx.logger.info('Cron', task)\n })\n\n return () => {\n ctx.logger.info('Demo 插件已卸载')\n }\n },\n })\n\n`)\n\n const npmrc = dedent(`\n registry=https://registry.npmmirror.com\n fund=false\n`)\n\n const fileTree = {\n 'app.ts': \"require('mioki').start({ cwd: __dirname })\",\n 'package.json': pkgJson,\n plugins: { demo: { 'index.ts': pluginCode } },\n ...(useNpmMirror ? { '.npmrc': npmrc } : {}),\n }\n\n createNewProject(name, fileTree)\n})()\n\nasync function createNewProject(name: string, fileTree: Record<string, any>) {\n const projectName = name\n const projectPath = withRoot(`./${projectName}`)\n\n if (fs.existsSync(projectPath)) {\n const overwrite = await confirm(`项目 ${projectName} 已存在,是否覆盖?`)\n\n if (!overwrite) {\n gracefullyExit()\n }\n\n if (projectPath === process.cwd()) {\n if (fs.readdirSync(projectPath).length !== 0) {\n const confirmOver = await confirm('项目路径与当前路径相同,将删除当前目录下所有内容再创建,是否继续?')\n if (!confirmOver) {\n gracefullyExit()\n }\n }\n }\n\n fs.rmSync(projectPath, { recursive: true })\n }\n\n fs.mkdirSync(projectPath)\n\n makeFileTree(fileTree, projectPath)\n\n console.log(`项目 ${projectName} 创建成功!根据下面的引导启动 mioki。`)\n console.log(`\\ncd ${projectPath} && npm install && npm start\\n`)\n}\n\nfunction gracefullyExit() {\n console.log('Bye!')\n process.exit(0)\n}\n\nfunction withRoot(_path: string) {\n return path.resolve(process.cwd(), _path)\n}\n\ntype OmitTypeWithRequired<T> = Omit<T, 'type' | 'required'> & { required?: boolean }\n\nasync function confirm(message: string, options?: OmitTypeWithRequired<ConfirmPromptOptions>) {\n return consola.prompt(message, { type: 'confirm', cancel: 'reject', ...options })\n}\n\nasync function input(message: string, options?: OmitTypeWithRequired<TextPromptOptions>) {\n const result = await consola.prompt(message, { type: 'text', cancel: 'reject', ...options })\n if (options?.required && !result) return input(message, options)\n return result\n}\n\nfunction makeFileTree(\n fileTree: Record<string, string | Record<string, string | Record<string, string>>>,\n base: string,\n) {\n for (const [name, content] of Object.entries(fileTree)) {\n if (typeof content === 'object' && content !== null) {\n const subPath = `${base}/${name}`\n if (!fs.existsSync(subPath)) {\n fs.mkdirSync(subPath)\n }\n for (const [subName, subContent] of Object.entries(content)) {\n if (typeof subContent === 'object') {\n makeFileTree(content, subPath)\n } else {\n fs.writeFileSync(`${subPath}/${subName}`, subContent)\n }\n }\n } else {\n const filePath = `${base}/${name}`\n const dirname = path.dirname(filePath)\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname)\n }\n fs.writeFileSync(filePath, content)\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_package = require('./package-Cs8cEndC.cjs');
1
+ const require_package = require('./package-Bryo1nSK.cjs');
2
2
  let node_fs = require("node:fs");
3
3
  node_fs = require_package.__toESM(node_fs);
4
4
  let node_util = require("node:util");
@@ -1537,7 +1537,6 @@ async function getMiokiStatus(bots) {
1537
1537
  botStatuses.push({
1538
1538
  uin: bot.bot_id,
1539
1539
  nickname: bot.nickname,
1540
- name: bot.name,
1541
1540
  friends: friendList.length,
1542
1541
  groups: groupList.length,
1543
1542
  send: bot.stat.send.group + bot.stat.send.private,
@@ -1549,7 +1548,6 @@ async function getMiokiStatus(bots) {
1549
1548
  botStatuses.push({
1550
1549
  uin: bot.bot_id,
1551
1550
  nickname: bot.nickname,
1552
- name: bot.name,
1553
1551
  friends: 0,
1554
1552
  groups: 0,
1555
1553
  send: 0,
@@ -1604,13 +1602,14 @@ async function formatMiokiStatus(status) {
1604
1602
  const { bots, plugins, stats, system, disk, cpu, memory, versions } = status;
1605
1603
  const diskValid = disk.total > 0 && disk.free >= 0;
1606
1604
  const diskDesc = `${disk.percent}%-${(0, filesize.filesize)(disk.used, { round: 1 })}/${(0, filesize.filesize)(disk.total, { round: 1 })}`;
1605
+ const botLines = bots.map((bot) => {
1606
+ return `👤 ${bot.nickname} (${bot.uin})\n 📋 ${localNum(bot.friends)} 好友 / ${localNum(bot.groups)} 群 / 📮 收 ${localNum(bot.receive)} 发 ${localNum(bot.send)}`;
1607
+ }).join("\n");
1608
+ const statsLine = bots.length > 1 ? `\n📮 总计: 收 ${localNum(stats.receive)} 条,发 ${localNum(stats.send)} 条` : "";
1607
1609
  return `
1608
1610
  〓 🟢 mioki 状态 〓
1609
- ${bots.map((bot, index) => {
1610
- return `👤 ${bot.name ? `[${bot.name}] ` : ""}${bot.nickname} (${bot.uin})\n 📋 ${localNum(bot.friends)} 好友 / ${localNum(bot.groups)} 群 / 📮 收 ${localNum(bot.receive)} 发 ${localNum(bot.send)}`;
1611
- }).join("\n")}
1612
- 🧩 启用了 ${localNum(plugins.enabled)} 个插件,共 ${localNum(plugins.total)} 个
1613
- 📮 总计: 收 ${localNum(stats.receive)} 条,发 ${localNum(stats.send)} 条
1611
+ ${botLines}
1612
+ 🧩 启用了 ${localNum(plugins.enabled)} 个插件,共 ${localNum(plugins.total)} 个${statsLine}
1614
1613
  🚀 ${(0, filesize.filesize)(memory.rss.used, { round: 1 })}/${memory.percent}%
1615
1614
  ⏳ 已运行 ${(0, pretty_ms.default)(stats.uptime, {
1616
1615
  hideYear: true,
@@ -1950,8 +1949,8 @@ const BUILTIN_PLUGINS = [core_default];
1950
1949
  //#region src/start.ts
1951
1950
  const connectedBots = /* @__PURE__ */ new Map();
1952
1951
  async function connectBot(config, index) {
1953
- const { protocol = "ws", port = 3001, host = "localhost", token = "", name } = config;
1954
- const botName = name || `Bot${index + 1}`;
1952
+ const { protocol = "ws", port = 3001, host = "localhost", token = "" } = config;
1953
+ const botName = `Bot${index + 1}`;
1955
1954
  const wsUrl = consola_utils.colors.green(`${protocol}://${host}:${port}${token ? "?access_token=***" : ""}`);
1956
1955
  logger.info(`>>> 正在连接 ${consola_utils.colors.cyan(botName)}: ${wsUrl}`);
1957
1956
  const napcat = new napcat_sdk.NapCat({
@@ -1971,8 +1970,7 @@ async function connectBot(config, index) {
1971
1970
  napcat.once("napcat.connected", ({ user_id, nickname, app_name, app_version }) => {
1972
1971
  logger.info(`已连接到 ${consola_utils.colors.cyan(botName)}: ${consola_utils.colors.green(`${app_name}-v${app_version} ${nickname}(${user_id})`)}`);
1973
1972
  if (connectedBots.has(user_id)) {
1974
- const existingBot = connectedBots.get(user_id);
1975
- if (existingBot.name) logger.warn(`${consola_utils.colors.yellow(botName)} (${user_id}) 与 ${consola_utils.colors.yellow(existingBot.name)} (${user_id}) QQ 号重复,将跳过`);
1973
+ logger.warn(`${consola_utils.colors.yellow(botName)} (${user_id}) 与已存在的 bot (${user_id}) QQ 号重复,将跳过`);
1976
1974
  napcat.close();
1977
1975
  resolve(null);
1978
1976
  return;
@@ -1981,7 +1979,6 @@ async function connectBot(config, index) {
1981
1979
  extendedNapCat.bot_id = user_id;
1982
1980
  extendedNapCat.app_name = app_name;
1983
1981
  extendedNapCat.app_version = app_version;
1984
- extendedNapCat.name = botName;
1985
1982
  resolve(extendedNapCat);
1986
1983
  });
1987
1984
  napcat.run().catch((err) => {
@@ -2088,10 +2085,10 @@ async function start(options = {}) {
2088
2085
  }
2089
2086
  const seenEndpoints = /* @__PURE__ */ new Set();
2090
2087
  const duplicateConfigs = [];
2091
- for (const config of napcatConfigs) {
2092
- const { protocol = "ws", host = "localhost", port = 3001 } = config;
2088
+ for (let i = 0; i < napcatConfigs.length; i++) {
2089
+ const { protocol = "ws", host = "localhost", port = 3001 } = napcatConfigs[i];
2093
2090
  const endpoint = `${protocol}://${host}:${port}`;
2094
- if (seenEndpoints.has(endpoint)) duplicateConfigs.push(`${config.name || "未命名"} (${endpoint})`);
2091
+ if (seenEndpoints.has(endpoint)) duplicateConfigs.push(`Bot${i + 1} (${endpoint})`);
2095
2092
  else seenEndpoints.add(endpoint);
2096
2093
  }
2097
2094
  if (duplicateConfigs.length > 0) {
@@ -2109,7 +2106,7 @@ async function start(options = {}) {
2109
2106
  }
2110
2107
  for (const bot of bots) connectedBots.set(bot.bot_id, bot);
2111
2108
  if (bots.length < napcatConfigs.length) logger.warn(`${consola_utils.colors.yellow(napcatConfigs.length - bots.length)} 个 NapCat 实例连接失败`);
2112
- const botNames = bots.map((b) => `${b.name}(${b.bot_id})`).join(", ");
2109
+ const botNames = bots.map((b) => `${b.bot_id}`).join(", ");
2113
2110
  logger.info(consola_utils.colors.green(`成功连接 ${bots.length} 个实例: ${botNames}`));
2114
2111
  logger.info(consola_utils.colors.dim("=".repeat(40)));
2115
2112
  const mainBot = bots[0];