karin-plugin-mys-core 1.0.22 → 1.0.24

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 CHANGED
@@ -19,6 +19,45 @@
19
19
 
20
20
  - 本插件已加入插件商店,可在插件商店中一键下载安装。
21
21
 
22
+ ```bash
23
+ # 或使用 npm 安装
24
+ npm add karin-plugin-mys-core -w
25
+ ```
26
+
27
+ ---
28
+
29
+ ## 快速开始
30
+
31
+ ```typescript
32
+ import { Config } from 'karin-plugin-mys-core/config'
33
+ import { Database, DatabaseType } from 'karin-plugin-mys-core/database'
34
+ import { ReactRender, React } from 'karin-plugin-mys-core/render'
35
+
36
+ // 1. 配置管理
37
+ const config = new Config('my-plugin:config', './config', {
38
+ enable: true,
39
+ users: []
40
+ }, {})
41
+
42
+ // 2. 数据库操作
43
+ const db = Database.get()
44
+ await db.init('./data', 'users', [
45
+ Database.PkColumn('userId', 'STRING'),
46
+ Database.Column('nickname', 'STRING', '')
47
+ ], {}, DatabaseType.Db)
48
+
49
+ // 3. 渲染组件
50
+ const render = new ReactRender({
51
+ name: 'my-plugin',
52
+ version: '1.0.0',
53
+ pluginDir: __dirname,
54
+ ResourcesDir: path.join(__dirname, '../resources')
55
+ })
56
+
57
+ const Card = ({ text }) => <div className="card">{text}</div>
58
+ const image = await render.template('card', Card, { text: 'Hello' })
59
+ ```
60
+
22
61
  ---
23
62
 
24
63
  ## 游戏模块
@@ -45,28 +84,48 @@ import { Config } from 'karin-plugin-mys-core/config'
45
84
 
46
85
  用于管理 JSON 配置文件,支持自动补全、类型安全和实时监听。
47
86
 
87
+ **特性**
88
+
89
+ - ✅ 自动补全缺失的配置项
90
+ - ✅ 自动过滤未定义的配置项
91
+ - ✅ 支持深层嵌套路径访问
92
+ - ✅ 文件变更自动监听
93
+ - ✅ 类型安全的 TypeScript 支持
94
+
48
95
  **构造函数**
49
96
 
50
97
  ```typescript
51
98
  const config = new Config<ConfigType>(
52
- 'plugin-name:config-name', // 配置名称
53
- '/path/to/config.json', // 配置文件路径
54
- defaultConfig, // 默认配置对象
55
- defineConfig // 配置定义对象
99
+ 'plugin-name:config-name', // 配置名称(格式:插件名:配置名)
100
+ '/path/to/config', // 配置文件目录
101
+ defaultConfig, // 默认配置对象
102
+ defineConfig // 配置定义对象(用于嵌套对象的结构定义)
56
103
  )
57
104
  ```
58
105
 
106
+ > **注意**:配置文件会自动保存为 `{config-name}.json`
107
+
59
108
  **主要方法**
60
109
 
61
110
  ```typescript
62
- // 获取配置值
63
- const value = config.get<T>('key.path')
111
+ // 获取配置值(支持深层路径)
112
+ const value = config.get('key.path')
64
113
 
65
- // 设置配置值
66
- config.set<T>('key.path', value, save?: boolean)
114
+ // 获取整个配置对象
115
+ const allConfig = config.get('')
67
116
 
68
117
  // 获取数组配置(返回 EnhancedArray)
69
- const arr = config.getArray<T>('key.path')
118
+ const arr = config.get('users', true) // 第二个参数为 true 表示返回数组
119
+ // 或使用第三个参数提供默认值
120
+ const arrWithDefault = config.get('users', true, [])
121
+
122
+ // 获取默认配置
123
+ const defaultValue = config.getDef('key.path')
124
+ const allDefaults = config.getDef('')
125
+
126
+ // 设置配置值
127
+ config.set('key.path', value, true) // 第三个参数为 true 表示立即保存
128
+ config.set('key.path', value, false) // false 表示不立即保存
70
129
 
71
130
  // 监听配置变化(文件修改时触发)
72
131
  config.watch((self, oldData, newData) => {
@@ -115,8 +174,8 @@ const isEnabled = config.get<boolean>('enable')
115
174
  // 设置配置
116
175
  config.set('settings.timeout', 10000, true)
117
176
 
118
- // 获取数组
119
- const users = config.getArray<string>('users')
177
+ // 获取数组(第二个参数为 true)
178
+ const users = config.get('users', true)
120
179
  users.add('user1', true, true)
121
180
 
122
181
  // 监听配置文件变化
@@ -144,39 +203,54 @@ config.watch((self, oldData, newData) => {
144
203
  // 检查元素是否存在
145
204
  arr.has(element)
146
205
 
147
- // 添加单个元素
148
- arr.add(element, isEqual: boolean, save: boolean)
206
+ // 添加单个元素(isEqual: 是否去重,save: 是否保存)
207
+ arr.add(element, isEqual, save)
149
208
 
150
209
  // 批量添加元素
151
- arr.addSome(elements, isEqual: boolean, save: boolean)
210
+ arr.addSome(elements, isEqual, save)
152
211
 
153
- // 删除元素
154
- arr.remove(predicate, save: boolean)
155
- arr.remove(index, save: boolean, true) // 按索引删除
212
+ // 按条件删除元素
213
+ arr.remove(predicate, save)
156
214
 
157
- // 批量删除元素
158
- arr.removeSome(elements, save: boolean)
215
+ // 按索引删除元素
216
+ arr.pullAt(index, save)
217
+
218
+ // 批量删除指定元素
219
+ arr.pullAll(elements, save)
220
+
221
+ // 清空数组(不保存)
222
+ arr.clear()
159
223
  ```
