@karinjs/plugin-basic 1.0.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/README.md ADDED
@@ -0,0 +1,23 @@
1
+ ## 安装插件
2
+
3
+ ```bash
4
+ pnpm add @karinjs/plugin-basic -w
5
+ ```
6
+
7
+ ## 基本指令
8
+
9
+ ```
10
+ # 关机
11
+ ```
12
+
13
+ ```
14
+ # 重启
15
+ ```
16
+
17
+ ```
18
+ # 状态
19
+ ```
20
+
21
+ ```
22
+ # 插件列表
23
+ ```
@@ -0,0 +1,6 @@
1
+ {
2
+ "status": "是否统计状态 关闭后可降低redis压力...",
3
+ "forward": "全部更新是否使用转发",
4
+ "restartMode": "默认重启是否为前台重启 true为前台重启 false为后台重启",
5
+ "restart": "更新完成是否自动重启"
6
+ }
@@ -0,0 +1,11 @@
1
+ # 是否统计状态 关闭后可降低redis压力...
2
+ status: true
3
+
4
+ # 全部更新是否使用转发
5
+ forward: true
6
+
7
+ # 默认重启是否为前台重启 true为前台重启 false为后台重启
8
+ restartMode: true
9
+
10
+ # 更新完成是否自动重启
11
+ restart: true
@@ -0,0 +1 @@
1
+ export declare const exit: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
@@ -0,0 +1,6 @@
1
+ import { common, karin } from 'node-karin';
2
+ export const exit = karin.command(/^#关机$/, async (e) => {
3
+ await e.reply(`开始关机 本次运行时间: ${common.uptime()}`, { at: true });
4
+ process.emit('SIGINT');
5
+ return true;
6
+ }, { name: '关机', perm: 'admin' });
@@ -0,0 +1 @@
1
+ export declare const restarts: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
@@ -0,0 +1,16 @@
1
+ import { config } from '../utils/config.js';
2
+ import { common, karin, logger, restart } from 'node-karin';
3
+ export const restarts = karin.command(/^#重启$/, async (e) => {
4
+ try {
5
+ await e.reply(`开始重启 本次运行时间: ${common.uptime()}`, { at: true });
6
+ const { status, data } = await restart(e.selfId, e.contact, e.messageId, config().restartMode);
7
+ if (status === 'failed')
8
+ throw data;
9
+ return true;
10
+ }
11
+ catch (error) {
12
+ logger.error(error);
13
+ await e.reply(`重启失败: ${error.message || '未知原因'}`, { at: true });
14
+ return true;
15
+ }
16
+ }, { name: '重启', perm: 'admin' });
@@ -0,0 +1 @@
1
+ export declare const status: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
@@ -0,0 +1,70 @@
1
+ import moment from 'node-karin/moment';
2
+ import { config } from '../utils/config.js';
3
+ import { EVENT_COUNT, karin, RECV_MSG, redis, SEND_MSG } from 'node-karin';
4
+ export const status = karin.command(/^#状态$/, async (e) => {
5
+ const today = moment().format('YYYY-MM-DD');
6
+ const month = moment().format('YYYY-MM');
7
+ const [send, recv, event, sendMonth, recvMonth, eventMonth] = await Promise.all([
8
+ getStat(`${SEND_MSG}:${today}*`),
9
+ getStat(`${RECV_MSG}:${today}*`),
10
+ getStat(`${EVENT_COUNT}:${today}*`),
11
+ getStat(`${SEND_MSG}:${month}*`),
12
+ getStat(`${RECV_MSG}:${month}*`),
13
+ getStat(`${EVENT_COUNT}:${month}*`)
14
+ ]);
15
+ await e.reply([
16
+ '------机器人状态------',
17
+ `当前版本:v${process.env.karin_app_version}`,
18
+ `内存占用:${MB()}MB`,
19
+ `运行时间:${uptime()}`,
20
+ '------今日统计------',
21
+ `发送消息:${send}次`,
22
+ `插件触发:${event}次`,
23
+ `收到消息:${recv}次`,
24
+ '------本月统计------',
25
+ `发送消息:${sendMonth}次`,
26
+ `插件触发:${eventMonth}次`,
27
+ `收到消息:${recvMonth}次`
28
+ ].join('\n'));
29
+ return true;
30
+ }, { name: '状态统计' });
31
+ /**
32
+ * 生成存储键
33
+ * @param contact 联系人
34
+ * @example
35
+ * ```ts
36
+ * friend:<peer>
37
+ * group:<peer>
38
+ * guild:<peer>:<subPeer>
39
+ * direct:<peer>:<subPeer>
40
+ * ```
41
+ */
42
+ const createKey = (contact) => {
43
+ const { scene, peer, subPeer } = contact;
44
+ return `${moment().format('YYYY-MM-DD')}:${scene}:${peer}${subPeer ? `:${subPeer}` : ''}`;
45
+ };
46
+ /**
47
+ * 获取 Redis 键值统计
48
+ */
49
+ const getStat = async (pattern) => {
50
+ const keys = await redis.keys(pattern);
51
+ const values = await Promise.all(keys.map((key) => redis.get(key).then(Number)));
52
+ return values.reduce((total, value) => total + (value || 0), 0);
53
+ };
54
+ const MB = () => (process.memoryUsage().rss / 1024 / 1024).toFixed(2);
55
+ const uptime = () => {
56
+ const uptime = process.uptime();
57
+ const hour = Math.floor(uptime / 3600);
58
+ const minute = Math.floor((uptime % 3600) / 60);
59
+ return `${hour}小时${minute}分钟`;
60
+ };
61
+ (() => {
62
+ if (!config().status)
63
+ return;
64
+ karin.on(RECV_MSG, (contact) => redis.incr(`${RECV_MSG}:${createKey(contact)}`));
65
+ karin.on(SEND_MSG, (contact) => redis.incr(`${SEND_MSG}:${createKey(contact)}`));
66
+ karin.on(EVENT_COUNT, ({ plugin, event }) => {
67
+ const key = `${EVENT_COUNT}:${moment().format('YYYY-MM-DD')}:${plugin.file.basename}:${plugin.file.method}`;
68
+ redis.incr(key);
69
+ });
70
+ })();
@@ -0,0 +1,10 @@
1
+ /** 插件列表 */
2
+ export declare const plugins: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
3
+ /** 检查更新 */
4
+ export declare const check: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
5
+ /** 更新插件 */
6
+ export declare const update: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
7
+ /** 更新日志 */
8
+ export declare const log: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
9
+ /** 全部更新 */
10
+ export declare const updateAll: import("node-karin").Command<keyof import("node-karin").MessageEventMap>;
@@ -0,0 +1,214 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { changelog, checkGitPluginUpdate, checkPkgUpdate, getCommit, getPlugins, getPkgVersion, karin, updateAllGitPlugin, updateAllPkg, updateGitPlugin, updatePkg } from 'node-karin';
4
+ const cache = [];
5
+ const getAll = async () => {
6
+ if (cache.length)
7
+ return cache;
8
+ const git = await getPlugins('git', false);
9
+ const npm = await getPlugins('npm', false);
10
+ const list = [
11
+ 'npm:node-karin',
12
+ ...git.map(name => `git:${name}`),
13
+ ...npm.map(name => `npm:${name}`)
14
+ ];
15
+ cache.push(...list);
16
+ setTimeout(() => {
17
+ cache.length = 0;
18
+ }, 60000);
19
+ return list;
20
+ };
21
+ /** 插件列表 */
22
+ export const plugins = karin.command(/^#插件列表$/, async (e) => {
23
+ const list = await getAll();
24
+ list.forEach((item, index) => {
25
+ item += `${index + 1}. ${item}`;
26
+ });
27
+ await e.reply([
28
+ '\n插件列表:',
29
+ '更新:#更新插件 序号或名称',
30
+ '检查更新:#检查更新 序号或名称',
31
+ '日志:#更新日志 条数 序号或名称',
32
+ ...list,
33
+ ].join('\n'), { at: true });
34
+ return true;
35
+ }, { name: '插件列表', perm: 'admin' });
36
+ /** 检查更新 */
37
+ export const check = karin.command(/^#检查更新/, async (e) => {
38
+ let name = e.msg.replace(/^#检查更新/, '').trim();
39
+ /** 传入的是序号 */
40
+ const index = Number(name);
41
+ if (index && typeof index === 'number') {
42
+ const list = await getAll();
43
+ name = list[index - 1];
44
+ }
45
+ if (!name) {
46
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
47
+ return true;
48
+ }
49
+ const tips = '当前版本已是最新版本';
50
+ if (name.includes('git:')) {
51
+ name = name.replace('git:', '');
52
+ const file = path.join(process.cwd(), 'plugins', name.replace('git:', ''));
53
+ const result = await checkGitPluginUpdate(file);
54
+ if (result.status === 'error') {
55
+ const { data } = result;
56
+ const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
57
+ await e.reply(msg, { at: true });
58
+ return true;
59
+ }
60
+ if (result.status === 'no') {
61
+ await e.reply(`\n${tips}${result.data.replace(tips + '\n', '')}`, { at: true });
62
+ return true;
63
+ }
64
+ await e.reply([
65
+ '\n存在新版本:',
66
+ `名称:${name}`,
67
+ `落后: ${result.count}次提交`,
68
+ `更新日志:\n${result.data}`,
69
+ ].join('\n'), { at: true });
70
+ return true;
71
+ }
72
+ if (name.includes('npm:')) {
73
+ name = name.replace('npm:', '');
74
+ const result = await checkPkgUpdate(name);
75
+ if (result.status === 'no') {
76
+ await e.reply(`\n当前版本: ${result.local}\n${tips}`, { at: true });
77
+ return true;
78
+ }
79
+ if (result.status === 'error') {
80
+ const { error } = result;
81
+ const msg = `获取更新信息失败: ${error.message || '未知错误'}`;
82
+ await e.reply(msg, { at: true });
83
+ return true;
84
+ }
85
+ await e.reply([
86
+ '\n存在新版本:',
87
+ `名称:${name}`,
88
+ `当前版本: ${result.local}`,
89
+ `最新版本: ${result.remote}`,
90
+ ].join('\n'), { at: true });
91
+ return true;
92
+ }
93
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
94
+ return true;
95
+ }, { name: '检查更新', perm: 'admin' });
96
+ /** 更新插件 */
97
+ export const update = karin.command(/^#(强制)?更新(插件)?(?!列表|日志)/, async (e) => {
98
+ let name = e.msg.replace(/^#(强制)?更新(插件)?(?!列表|日志)/, '').trim();
99
+ /** 传入的是序号 */
100
+ const index = Number(name);
101
+ if (index && typeof index === 'number') {
102
+ const list = await getAll();
103
+ name = list[index - 1];
104
+ }
105
+ if (!name) {
106
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
107
+ return true;
108
+ }
109
+ if (name.includes('git:')) {
110
+ name = name.replace('git:', '');
111
+ const file = path.join(process.cwd(), 'plugins', name.replace('git:', ''));
112
+ let cmd = 'git pull';
113
+ if (e.msg.includes('强制'))
114
+ cmd = 'git reset --hard && git pull --allow-unrelated-histories';
115
+ const result = await updateGitPlugin(file, cmd, 120);
116
+ if (result.status === 'failed') {
117
+ const { data } = result;
118
+ const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
119
+ await e.reply(msg, { at: true });
120
+ return true;
121
+ }
122
+ await e.reply(`\n${result.data}`, { at: true });
123
+ return true;
124
+ }
125
+ if (name.includes('npm:')) {
126
+ name = name.replace('npm:', '');
127
+ const result = await updatePkg(name);
128
+ if (result.status === 'failed') {
129
+ const { data } = result;
130
+ const msg = typeof data === 'string' ? data : `获取更新信息失败: ${data.message || '未知错误'}`;
131
+ await e.reply(`\n${msg}`, { at: true });
132
+ return true;
133
+ }
134
+ const log = parseLog(name, result.local, result.remote);
135
+ await e.reply(`\n更新成功\n当前版本: ${result.remote}\n更新日志: \n${log}`, { at: true });
136
+ return true;
137
+ }
138
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
139
+ return true;
140
+ }, { name: '更新插件', perm: 'admin' });
141
+ /** 更新日志 */
142
+ export const log = karin.command(/^#更新日志/, async (e) => {
143
+ // 更新日志 npm:node-karin 10
144
+ const [index, num] = e.msg.replace(/^#更新日志/, '').trim().split(' ');
145
+ if (!index || !num) {
146
+ await e.reply('\n请输入正确的命令 #更新日志 <序号或插件名称> [日志数量]', { at: true });
147
+ return true;
148
+ }
149
+ const count = Number(num) || 10;
150
+ let name = index;
151
+ if (Number(index)) {
152
+ const list = await getAll();
153
+ name = list[Number(index) - 1];
154
+ }
155
+ if (!name) {
156
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
157
+ return true;
158
+ }
159
+ if (name.includes('npm:')) {
160
+ name = name.replace('npm:', '');
161
+ const local = await getPkgVersion(name);
162
+ if (!local) {
163
+ await e.reply('获取插件版本失败,请检查是否存在此插件', { at: true });
164
+ }
165
+ else {
166
+ const result = parseLog(name, local, count);
167
+ await e.reply(`\n${result}`, { at: true });
168
+ }
169
+ return true;
170
+ }
171
+ if (name.includes('git:')) {
172
+ name = name.replace('git:', '');
173
+ const file = path.join(process.cwd(), 'plugins', name);
174
+ const result = await getCommit({ path: file, count });
175
+ await e.reply(`\n${result}`, { at: true });
176
+ return true;
177
+ }
178
+ await e.reply('\n请输入正确的插件名称或序号~', { at: true });
179
+ return true;
180
+ }, { name: '更新日志', perm: 'admin' });
181
+ /** 全部更新 */
182
+ export const updateAll = karin.command(/^#全部(强制)?更新$/, async (e) => {
183
+ const cmd = e.msg.includes('强制') ? 'git reset --hard && git pull --allow-unrelated-histories' : 'git pull';
184
+ try {
185
+ const git = await updateAllGitPlugin(cmd);
186
+ const npm = await updateAllPkg();
187
+ await e.reply([
188
+ '\n全部更新完成',
189
+ '-----',
190
+ git,
191
+ '-----',
192
+ npm,
193
+ ].join('\n'), { at: true });
194
+ }
195
+ catch (error) {
196
+ await e.reply(`\n全部更新失败: ${error.message || '未知错误'}`, { at: true });
197
+ }
198
+ return true;
199
+ }, { name: '全部更新', perm: 'admin' });
200
+ /**
201
+ * @param pkg npm包名
202
+ * @param local 本地版本
203
+ * @param count 提取的日志数量 或 版本号
204
+ */
205
+ const parseLog = (pkg, local, count) => {
206
+ const file = path.join(process.cwd(), 'node_modules', pkg, 'CHANGELOG.md');
207
+ if (!fs.existsSync(file))
208
+ return '插件未提供`CHANGELOG.md`文件';
209
+ const data = fs.readFileSync(file, 'utf-8');
210
+ if (typeof count === 'number') {
211
+ return changelog.logs(data, local, count) || '未找到对应的更新日志';
212
+ }
213
+ return changelog.range(data, local, count) || '未找到对应的更新日志';
214
+ };
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/lib/cli/pr.js ADDED
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'fs';
3
+ /**
4
+ * @description 获取package.json路径
5
+ */
6
+ const getPkgPath = () => process.cwd() + '/package.json';
7
+ /**
8
+ * @description 读取package.json
9
+ */
10
+ const readPkg = () => JSON.parse(fs.readFileSync(getPkgPath(), 'utf-8'));
11
+ /**
12
+ * @description 写入package.json
13
+ * @param pkg package.json
14
+ */
15
+ const writePkg = (pkg) => fs.writeFileSync(getPkgPath(), JSON.stringify(pkg, null, 2));
16
+ /**
17
+ * @description 构建pr版本号 <主版本号>.<次版本号>.<修订号>-<预发布标识>.<PR标识>.<PR编号>.<工作流唯一编号>-<时间戳>
18
+
19
+ * @param pkg package.json
20
+ */
21
+ const updateVersion = (pkg) => {
22
+ const list = pkg.version.split('.');
23
+ // 1.0.0 => 1.0.1-beta.pr.pr编号.工作流唯一编号-时间戳 => 1.0.1-beta.pr.184-1631537630
24
+ const timestamp = Math.floor(Date.now() / 1000);
25
+ list[2] = `${Number(list[2]) + 1}-beta.pr.${process.env.PR_NUMBER}.${process.env.GITHUB_RUN_ATTEMPT || 1}-${timestamp}`;
26
+ pkg.version = list.join('.');
27
+ };
28
+ /**
29
+ * @description 设置环境变量
30
+ * @param pkg package.json
31
+ */
32
+ const setEnvVariables = (pkg) => {
33
+ fs.appendFileSync(process.env.GITHUB_ENV, `PKG_NAME=${pkg.name}\nPKG_VERSION=${pkg.version}\n`);
34
+ };
35
+ /**
36
+ * @description 更新版本号并设置环境变量
37
+ */
38
+ const version = () => {
39
+ const pkg = readPkg();
40
+ updateVersion(pkg);
41
+ writePkg(pkg);
42
+ setEnvVariables(pkg);
43
+ };
44
+ /**
45
+ * @description 删除devDependencies和peerDependencies
46
+ */
47
+ const clean = () => {
48
+ const pkg = readPkg();
49
+ delete pkg.devDependencies;
50
+ delete pkg.peerDependencies;
51
+ writePkg(pkg);
52
+ };
53
+ /**
54
+ * @description 执行所有操作
55
+ */
56
+ const all = () => {
57
+ const pkg = readPkg();
58
+ updateVersion(pkg);
59
+ delete pkg.devDependencies;
60
+ delete pkg.peerDependencies;
61
+ writePkg(pkg);
62
+ setEnvVariables(pkg);
63
+ };
64
+ const cmd = process.argv[2];
65
+ if (cmd === 'version') {
66
+ version();
67
+ }
68
+ else if (cmd === 'clean') {
69
+ clean();
70
+ }
71
+ else if (cmd === 'all') {
72
+ all();
73
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { logger } from 'node-karin';
2
+ import { basename, config } from './utils/index.js';
3
+ /** 请不要在这编写插件 不会有任何效果~ */
4
+ logger.info(`${logger.violet(`[插件:${config.pkg().version}]`)} ${logger.green(basename)} 初始化完成~`);
@@ -0,0 +1,11 @@
1
+ /** `config.yaml` 文件的类型定义 */
2
+ export type Config = {
3
+ /** 是否统计状态 关闭后可降低redis压力 */
4
+ status: boolean;
5
+ /** 全部更新是否使用转发 */
6
+ forward: boolean;
7
+ /** 默认重启是否为前台重启 true为前台重启 false为后台重启 */
8
+ restartMode: boolean;
9
+ /** 更新完成是否自动重启 */
10
+ restart: boolean;
11
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { Config } from '../types/config.js';
2
+ /**
3
+ * @description package.json
4
+ */
5
+ export declare const pkg: () => any;
6
+ /**
7
+ * @description 配置文件
8
+ */
9
+ export declare const config: () => Config;
@@ -0,0 +1,38 @@
1
+ import { dirPath } from '../utils/index.js';
2
+ import { watch, basePath, filesByExt, copyConfigSync, requireFileSync, } from 'node-karin';
3
+ let cache;
4
+ /**
5
+ * @description package.json
6
+ */
7
+ export const pkg = () => requireFileSync(`${dirPath}/package.json`);
8
+ /** 用户配置的插件名称 */
9
+ const pluginName = pkg().name.replace(/\//g, '-');
10
+ /** 用户配置 */
11
+ const dirConfig = `${basePath}/${pluginName}/config`;
12
+ /** 默认配置 */
13
+ const defConfig = `${dirPath}/config/config`;
14
+ /**
15
+ * @description 初始化配置文件
16
+ */
17
+ copyConfigSync(defConfig, dirConfig, ['.yaml']);
18
+ /**
19
+ * @description 配置文件
20
+ */
21
+ export const config = () => {
22
+ if (cache)
23
+ return cache;
24
+ const user = requireFileSync(`${dirConfig}/config.yaml`);
25
+ const def = requireFileSync(`${defConfig}/config.yaml`);
26
+ const result = { ...def, ...user };
27
+ cache = result;
28
+ return result;
29
+ };
30
+ /**
31
+ * @description 监听配置文件
32
+ */
33
+ setTimeout(() => {
34
+ const list = filesByExt(dirConfig, '.yaml', 'abs');
35
+ list.forEach(file => watch(file, (old, now) => {
36
+ cache = undefined;
37
+ }));
38
+ }, 2000);
@@ -0,0 +1,5 @@
1
+ /** 插件包绝对路径 */
2
+ declare const dirPath: string;
3
+ /** 插件包的名称 */
4
+ declare const basename: string;
5
+ export { dirPath, basename };
@@ -0,0 +1,9 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ /** 当前文件的绝对路径 */
4
+ const filePath = fileURLToPath(import.meta.url).replace(/\\/g, '/');
5
+ /** 插件包绝对路径 */
6
+ const dirPath = path.resolve(filePath, '../../../');
7
+ /** 插件包的名称 */
8
+ const basename = path.basename(dirPath);
9
+ export { dirPath, basename };
@@ -0,0 +1,3 @@
1
+ export * from './dir.js';
2
+ export * from './config.js';
3
+ export * as config from './config.js';
@@ -0,0 +1,3 @@
1
+ export * from './dir.js';
2
+ export * from './config.js';
3
+ export * as config from './config.js';
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@karinjs/plugin-basic",
3
+ "version": "1.0.1",
4
+ "description": "karin plugin for basic functions",
5
+ "homepage": "https://github.com/KarinJS/karin-plugin-basic",
6
+ "bugs": {
7
+ "url": "https://github.com/KarinJS/karin-plugin-basic/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/KarinJS/karin-plugin-basic.git"
12
+ },
13
+ "author": "shijin",
14
+ "type": "module",
15
+ "main": "lib/index.js",
16
+ "files": [
17
+ "/lib/**/*.js",
18
+ "/lib/**/*.d.ts",
19
+ "config",
20
+ "resources",
21
+ "LICENSE",
22
+ "package.json",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
27
+ "pr": "node lib/cli/pr.js",
28
+ "pub": "npm publish --access public",
29
+ "sort": "npx sort-package-json",
30
+ "dev": "tsx watch --include \"src/**/*.ts\" ./node_modules/node-karin/dist/index.js",
31
+ "karin": "karin"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "registry": "https://registry.npmjs.org"
36
+ },
37
+ "karin": {
38
+ "main": "src/index.ts",
39
+ "apps": [
40
+ "lib/apps"
41
+ ],
42
+ "ts-apps": [
43
+ "src/apps"
44
+ ],
45
+ "static": [
46
+ "resources"
47
+ ],
48
+ "files": [
49
+ "config",
50
+ "data",
51
+ "resources"
52
+ ],
53
+ "include": [
54
+ "src/**/*"
55
+ ],
56
+ "exclude": [
57
+ "lib/**/*",
58
+ "@karinjs/**/*"
59
+ ]
60
+ }
61
+ }