node-karin 0.6.26 → 0.6.28

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.
@@ -103,8 +103,9 @@ declare class PluginLoader {
103
103
  * @param name - 插件名称
104
104
  * @param isOrderBy - 是否为动态导入 默认为静态导入
105
105
  * @param isNpm - 是否为npm包
106
+ * @param isMain - 是否为主入口文件
106
107
  */
107
- createdApp(dir: dirName, name: fileName, isOrderBy?: boolean, isNpm?: boolean): Promise<boolean>;
108
+ createdApp(dir: dirName, name: fileName, isOrderBy?: boolean, isNpm?: boolean, isMain?: boolean): Promise<boolean>;
108
109
  /**
109
110
  * 新增rule
110
111
  */
@@ -98,7 +98,7 @@ class PluginLoader {
98
98
  /** 获取npm插件 */
99
99
  const npm = await common.getNpmPlugins(true)
100
100
  /** 载入npm插件 */
101
- promises.push(...npm.map(async ({ dir, name }) => await this.createdApp(dir, name, false, true)))
101
+ promises.push(...npm.map(async ({ dir, name, isMain }) => await this.createdApp(dir, name, false, true, isMain)))
102
102
  /** 等待所有插件加载完成 */
103
103
  await Promise.all(promises)
104
104
  /** 释放缓存 */
@@ -252,13 +252,16 @@ class PluginLoader {
252
252
  * @param name - 插件名称
253
253
  * @param isOrderBy - 是否为动态导入 默认为静态导入
254
254
  * @param isNpm - 是否为npm包
255
+ * @param isMain - 是否为主入口文件
255
256
  */
256
- async createdApp (dir, name, isOrderBy = false, isNpm = false) {
257
+ async createdApp (dir, name, isOrderBy = false, isNpm = false, isMain = false) {
257
258
  try {
258
259
  const list = []
259
260
  let path = `${this.dirPath}${isNpm ? 'node_modules' : 'plugins'}/${dir}/${name}`
260
261
  if (isOrderBy) { path = path + `?${Date.now()}` }
261
262
  const tmp = await import(path)
263
+ /** npm包的入口文件不作为app载入 只加载 */
264
+ if (isMain) { return true }
262
265
  lodash.forEach(tmp, (App) => {
263
266
  const index = this.index
264
267
  this.index++
package/lib/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export declare const Cfg: {
37
37
  review: boolean;
38
38
  logger: import("log4js").Logger;
39
39
  initCfg(): Promise<void>;
40
- getPlugins(): string[];
40
+ getPlugins(): Promise<string[]>;
41
41
  mkdir(dirname: string): boolean;
42
42
  dirPath(_path: string, plugins: string[]): Promise<void>;
43
43
  timeout(type?: "ws" | "grpc"): number;
@@ -148,6 +148,7 @@ export declare const common: {
148
148
  getNpmPlugins<T extends boolean>(showDetails: T): Promise<T extends true ? {
149
149
  dir: string;
150
150
  name: fileName;
151
+ isMain: boolean;
151
152
  }[] : string[]>;
152
153
  /**
153
154
  * 获取运行时间
@@ -406,7 +406,17 @@ export const common = new (class Common {
406
406
  const pkg = JSON.parse(fs.readFileSync('./package.json', 'utf8'))
407
407
  const dependencies = Object.keys(pkg.dependencies).filter((name) => !pkgdependencies.includes(name))
408
408
  if (!showDetails) {
409
- return dependencies
409
+ const list = []
410
+ // 检查pkg是否存在karin字段
411
+ const readPackageJson = async (name) => {
412
+ try {
413
+ const pkgPath = path.join(process.cwd(), 'node_modules', name, 'package.json')
414
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
415
+ if (pkg?.karin) { list.push(name) }
416
+ } catch { }
417
+ }
418
+ await Promise.all(dependencies.map(readPackageJson))
419
+ return list
410
420
  } else {
411
421
  const list = []
412
422
  const readPackageJson = async (name) => {
@@ -416,7 +426,7 @@ export const common = new (class Common {
416
426
  if (pkg?.karin) {
417
427
  if (pkg?.main) {
418
428
  const dir = `${name}/${path.dirname(pkg.main).replace(/\.\//, '')}`
419
- list.push({ dir, name: path.basename(pkg.main) })
429
+ list.push({ dir, name: path.basename(pkg.main), isMain: true })
420
430
  }
421
431
  if (pkg?.karin?.apps?.length) {
422
432
  pkg.karin.apps.forEach((app) => {
@@ -424,7 +434,7 @@ export const common = new (class Common {
424
434
  /** 忽略非js */
425
435
  if (!name.endsWith('.js')) { return }
426
436
  const dir = `${name}/${app}`
427
- list.push({ dir, name })
437
+ list.push({ dir, name, isMain: false })
428
438
  })
429
439
  })
430
440
  }
@@ -26,7 +26,7 @@ export declare const config: {
26
26
  logger: Logger;
27
27
  /** 初始化配置 */
28
28
  initCfg(): Promise<void>;
29
- getPlugins(): string[];
29
+ getPlugins(): Promise<string[]>;
30
30
  /**
31
31
  * 递归创建目录
32
32
  * @param dirname - 要创建的文件夹路径
@@ -1,6 +1,7 @@
1
1
  import path from 'path'
2
2
  import { karinDir } from '../core/dir.js'
3
3
  import { fs, yaml as Yaml, chokidar } from '../modules.js'
4
+ import { common } from './common.js'
4
5
  /**
5
6
  * 配置文件
6
7
  */
@@ -57,7 +58,7 @@ export const config = new (class Cfg {
57
58
  })
58
59
  }
59
60
  /** 为每个插件包创建统一存储的文件夹 */
60
- const plugins = this.getPlugins()
61
+ const plugins = await this.getPlugins()
61
62
  const DataList = [
62
63
  'data',
63
64
  'temp',
@@ -69,10 +70,14 @@ export const config = new (class Cfg {
69
70
  this.logger = (await import('./logger.js')).default
70
71
  }
71
72
 
72
- getPlugins () {
73
+ async getPlugins () {
74
+ const list = []
73
75
  const files = fs.readdirSync('./plugins', { withFileTypes: true })
74
76
  // 过滤掉非karin-plugin-开头的文件夹
75
- return files.filter(file => file.isDirectory() && (file.name.startsWith('karin-plugin-'))).map(dir => dir.name)
77
+ list.push(...files.filter(file => file.isDirectory() && (file.name.startsWith('karin-plugin-'))).map(dir => dir.name))
78
+ // 获取npm插件
79
+ list.push(...(await common.getNpmPlugins(false)))
80
+ return list
76
81
  }
77
82
 
78
83
  /**
@@ -1,60 +1,85 @@
1
1
  import Yaml from 'yaml';
2
+ export type YamlValue = string | boolean | number | object | any[];
2
3
  export declare class YamlEditor {
3
4
  filePath: string;
4
5
  document: Yaml.Document;
5
- constructor(filePath: string);
6
- load(): void;
6
+ constructor(file: string);
7
7
  /**
8
8
  * 获取指定路径的值
9
- * @param path - 路径,用点号分隔,例如:'a.b.c'
9
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
10
10
  */
11
11
  get(path: string): any;
12
12
  /**
13
13
  * 设置指定路径的值
14
- * @param path - 路径,用点号分隔,例如:'a.b.c'
15
- * @param value - 要设置的值
14
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
15
+ * @param value - 要设置的值 允许的类型:`string`, `boolean`, `number`, `object`, `array`
16
16
  */
17
- set(path: string | string[], value: string | boolean): null | undefined;
17
+ set(path: string, value: YamlValue): null | undefined;
18
18
  /**
19
19
  * 向指定路径添加新值
20
- * @param path - 路径,用点号分隔,例如:'a.b.c'
20
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
21
21
  * @param value - 要添加的值
22
22
  */
23
- add(path: string | string[], value: string): void;
23
+ add(path: string, value: YamlValue): void;
24
24
  /**
25
25
  * 删除指定路径
26
- * @param path - 路径,用点号分隔,例如:'a.b.c'
26
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
27
27
  * @returns 是否删除成功
28
28
  */
29
- del(path: string | string[]): boolean;
29
+ del(path: string): boolean;
30
30
  /**
31
31
  * 向指定路径的数组添加新值,可以选择添加到数组的开始或结束
32
- * @param path - 路径,用点号分隔,例如:'a.b.c'
32
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
33
33
  * @param value - 要添加的值
34
34
  * @param prepend - 如果为 true,则添加到数组的开头,否则添加到末尾
35
35
  */
36
- append(path: string | string[], value: string, prepend?: boolean): void;
36
+ append(path: string, value: string, prepend?: boolean): void;
37
37
  /**
38
38
  * 检查指定路径的键是否存在
39
39
  * @param path - 路径,用点号分隔
40
40
  */
41
- has(path: string | string[]): boolean;
41
+ has(path: string): boolean;
42
42
  /**
43
43
  * 查询指定路径中是否包含指定的值
44
44
  * @param path - 路径,用点号分隔
45
45
  * @param value - 要查询的值
46
46
  */
47
- hasVal(path: string | string[], value: any): boolean;
47
+ hasval(path: string, value: YamlValue): boolean;
48
+ /**
49
+ * 查询指定路径中是否包含指定的值
50
+ * @param path - 路径,用点号分隔
51
+ * @param value - 要查询的值
52
+ * @deprecated 请使用 `hasval` 代替
53
+ */
54
+ hasVal(path: string, value: YamlValue): boolean;
48
55
  /**
49
56
  * 向根节点新增元素,如果根节点不是数组,则将其转换为数组再新增元素
50
57
  * @param value - 要新增的元素
51
58
  */
52
- pusharr(value: any): false | undefined;
59
+ pusharr(value: YamlValue): false | undefined;
53
60
  /**
54
61
  * 根据索引从根节点数组删除元素
55
62
  * @param index - 要删除元素的索引
56
63
  */
57
64
  delarr(index: number): boolean;
65
+ /**
66
+ * 获取指定路径的pair对象
67
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
68
+ */
69
+ getpair(path: string): any;
70
+ /**
71
+ * 设置指定键的注释
72
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
73
+ * @param comment - 要设置的注释
74
+ * @param prepend - 如果为 true,则添加到注释的开头,否则添加到同一行的末尾
75
+ */
76
+ comment(path: string, comment: string, prepend?: boolean): void;
77
+ /**
78
+ * 删除指定键的注释
79
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
80
+ * @param type - 要删除的注释类型,`before` 为注释前,`after` 为注释后,`all` 为全部
81
+ */
82
+ uncomment(path: string, type?: 'before' | 'after' | 'all'): void;
58
83
  /**
59
84
  * 保存文件
60
85
  */
@@ -4,30 +4,20 @@
4
4
  * https://github.com/OpenAI
5
5
  */
6
6
  import fs from 'fs'
7
- import Yaml from 'yaml'
8
7
  import lodash from 'lodash'
9
8
  import logger from './logger.js'
9
+ import Yaml, { isMap, isSeq, isPair } from 'yaml'
10
10
  export class YamlEditor {
11
11
  filePath
12
12
  document
13
- constructor (filePath) {
14
- this.filePath = filePath
15
- this.load()
16
- }
17
-
18
- load () {
19
- try {
20
- const fileContents = fs.readFileSync(this.filePath, 'utf8')
21
- this.document = Yaml.parseDocument(fileContents)
22
- logger.debug('[YamlEditor] 文件加载成功')
23
- } catch (error) {
24
- logger.error(`[YamlEditor] 加载文件时出错:${error}`)
25
- }
13
+ constructor (file) {
14
+ this.filePath = file
15
+ this.document = Yaml.parseDocument(fs.readFileSync(file, 'utf8'))
26
16
  }
27
17
 
28
18
  /**
29
19
  * 获取指定路径的值
30
- * @param path - 路径,用点号分隔,例如:'a.b.c'
20
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
31
21
  */
32
22
  get (path) {
33
23
  try {
@@ -41,13 +31,13 @@ export class YamlEditor {
41
31
 
42
32
  /**
43
33
  * 设置指定路径的值
44
- * @param path - 路径,用点号分隔,例如:'a.b.c'
45
- * @param value - 要设置的值
34
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
35
+ * @param value - 要设置的值 允许的类型:`string`, `boolean`, `number`, `object`, `array`
46
36
  */
47
37
  set (path, value) {
48
38
  try {
49
- path = typeof path === 'string' ? path.split('.') : path
50
- this.document.setIn(path, value)
39
+ const _path = typeof path === 'string' ? path.split('.') : path
40
+ this.document.setIn(_path, value)
51
41
  } catch (error) {
52
42
  logger.error(`[YamlEditor] 设置数据时出错:${error}`)
53
43
  return null
@@ -56,13 +46,13 @@ export class YamlEditor {
56
46
 
57
47
  /**
58
48
  * 向指定路径添加新值
59
- * @param path - 路径,用点号分隔,例如:'a.b.c'
49
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
60
50
  * @param value - 要添加的值
61
51
  */
62
52
  add (path, value) {
63
53
  try {
64
- path = typeof path === 'string' ? path.split('.') : path
65
- this.document.addIn(path, value)
54
+ const _path = typeof path === 'string' ? path.split('.') : path
55
+ this.document.addIn(_path, value)
66
56
  logger.debug(`[YamlEditor] 已在 ${path} 添加新的值`)
67
57
  } catch (error) {
68
58
  logger.error(`[YamlEditor] 添加数据时出错:${error}`)
@@ -71,13 +61,13 @@ export class YamlEditor {
71
61
 
72
62
  /**
73
63
  * 删除指定路径
74
- * @param path - 路径,用点号分隔,例如:'a.b.c'
64
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
75
65
  * @returns 是否删除成功
76
66
  */
77
67
  del (path) {
78
68
  try {
79
- path = typeof path === 'string' ? path.split('.') : path
80
- this.document.deleteIn(path)
69
+ const _path = typeof path === 'string' ? path.split('.') : path
70
+ this.document.deleteIn(_path)
81
71
  return true
82
72
  } catch (error) {
83
73
  logger.error(`[YamlEditor] 删除数据时出错:${error}`)
@@ -87,25 +77,21 @@ export class YamlEditor {
87
77
 
88
78
  /**
89
79
  * 向指定路径的数组添加新值,可以选择添加到数组的开始或结束
90
- * @param path - 路径,用点号分隔,例如:'a.b.c'
80
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
91
81
  * @param value - 要添加的值
92
82
  * @param prepend - 如果为 true,则添加到数组的开头,否则添加到末尾
93
83
  */
94
84
  append (path, value, prepend = false) {
95
85
  try {
96
- path = typeof path === 'string' ? path.split('.') : path || []
97
- let current = this.document.getIn(path)
86
+ const _path = typeof path === 'string' ? path.split('.') : path || []
87
+ let current = this.document.getIn(_path)
98
88
  if (!current) {
99
89
  current = new Yaml.YAMLSeq()
100
- this.document.setIn(path, current)
90
+ this.document.setIn(_path, current)
101
91
  } else if (!(current instanceof Yaml.YAMLSeq)) {
102
92
  throw new Error('[YamlEditor] 指定的路径不是数组')
103
93
  } else {
104
- if (prepend) {
105
- current.items.unshift(value)
106
- } else {
107
- current.add(value)
108
- }
94
+ prepend ? current.items.unshift(value) : current.add(value)
109
95
  }
110
96
  logger.debug(`[YamlEditor] 已向 ${path} 数组${prepend ? '开头' : '末尾'}添加新元素:${value}`)
111
97
  } catch (error) {
@@ -119,8 +105,8 @@ export class YamlEditor {
119
105
  */
120
106
  has (path) {
121
107
  try {
122
- path = typeof path === 'string' ? path.split('.') : path
123
- return this.document.hasIn(path)
108
+ const _path = typeof path === 'string' ? path.split('.') : path
109
+ return this.document.hasIn(_path)
124
110
  } catch (error) {
125
111
  logger.error(`[YamlEditor] 检查路径是否存在时出错:${error}`)
126
112
  return false
@@ -132,10 +118,10 @@ export class YamlEditor {
132
118
  * @param path - 路径,用点号分隔
133
119
  * @param value - 要查询的值
134
120
  */
135
- hasVal (path, value) {
121
+ hasval (path, value) {
136
122
  try {
137
- path = typeof path === 'string' ? path.split('.') : path
138
- const current = this.document.getIn(path)
123
+ const _path = typeof path === 'string' ? path.split('.') : path
124
+ const current = this.document.getIn(_path)
139
125
  if (!current) { return false }
140
126
  /** 检查当前节点是否包含指定的值 */
141
127
  if (current instanceof Yaml.YAMLSeq) {
@@ -154,6 +140,16 @@ export class YamlEditor {
154
140
  }
155
141
  }
156
142
 
143
+ /**
144
+ * 查询指定路径中是否包含指定的值
145
+ * @param path - 路径,用点号分隔
146
+ * @param value - 要查询的值
147
+ * @deprecated 请使用 `hasval` 代替
148
+ */
149
+ hasVal (path, value) {
150
+ return this.hasval(path, value)
151
+ }
152
+
157
153
  /**
158
154
  * 向根节点新增元素,如果根节点不是数组,则将其转换为数组再新增元素
159
155
  * @param value - 要新增的元素
@@ -194,6 +190,63 @@ export class YamlEditor {
194
190
  }
195
191
  }
196
192
 
193
+ /**
194
+ * 获取指定路径的pair对象
195
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
196
+ */
197
+ getpair (path) {
198
+ if (!path) { throw new Error('path is required') }
199
+ const keys = path.split('.')
200
+ // 好多any啊,我要当any糕手~
201
+ let pair = this.document.contents
202
+ keys.forEach(key => {
203
+ if (isMap(pair)) {
204
+ pair = pair.items.find((item) => item.key.value === key)
205
+ } else if (isSeq(pair)) {
206
+ pair = pair.items.find((item) => item.value === key)
207
+ } else if (isPair(pair)) {
208
+ pair = pair.value.items.find((item) => item.key.value === key)
209
+ }
210
+ })
211
+ return pair
212
+ }
213
+
214
+ /**
215
+ * 设置指定键的注释
216
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
217
+ * @param comment - 要设置的注释
218
+ * @param prepend - 如果为 true,则添加到注释的开头,否则添加到同一行的末尾
219
+ */
220
+ comment (path, comment, prepend = false) {
221
+ if (!path) { throw new Error('[YamlEditor] path 不能为空') }
222
+ const pair = this.getpair(path)
223
+ if (!pair) { throw new Error(`[YamlEditor] 未找到节点 ${path}`) }
224
+ if (prepend) {
225
+ pair.key.commentBefore = comment
226
+ } else {
227
+ pair.key.comment = comment
228
+ }
229
+ }
230
+
231
+ /**
232
+ * 删除指定键的注释
233
+ * @param path - 路径,多个路径使用`.`连接,例如:`a.b.c`
234
+ * @param type - 要删除的注释类型,`before` 为注释前,`after` 为注释后,`all` 为全部
235
+ */
236
+ uncomment (path, type = 'all') {
237
+ if (!path) { throw new Error('[YamlEditor] path 不能为空') }
238
+ const pair = this.getpair(path)
239
+ if (!pair) { throw new Error(`[YamlEditor] 未找到节点 ${path}`) }
240
+ if (type === 'all') {
241
+ delete pair.key.comment
242
+ delete pair.key.commentBefore
243
+ } else if (type === 'before') {
244
+ delete pair.key.commentBefore
245
+ } else if (type === 'after') {
246
+ delete pair.key.comment
247
+ }
248
+ }
249
+
197
250
  /**
198
251
  * 保存文件
199
252
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-karin",
3
- "version": "0.6.26",
3
+ "version": "0.6.28",
4
4
  "private": false,
5
5
  "description": "基于 Kritor 进行开发的nodejs机器人框架",
6
6
  "homepage": "https://github.com/KarinJS/Karin",