160
224
 
161
225
  **示例**
162
226
 
163
227
  ```typescript
164
- const users = config.getArray<string>('users')
228
+ // 获取数组配置
229
+ const users = config.get('users', true)
165
230
 
166
- // 添加元素(去重)
231
+ // 添加元素(去重 + 保存)
167
232
  users.add('user1', true, true)
168
233
 
169
- // 批量添加
234
+ // 批量添加(去重 + 保存)
170
235
  users.addSome(['user2', 'user3'], true, true)
171
236
 
172
- // 删除元素
173
- users.remove('user1', true)
174
-
175
237
  // 按条件删除
176
238
  users.remove(user => user.startsWith('test'), true)
177
239
 
178
240
  // 按索引删除
179
- users.remove(0, true, true)
241
+ users.pullAt(0, true)
242
+
243
+ // 批量删除指定元素
244
+ users.pullAll(['user1', 'user2'], true)
245
+
246
+ // 检查元素是否存在
247
+ if (users.has('user1')) {
248
+ console.log('用户存在')
249
+ }
250
+
251
+ // 清空数组(需要手动保存)
252
+ users.clear()
253
+ config.save()
180
254
  ```
181
255
 
182
256
  ---
@@ -212,31 +286,33 @@ const dbList = Database.details
212
286
  **列定义方法**
213
287
 
214
288
  ```typescript
215
- // 1. 普通列 - Column(type, defaultValue, options?)
289
+ // 1. 主键列 - PkColumn(key, type, options?)
290
+ Database.PkColumn(
291
+ 'userId', // 列名(必须与 schema 中的 key 一致)
292
+ 'STRING', // 数据类型:STRING, INTEGER 等
293
+ { // 可选配置(已包含 primaryKey: true, allowNull: false)
294
+ autoIncrement: true // 自动递增(仅数字类型)
295
+ }
296
+ )
297
+
298
+ // 2. 普通列 - Column(key, type, defaultValue, options?)
216
299
  Database.Column(
300
+ 'nickname', // 列名(必须与 schema 中的 key 一致)
217
301
  'STRING', // 数据类型:STRING, INTEGER, BOOLEAN, TEXT 等
218
- 'default', // 默认值
302
+ 'Guest', // 默认值
219
303
  { // 可选配置
220
304
  allowNull: false, // 是否允许为空
221
305
  unique: true // 是否唯一
222
306
  }
223
307
  )
224
308
 
225
- // 2. 主键列 - PkColumn(type, options?)
226
- Database.PkColumn(
227
- 'STRING', // 数据类型
228
- { // 可选配置(已包含 primaryKey: true, allowNull: false)
229
- autoIncrement: true // 自动递增(仅数字类型)
230
- }
231
- )
232
-
233
309
  // 3. 数组列 - ArrayColumn(key, transformFn?)
234
310
  Database.ArrayColumn(
235
311
  'tags', // 列名(必须与 schema 中的 key 一致)
236
- (data) => data // 可选:数据转换函数
312
+ (data) => data // 可选:数据转换函数(在 set 时调用)
237
313
  )
238
314
  // 存储格式:逗号分隔的字符串 "tag1,tag2,tag3"
239
- // 读取返回:DatabaseArray<T> 类型
315
+ // 读取返回:DatabaseArray<T> 类型(扩展数组,支持 push、splice 等标准数组方法)
240
316
 
241
317
  // 4. JSON 列 - JsonColumn(key, defaultValue)
242
318
  Database.JsonColumn(
@@ -252,29 +328,34 @@ Database.JsonColumn(
252
328
  ```typescript
253
329
  import { Database } from 'karin-plugin-mys-core/database'
254
330
 
255
- const userSchema = {
256
- // 主键列:只需指定类型
257
- userId: Database.PkColumn('STRING'),
331
+ // Schema 使用数组形式
332
+ const userSchema = [
333
+ // 主键列:列名 + 数据类型 + 可选配置
334
+ Database.PkColumn('userId', 'STRING'),
258
335
 
259
- // 普通列:类型 + 默认值 + 可选配置
260
- nickname: Database.Column('STRING', 'Guest', { allowNull: false }),
261
- email: Database.Column('STRING', '', { unique: true }),
262
- age: Database.Column('INTEGER', 0),
263
- active: Database.Column('BOOLEAN', true),
264
- bio: Database.Column('TEXT', ''),
336
+ // 普通列:列名 + 数据类型 + 默认值 + 可选配置
337
+ Database.Column('nickname', 'STRING', 'Guest', { allowNull: false }),
338
+ Database.Column('email', 'STRING', '', { unique: true }),
339
+ Database.Column('age', 'INTEGER', 0),
340
+ Database.Column('active', 'BOOLEAN', true),
341
+ Database.Column('bio', 'TEXT', ''),
265
342
 
266
- // 数组列:列名必须与 key 一致
267
- tags: Database.ArrayColumn('tags'),
343
+ // 数组列:列名 + 可选转换函数
344
+ Database.ArrayColumn('tags'),
268
345
  // 或带转换函数
269
- roles: Database.ArrayColumn('roles', (data) => {
346
+ Database.ArrayColumn('roles', (data) => {
270
347
  return data.filter(role => role !== 'banned')
271
348
  }),
272
349
 
273
350
  // JSON 列:列名 + 默认值对象
274
- profile: Database.JsonColumn('profile', { level: 1, exp: 0 }),
275
- settings: Database.JsonColumn('settings', { theme: 'light' }),
276
- metadata: Database.JsonColumn('metadata', {})
277
- }
351
+ Database.JsonColumn('profile', { level: 1, exp: 0 }),
352
+ Database.JsonColumn('settings', { theme: 'light' }),
353
+ Database.JsonColumn('metadata', {})
354
+ ]
355
+
356
+ // 使用时
357
+ const db = Database.get()
358
+ await db.init('./data', 'users', userSchema, {}, DatabaseType.Db)
278
359
  ```
279
360
 
280
361
  **数据库类型**
@@ -310,7 +391,8 @@ const dbInstance = Database.get<UserType, DatabaseType.Db>()
310
391
  await dbInstance.init(
311
392
  './data', // 数据目录
312
393
  'users', // 表名
313
- schema, // 表结构
394
+ schema, // 表结构(数组形式)
395
+ {}, // Schema 定义(通常为空对象)
314
396
  DatabaseType.Db // 数据库类型:SQL 数据库
315
397
  )
316
398
  // 存储位置:./data/database/sqlite3.db(表名:users)
@@ -320,7 +402,8 @@ const fileInstance = Database.get<ConfigType, DatabaseType.File>()
320
402
  await fileInstance.init(
321
403
  './data', // 数据目录
322
404
  'configs', // 目录名
323
- schema, // 数据结构
405
+ schema, // 数据结构(数组形式)
406
+ {}, // Schema 定义(通常为空对象)
324
407
  DatabaseType.File // 数据库类型:单文件
325
408
  )
326
409
  // 存储位置:./data/configs/{userId}.json
@@ -330,7 +413,8 @@ const dirInstance = Database.get<ComplexType, DatabaseType.Dir>()
330
413
  await dirInstance.init(
331
414
  './data', // 数据目录
332
415
  'userdata', // 目录名
333
- schema, // 数据结构
416
+ schema, // 数据结构(数组形式)
417
+ {}, // Schema 定义(通常为空对象)
334
418
  DatabaseType.Dir // 数据库类型:目录
335
419
  )
336
420
  // 存储位置:./data/userdata/{userId}/*.json
@@ -342,21 +426,28 @@ await dirInstance.init(
342
426
 
343
427
  ```typescript
344
428
  // 查找记录(主键)
345
- const record = await db.findByPk(pk, create?: boolean)
429
+ const record = await db.findByPk(pk) // 不存在返回 undefined
430
+ const record = await db.findByPk(pk, true) // 不存在则创建
346
431
 
347
432
  // 查找多个记录(批量查询)
348
- const records = await db.findAllByPks(pks)
433
+ const records = await db.findAllByPks(['pk1', 'pk2', 'pk3'])
349
434
 
350
- // 查找所有记录(可排除指定主键)
351
- const allRecords = await db.findAll(excludePks?: string[])
435
+ // 查找所有记录
436
+ const allRecords = await db.findAll() // 查找所有
437
+ const someRecords = await db.findAll(['pk1']) // 排除指定主键
352
438
 
353
- // 保存记录
354
- await record.save({ key: value })
439
+ // 保存记录(会自动合并数据,只更新提供的字段)
440
+ await record.save({
441
+ nickname: 'new name', // 只更新这些字段
442
+ level: 10
443
+ })
355
444
 
356
445
  // 删除记录
357
- await record.destroy()
446
+ await record.destroy() // 删除数据库记录/文件/目录
358
447
  ```
359
448
 
449
+ > **注意**:`save` 方法会自动过滤未定义的字段,并与现有数据合并
450
+
360
451
  **示例**
361
452
 
362
453
  **示例 1:SQL 数据库模式 - 用户信息表**
@@ -364,20 +455,20 @@ await record.destroy()
364
455
  ```typescript
365
456
  import { Database, DatabaseType } from 'karin-plugin-mys-core/database'
366
457
 
367
- // 定义用户表结构(注意参数顺序)
368
- const userSchema = {
369
- userId: Database.PkColumn('STRING'), // 主键
370
- nickname: Database.Column('STRING', '', { allowNull: false }), // 默认值 '', 不允许为空
371
- level: Database.Column('INTEGER', 1), // 默认值 1
372
- coins: Database.Column('INTEGER', 0), // 默认值 0
373
- vip: Database.Column('BOOLEAN', false), // 默认值 false
374
- tags: Database.ArrayColumn('tags'), // 数组列
375
- data: Database.JsonColumn('data', {}) // JSON 列,默认值 {}
376
- }
458
+ // 定义用户表结构(数组形式)
459
+ const userSchema = [
460
+ Database.PkColumn('userId', 'STRING'), // 主键
461
+ Database.Column('nickname', 'STRING', '', { allowNull: false }), // 默认值 '', 不允许为空
462
+ Database.Column('level', 'INTEGER', 1), // 默认值 1
463
+ Database.Column('coins', 'INTEGER', 0), // 默认值 0
464
+ Database.Column('vip', 'BOOLEAN', false), // 默认值 false
465
+ Database.ArrayColumn('tags'), // 数组列
466
+ Database.JsonColumn('data', {}) // JSON 列,默认值 {}
467
+ ]
377
468
 
378
469
  // 初始化 SQL 数据库
379
470
  const userDB = Database.get<UserType, DatabaseType.Db>()
380
- await userDB.init('./data', 'users', userSchema, DatabaseType.Db)
471
+ await userDB.init('./data', 'users', userSchema, {}, DatabaseType.Db)
381
472
 
382
473
  // 操作数据
383
474
  const user = await userDB.findByPk('123456', true) // 不存在则创建
@@ -399,17 +490,17 @@ const allUsers = await userDB.findAll()
399
490
  ```typescript
400
491
  import { Database, DatabaseType } from 'karin-plugin-mys-core/database'
401
492
 
402
- // 定义配置结构(注意参数顺序)
403
- const configSchema = {
404
- key: Database.PkColumn('STRING'), // 主键
405
- value: Database.Column('TEXT', ''), // 默认值 ''
406
- type: Database.Column('STRING', 'string'), // 默认值 'string'
407
- updatedAt: Database.Column('INTEGER', 0) // 默认值 0
408
- }
493
+ // 定义配置结构(数组形式)
494
+ const configSchema = [
495
+ Database.PkColumn('key', 'STRING'), // 主键
496
+ Database.Column('value', 'TEXT', ''), // 默认值 ''
497
+ Database.Column('type', 'STRING', 'string'), // 默认值 'string'
498
+ Database.Column('updatedAt', 'INTEGER', 0) // 默认值 0
499
+ ]
409
500
 
410
501
  // 初始化文件存储
411
502
  const configDB = Database.get<ConfigType, DatabaseType.File>()
412
- await configDB.init('./config', 'settings', configSchema, DatabaseType.File)
503
+ await configDB.init('./config', 'settings', configSchema, {}, DatabaseType.File)
413
504
 
414
505
  // 操作配置
415
506
  const config = await configDB.findByPk('app_name', true)
@@ -427,18 +518,18 @@ await config.save({
427
518
  ```typescript
428
519
  import { Database, DatabaseType } from 'karin-plugin-mys-core/database'
429
520
 
430
- // 定义复杂数据结构(注意参数顺序)
431
- const complexSchema = {
432
- userId: Database.PkColumn('STRING'), // 主键
433
- profile: Database.JsonColumn('profile', {}), // JSON 列,默认值 {}
434
- inventory: Database.JsonColumn('inventory', { items: [] }), // JSON 列,默认值 { items: [] }
435
- achievements: Database.ArrayColumn('achievements'), // 数组列
436
- settings: Database.JsonColumn('settings', {}) // JSON 列,默认值 {}
437
- }
521
+ // 定义复杂数据结构(数组形式)
522
+ const complexSchema = [
523
+ Database.PkColumn('userId', 'STRING'), // 主键
524
+ Database.JsonColumn('profile', {}), // JSON 列,默认值 {}
525
+ Database.JsonColumn('inventory', { items: [] }), // JSON 列,默认值 { items: [] }
526
+ Database.ArrayColumn('achievements'), // 数组列
527
+ Database.JsonColumn('settings', {}) // JSON 列,默认值 {}
528
+ ]
438
529
 
439
530
  // 初始化目录存储
440
531
  const complexDB = Database.get<ComplexType, DatabaseType.Dir>()
441
- await complexDB.init('./data', 'userdata', complexSchema, DatabaseType.Dir)
532
+ await complexDB.init('./data', 'userdata', complexSchema, {}, DatabaseType.Dir)
442
533
 
443
534
  // 操作数据
444
535
  const userData = await complexDB.findByPk('123456', true)
@@ -476,16 +567,26 @@ Database.default(Dialect.PostgreSQL) // 或 MySQL, MariaDB
476
567
 
477
568
  **内置表**
478
569
 
570
+ 插件提供了三个内置的米游社相关表:
571
+
479
572
  ```typescript
480
573
  import {
481
- MysUserInfoDB, // 用户信息表
482
- MysAccountInfoDB, // 账号信息表
483
- MysDeviceInfoDB // 设备信息表
574
+ MysUserInfoDB, // 用户信息表:存储用户的 ltuid、stuid 等信息
575
+ MysAccountInfoDB, // 账号信息表:存储米游社账号的 cookie、stoken 等
576
+ MysDeviceInfoDB // 设备信息表:存储设备信息(设备指纹等)
484
577
  } from 'karin-plugin-mys-core/database'
485
578
 
486
- // 使用内置表
579
+ // 使用内置表(需要 await)
487
580
  const userDB = await MysUserInfoDB()
488
581
  const user = await userDB.findByPk(userId, true)
582
+
583
+ // 账号信息表
584
+ const accountDB = await MysAccountInfoDB()
585
+ const account = await accountDB.findByPk(ltuid, true)
586
+
587
+ // 设备信息表
588
+ const deviceDB = await MysDeviceInfoDB()
589
+ const device = await deviceDB.findByPk(deviceMd5, true)
489
590
  ```
490
591
 
491
592
  ---
@@ -567,12 +668,16 @@ import { GameUserInfo } from './GameUserInfo' // 你的游戏用户信息类
567
668
 
568
669
  // 创建游戏注册对象
569
670
  const MyGame = new RegisterGameBase(
570
- 'game_key', // 游戏标识(如:gs, sr, zzz)
671
+ 'gs', // 游戏标识(如:gs, sr, zzz)
571
672
  '原神', // 游戏名称
572
- /^#?(原神|gs)/i, // 指令前缀匹配正则
673
+ ['原神', 'gs', 'ys'], // 指令前缀数组(不含 #)
573
674
  GameUserInfo, // 游戏用户信息类
574
- (info) => { // UID 刷新函数
575
- return info.map(item => item.game_uid)
675
+ async (info, options) => { // UID 刷新函数
676
+ // info: 米游社返回的角色列表
677
+ // options: { userId, cookie, ltuid, type }
678
+ return info
679
+ .filter(role => role.game_biz === 'hk4e_cn') // 过滤对应游戏
680
+ .map(role => role.game_uid) // 返回 UID 数组
576
681
  }
577
682
  )
578
683
 
@@ -583,12 +688,12 @@ MysGame.RegisterGame(MyGame)
583
688
  **游戏匹配**
584
689
 
585
690
  ```typescript
586
- // 通过指令前缀匹配游戏
587
- const game = MysGame.match('#原神角色')
691
+ // 通过指令前缀匹配游戏(传入去掉 # 的指令前缀)
692
+ const game = MysGame.match('原神') // 或 'gs', 'ys'
588
693
  if (game) {
589
- console.log('匹配到游戏:', game.name)
590
- console.log('游戏标识:', game.game)
591
- console.log('列键名:', game.columnKey) // 'gs-uids'
694
+ console.log('匹配到游戏:', game.name) // '原神'
695
+ console.log('游戏标识:', game.game) // 'gs'
696
+ console.log('列键名:', game.columnKey) // { uids: 'gs-uids', main: 'gs-main' }
592
697
  }
593
698
  ```
594
699
 
@@ -636,11 +741,11 @@ class GenshinUserInfo extends GameUserInfoBase<GenshinUserInfoTableType> {
636
741
 
637
742
  // 2. 创建并注册游戏
638
743
  const Genshin = new RegisterGameBase(
639
- 'gs', // 游戏标识
640
- '原神', // 游戏名称
641
- /^#?(原神|gs|ys)/i, // 匹配 #原神 #gs #ys
642
- GenshinUserInfo, // 用户信息类
643
- (roleList) => { // UID 提取函数
744
+ 'gs', // 游戏标识
745
+ '原神', // 游戏名称
746
+ ['原神', 'gs', 'ys'], // 指令前缀数组(不含 #)
747
+ GenshinUserInfo, // 用户信息类
748
+ async (roleList, options) => { // UID 提取函数
644
749
  return roleList
645
750
  .filter(role => role.game_biz === 'hk4e_cn')
646
751
  .map(role => role.game_uid)
@@ -650,7 +755,7 @@ const Genshin = new RegisterGameBase(
650
755
  MysGame.RegisterGame(Genshin)
651
756
 
652
757
  // 3. 使用游戏
653
- const game = MysGame.match('#原神角色')
758
+ const game = MysGame.match('原神') // 去掉 # 的指令前缀
654
759
  if (game) {
655
760
  // 创建用户信息
656
761
  const userInfo = await game.UserInfo.create(userId)
@@ -781,15 +886,11 @@ render.plugin
781
886
  // name: string // 插件名称
782
887
  // version: string // 插件版本
783
888
  // resources: {
784
- // default: string // 插件内部资源路径
785
- // download: string // 插件外部资源路径
889
+ // default: string // 插件内部资源路径(绝对路径)
890
+ // download: string // 插件外部资源路径(@karinjs 目录,绝对路径)
786
891
  // }
787
892
  // ...customOptions // 自定义选项
788
893
  // }
789
-
790
- // 获取 Karin 版本信息
791
- render.karin
792
- // 返回: { version: string }
793
894
  ```
794
895
 
795
896
  **template 方法**
@@ -803,11 +904,11 @@ async template<C extends React.ComponentType<any>>(
803
904
  props: React.ComponentProps<C>, // 组件 props
804
905
  options?: {
805
906
  type?: 'png' | 'jpeg' | 'webp' // 图片格式,默认 'jpeg'
806
- plugin?: Record<string, any> // 额外插件参数
907
+ plugin?: Record<string, any> // 额外插件参数(当前未使用)
807
908
  render?: { // 渲染选项
808
- name?: string // 文件名(不含后缀)
909
+ name?: string // 文件名(不含后缀),默认使用模板名+随机字符串
809
910
  setViewport?: {
810
- deviceScaleFactor?: number // 设备缩放比例,默认 2
911
+ deviceScaleFactor?: number // 设备缩放比例,默认 3
811
912
  }
812
913
  // 更多 karin.render 选项...
813
914
  }
@@ -1037,10 +1138,16 @@ const image = await render.template('content', ContentCard, {
1037
1138
  **注意事项**
1038
1139
 
1039
1140
  1. **CSS 文件位置**:CSS 文件必须位于 `resources/styles/{插件名}.css`,否则样式无法加载
1040
- 2. **图片格式**:`png` 支持透明背景,`jpeg` 文件更小,`webp` 是现代格式
1041
- 3. **性能优化**:使用 `deviceScaleFactor: 2` 可获得高清图片,但会增加渲染时间
1141
+ 2. **图片格式**:
1142
+ - `jpeg`(默认):文件更小,适合大多数场景,不支持透明背景
1143
+ - `png`:支持透明背景,文件较大
1144
+ - `webp`:现代格式,体积小且质量好
1145
+ 3. **性能优化**:默认使用 `deviceScaleFactor: 3` 渲染高清图片,可自定义降低以提升速度
1042
1146
  4. **临时文件**:HTML 临时文件保存在 `@karinjs/temp/html/{插件名}/{模板名}/` 目录
1043
- 5. **资源路径**:在组件中使用 `render.plugin.resources.default` 访问插件资源
1147
+ 5. **资源路径**:
1148
+ - `render.plugin.resources.default`:插件内部资源(开发时的 resources 目录)
1149
+ - `render.plugin.resources.download`:插件外部资源(@karinjs 目录下的 resources)
1150
+ 6. **选择器**:默认使用 `container` 选择器,确保你的根元素有 `container` 类名或根据需要自定义选择器
1044
1151
 
1045
1152
  ---
1046
1153
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ShowBindAccountCmdFunc
3
- } from "../chunk-SCXP2BGQ.js";
4
- import "../chunk-C2ZR7X67.js";
3
+ } from "../chunk-AVUQGP7L.js";
4
+ import "../chunk-QZUNBUDC.js";
5
5
  import {
6
6
  UserInfo,
7
7
  fetchQRcode,
@@ -9,11 +9,11 @@ import {
9
9
  getTokenByGameToken,
10
10
  getUserFullInfo,
11
11
  queryQRcode
12
- } from "../chunk-AFF6YSYO.js";
12
+ } from "../chunk-XSW4HNMM.js";
13
13
  import "../chunk-5LRGHP36.js";
14
14
  import "../chunk-HI6OZTI2.js";
15
15
  import "../chunk-BLE3V6QR.js";
16
- import "../chunk-4N3KY3KE.js";
16
+ import "../chunk-A4WGB4ID.js";
17
17
  import {
18
18
  common_exports
19
19
  } from "../chunk-RX4VMVAI.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  DeviceInfo,
3
3
  UserInfo
4
- } from "../chunk-AFF6YSYO.js";
4
+ } from "../chunk-XSW4HNMM.js";
5
5
  import "../chunk-5LRGHP36.js";
6
6
  import "../chunk-HI6OZTI2.js";
7
7
  import "../chunk-BLE3V6QR.js";
8
- import "../chunk-4N3KY3KE.js";
8
+ import "../chunk-A4WGB4ID.js";
9
9
  import "../chunk-RX4VMVAI.js";
10
10
  import "../chunk-SHLPPEAY.js";
11
11
  import "../chunk-MLKGABMK.js";
@@ -5,13 +5,13 @@ import {
5
5
  ShowBindAccountCmdFunc,
6
6
  UnbindAccount,
7
7
  UnbindUID
8
- } from "../chunk-SCXP2BGQ.js";
9
- import "../chunk-C2ZR7X67.js";
10
- import "../chunk-AFF6YSYO.js";
8
+ } from "../chunk-AVUQGP7L.js";
9
+ import "../chunk-QZUNBUDC.js";
10
+ import "../chunk-XSW4HNMM.js";
11
11
  import "../chunk-5LRGHP36.js";
12
12
  import "../chunk-HI6OZTI2.js";
13
13
  import "../chunk-BLE3V6QR.js";
14
- import "../chunk-4N3KY3KE.js";
14
+ import "../chunk-A4WGB4ID.js";
15
15
  import "../chunk-RX4VMVAI.js";
16
16
  import "../chunk-SHLPPEAY.js";
17
17
  import "../chunk-MLKGABMK.js";
@@ -271,7 +271,11 @@ var Sqlite3 = class extends DbBase {
271
271
  async init(DataDir, modelName, modelSchema, modelSchemaDefine, type, primaryKey) {
272
272
  this.initBase(DataDir, modelName, modelSchema, modelSchemaDefine, type, primaryKey);
273
273
  if (this.databaseType === "db" /* Db */) {
274
- this.model = sequelize.define(this.modelName, this.modelSchema, {
274
+ const modelSchema2 = this.modelSchema.reduce((acc, cur) => {
275
+ acc[cur.key] = cur.Option;
276
+ return acc;
277
+ }, {});
278
+ this.model = sequelize.define(this.modelName, modelSchema2, {
275
279
  timestamps: false,
276
280
  freezeTableName: true
277
281
  });
@@ -2,11 +2,11 @@ import {
2
2
  DefaultLayoutComponent,
3
3
  React,
4
4
  ReactRender
5
- } from "./chunk-C2ZR7X67.js";
5
+ } from "./chunk-QZUNBUDC.js";
6
6
  import {
7
7
  MysGame,
8
8
  UserInfo
9
- } from "./chunk-AFF6YSYO.js";
9
+ } from "./chunk-XSW4HNMM.js";
10
10
  import {
11
11
  dir
12
12
  } from "./chunk-SHLPPEAY.js";
@@ -95,8 +95,8 @@ var ReactRender = class {
95
95
  const savePath = path.join(saveDir, `${options.render?.name || template}-${common_exports.randomString(8, "Lower")}.html`);
96
96
  fs.writeFileSync(savePath, Html, "utf-8");
97
97
  const image = await karin.render({
98
- type: options.type || "jpeg",
99
- omitBackground: options.type === "png",
98
+ type: options.type || "png",
99
+ omitBackground: options.type !== "png",
100
100
  selector: "container",
101
101
  setViewport: {
102
102
  deviceScaleFactor: 3
@@ -5,7 +5,7 @@ import {
5
5
  MysAccountInfoDB,
6
6
  MysDeviceInfoDB,
7
7
  MysUserInfoDB
8
- } from "./chunk-4N3KY3KE.js";
8
+ } from "./chunk-A4WGB4ID.js";
9
9
  import {
10
10
  common_exports
11
11
  } from "./chunk-RX4VMVAI.js";
package/lib/core/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  DeviceCfg
5
5
  } from "../chunk-HI6OZTI2.js";
6
6
  import "../chunk-BLE3V6QR.js";
7
- import "../chunk-4N3KY3KE.js";
7
+ import "../chunk-A4WGB4ID.js";
8
8
  import "../chunk-RX4VMVAI.js";
9
9
  import "../chunk-SHLPPEAY.js";
10
10
  import "../chunk-MLKGABMK.js";
@@ -61,12 +61,16 @@ declare class Table<TableType extends Record<string, any>, ExtraTableType extend
61
61
  * @param type Db: 直接保存在sqlite数据中、 File: 保存在单个json文件中、 Dir: 保存在多个json文件的目录中、Schema中除pk外每一个键值对应一个文件 e.g tableName/user/key.json
62
62
  */
63
63
  constructor(DataDir: string, tableName: string, type: DBType, primaryKey?: keyof TableType);
64
- init<const S extends readonly {
64
+ init<SchemDefine extends Partial<Record<keyof TableType, any>> = {}, const S extends readonly {
65
65
  key: keyof TableType;
66
- }[]>(Schema: ValidateSchema<TableType, S>, SchemaDefine?: Partial<Record<keyof TableType, any>>): Promise<() => Promise<DatabaseClassInstance<TableType, DBType>>>;
67
- addSchem<newTableType extends ExtraTableType, const S extends readonly {
66
+ }[] = readonly {
67
+ key: keyof TableType;
68
+ }[]>(Schema: ValidateSchema<TableType, S>, SchemaDefine?: SchemDefine): Promise<() => Promise<DatabaseClassInstance<TableType, DBType>>>;
69
+ addSchem<newTableType extends ExtraTableType, newSchemDefine extends Partial<Record<keyof newTableType, any>> = {}, const S extends readonly {
70
+ key: keyof newTableType;
71
+ }[] = readonly {
68
72
  key: keyof newTableType;
69
- }[]>(newSchema: ValidateSchema<newTableType, S>, SchemaDefine?: Partial<Record<keyof newTableType, any>>): Promise<() => Promise<DatabaseClassInstance<TableType & newTableType, DBType>>>;
73
+ }[]>(newSchema: ValidateSchema<newTableType, S>, SchemaDefine?: newSchemDefine): Promise<() => Promise<DatabaseClassInstance<TableType & newTableType, DBType>>>;
70
74
  }
71
75
  declare function createTable<TableType extends Record<string, any>, ExtraTableType extends Record<string, any> = {}>(DataDir: string, tableName: string, type: DatabaseType.File, primaryKey: keyof TableType): Table<TableType, ExtraTableType, DatabaseType.File>;
72
76
  declare function createTable<TableType extends Record<string, any>, ExtraTableType extends Record<string, any> = {}>(DataDir: string, tableName: string, type: DatabaseType.Dir, primaryKey: keyof TableType): Table<TableType, ExtraTableType, DatabaseType.Dir>;
@@ -15,7 +15,7 @@ import {
15
15
  Table,
16
16
  UidPermission,
17
17
  createTable
18
- } from "../../chunk-4N3KY3KE.js";
18
+ } from "../../chunk-A4WGB4ID.js";
19
19
  import "../../chunk-RX4VMVAI.js";
20
20
  import "../../chunk-SHLPPEAY.js";
21
21
  import "../../chunk-MLKGABMK.js";
@@ -15,11 +15,11 @@ import {
15
15
  getUserFullInfo,
16
16
  getUserGameRolesByCookie,
17
17
  queryQRcode
18
- } from "../../chunk-AFF6YSYO.js";
18
+ } from "../../chunk-XSW4HNMM.js";
19
19
  import "../../chunk-5LRGHP36.js";
20
20
  import "../../chunk-HI6OZTI2.js";
21
21
  import "../../chunk-BLE3V6QR.js";
22
- import "../../chunk-4N3KY3KE.js";
22
+ import "../../chunk-A4WGB4ID.js";
23
23
  import "../../chunk-RX4VMVAI.js";
24
24
  import "../../chunk-SHLPPEAY.js";
25
25
  import "../../chunk-MLKGABMK.js";
@@ -42,8 +42,7 @@ declare class ReactRender<P extends Record<string, any>, K extends string> {
42
42
  get plugin(): Omit<P, 'name' | 'version' | 'resources'> & DefaultRenderPluginOptionsType;
43
43
  template<C extends React.ComponentType<any>>(template: K, component: C, props: React.ComponentProps<C>, options?: {
44
44
  type?: 'png' | 'jpeg' | 'webp';
45
- plugin?: Record<string, any>;
46
- render?: Omit<Options, 'file' | 'data'>;
45
+ render?: Omit<Options, 'file' | 'data' | 'type' | 'omitBackground'>;
47
46
  }): Promise<string | null>;
48
47
  }
49
48
 
@@ -2,7 +2,7 @@ import {
2
2
  DefaultLayoutComponent,
3
3
  React,
4
4
  ReactRender
5
- } from "../../chunk-C2ZR7X67.js";
5
+ } from "../../chunk-QZUNBUDC.js";
6
6
  import "../../chunk-RX4VMVAI.js";
7
7
  import "../../chunk-SHLPPEAY.js";
8
8
  import "../../chunk-MLKGABMK.js";
package/lib/web.config.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  DeviceCfg
4
4
  } from "./chunk-HI6OZTI2.js";
5
5
  import "./chunk-BLE3V6QR.js";
6
- import "./chunk-4N3KY3KE.js";
6
+ import "./chunk-A4WGB4ID.js";
7
7
  import "./chunk-RX4VMVAI.js";
8
8
  import {
9
9
  dir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "karin-plugin-mys-core",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "author": "babanbang",
5
5
  "type": "module",
6
6
  "description": "karin-plugin-mys-core",