@satorijs/adapter-lark 3.10.6 → 3.11.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.
Files changed (119) hide show
  1. package/lib/content.d.ts +211 -93
  2. package/lib/index.cjs +2954 -2474
  3. package/lib/internal.d.ts +4 -4
  4. package/lib/message.d.ts +2 -3
  5. package/lib/types/acs.d.ts +212 -172
  6. package/lib/types/admin.d.ts +331 -291
  7. package/lib/types/aily.d.ts +331 -216
  8. package/lib/types/apaas.d.ts +646 -494
  9. package/lib/types/application.d.ts +559 -458
  10. package/lib/types/approval.d.ts +826 -791
  11. package/lib/types/attendance.d.ts +1094 -994
  12. package/lib/types/auth.d.ts +66 -61
  13. package/lib/types/authen.d.ts +221 -186
  14. package/lib/types/baike.d.ts +258 -233
  15. package/lib/types/base.d.ts +74 -0
  16. package/lib/types/bitable.d.ts +830 -770
  17. package/lib/types/board.d.ts +29 -14
  18. package/lib/types/calendar.d.ts +660 -605
  19. package/lib/types/cardkit.d.ts +149 -134
  20. package/lib/types/compensation.d.ts +84 -49
  21. package/lib/types/contact.d.ts +1279 -1204
  22. package/lib/types/corehr.d.ts +4982 -4526
  23. package/lib/types/directory.d.ts +447 -0
  24. package/lib/types/docs.d.ts +28 -18
  25. package/lib/types/document_ai.d.ts +347 -252
  26. package/lib/types/docx.d.ts +428 -383
  27. package/lib/types/drive.d.ts +1093 -1048
  28. package/lib/types/ehr.d.ts +66 -51
  29. package/lib/types/event.d.ts +16 -6
  30. package/lib/types/helpdesk.d.ts +816 -741
  31. package/lib/types/hire.d.ts +3955 -3589
  32. package/lib/types/human_authentication.d.ts +32 -22
  33. package/lib/types/im.d.ts +1420 -1295
  34. package/lib/types/index.d.ts +1422 -330
  35. package/lib/types/lingo.d.ts +279 -249
  36. package/lib/types/mail.d.ts +1032 -675
  37. package/lib/types/mdm.d.ts +105 -37
  38. package/lib/types/minutes.d.ts +73 -26
  39. package/lib/types/moments.d.ts +23 -13
  40. package/lib/types/okr.d.ts +266 -225
  41. package/lib/types/optical_char_recognition.d.ts +22 -12
  42. package/lib/types/passport.d.ts +58 -48
  43. package/lib/types/payroll.d.ts +210 -53
  44. package/lib/types/performance.d.ts +463 -414
  45. package/lib/types/personal_settings.d.ts +93 -82
  46. package/lib/types/report.d.ts +79 -58
  47. package/lib/types/search.d.ts +265 -235
  48. package/lib/types/security_and_compliance.d.ts +30 -19
  49. package/lib/types/sheets.d.ts +356 -321
  50. package/lib/types/speech_to_text.d.ts +44 -34
  51. package/lib/types/task.d.ts +998 -1087
  52. package/lib/types/tenant.d.ts +25 -15
  53. package/lib/types/translation.d.ts +42 -32
  54. package/lib/types/trust_party.d.ts +81 -0
  55. package/lib/types/vc.d.ts +1218 -1123
  56. package/lib/types/verification.d.ts +11 -6
  57. package/lib/types/wiki.d.ts +270 -235
  58. package/lib/types/workplace.d.ts +58 -38
  59. package/lib/utils.d.ts +2 -2
  60. package/package.json +4 -4
  61. package/src/bot.ts +15 -15
  62. package/src/content.ts +230 -107
  63. package/src/internal.ts +29 -12
  64. package/src/message.ts +82 -111
  65. package/src/types/acs.ts +234 -186
  66. package/src/types/admin.ts +353 -305
  67. package/src/types/aily.ts +375 -233
  68. package/src/types/apaas.ts +754 -568
  69. package/src/types/application.ts +633 -507
  70. package/src/types/approval.ts +914 -872
  71. package/src/types/attendance.ts +1226 -1104
  72. package/src/types/auth.ts +72 -66
  73. package/src/types/authen.ts +233 -191
  74. package/src/types/baike.ts +276 -246
  75. package/src/types/base.ts +93 -0
  76. package/src/types/bitable.ts +966 -894
  77. package/src/types/board.ts +34 -16
  78. package/src/types/calendar.ts +751 -685
  79. package/src/types/cardkit.ts +164 -146
  80. package/src/types/compensation.ts +97 -55
  81. package/src/types/contact.ts +1465 -1375
  82. package/src/types/corehr.ts +5664 -5077
  83. package/src/types/directory.ts +569 -0
  84. package/src/types/docs.ts +31 -19
  85. package/src/types/document_ai.ts +401 -287
  86. package/src/types/docx.ts +492 -438
  87. package/src/types/drive.ts +1266 -1213
  88. package/src/types/ehr.ts +71 -53
  89. package/src/types/event.ts +19 -7
  90. package/src/types/helpdesk.ts +930 -840
  91. package/src/types/hire.ts +4453 -4019
  92. package/src/types/human_authentication.ts +35 -23
  93. package/src/types/im.ts +1626 -1476
  94. package/src/types/index.ts +1532 -346
  95. package/src/types/lingo.ts +299 -263
  96. package/src/types/mail.ts +1231 -779
  97. package/src/types/mdm.ts +122 -39
  98. package/src/types/minutes.ts +88 -28
  99. package/src/types/moments.ts +26 -14
  100. package/src/types/okr.ts +286 -238
  101. package/src/types/optical_char_recognition.ts +25 -13
  102. package/src/types/passport.ts +62 -50
  103. package/src/types/payroll.ts +254 -57
  104. package/src/types/performance.ts +528 -467
  105. package/src/types/personal_settings.ts +101 -89
  106. package/src/types/report.ts +86 -62
  107. package/src/types/search.ts +285 -249
  108. package/src/types/security_and_compliance.ts +33 -21
  109. package/src/types/sheets.ts +421 -379
  110. package/src/types/speech_to_text.ts +48 -36
  111. package/src/types/task.ts +1152 -1260
  112. package/src/types/tenant.ts +29 -17
  113. package/src/types/translation.ts +46 -34
  114. package/src/types/trust_party.ts +110 -0
  115. package/src/types/vc.ts +1397 -1283
  116. package/src/types/verification.ts +13 -7
  117. package/src/types/wiki.ts +293 -251
  118. package/src/types/workplace.ts +65 -41
  119. package/src/utils.ts +3 -3
package/src/internal.ts CHANGED
@@ -34,17 +34,26 @@ export interface InternalRoute {
34
34
  }
35
35
 
36
36
  export class Internal<C extends Context = Context> {
37
- constructor(private bot: LarkBot<C>) {}
37
+ constructor(bot: LarkBot<C>, tree = Internal._tree) {
38
+ return new Proxy(this, {
39
+ get: (target, prop) => {
40
+ if (typeof prop === 'symbol') return Reflect.get(target, prop)
41
+ const value = tree[prop]
42
+ if (typeof value === 'function') return value.bind(bot)
43
+ if (value) return new Internal(bot, value)
44
+ },
45
+ })
46
+ }
38
47
 
39
- private _assertResponse(response: HTTP.Response<BaseResponse>) {
48
+ private static _assertResponse(bot: LarkBot, response: HTTP.Response<BaseResponse>) {
40
49
  if (!response.data.code) return
41
- this.bot.logger.debug('response: %o', response.data)
50
+ bot.logger.debug('response: %o', response.data)
42
51
  const error = new HTTP.Error(`request failed`)
43
52
  error.response = response
44
53
  throw error
45
54
  }
46
55
 
47
- private _buildData(arg: object, options: InternalRoute) {
56
+ private static _buildData(arg: object, options: InternalRoute) {
48
57
  if (options.multipart) {
49
58
  const form = new FormData()
50
59
  for (const [key, value] of Object.entries(arg)) {
@@ -60,6 +69,8 @@ export class Internal<C extends Context = Context> {
60
69
  }
61
70
  }
62
71
 
72
+ private static _tree: Dict = Object.create(null)
73
+
63
74
  static define(routes: Dict<Partial<Record<HTTP.Method, string | InternalRoute>>>) {
64
75
  for (const path in routes) {
65
76
  for (const key in routes[path]) {
@@ -69,7 +80,7 @@ export class Internal<C extends Context = Context> {
69
80
  route = { name: route }
70
81
  }
71
82
 
72
- const impl = async function (this: Internal, ...args: any[]) {
83
+ const impl = async function (bot: LarkBot, ...args: any[]) {
73
84
  const raw = args.join(', ')
74
85
  const url = path.replace(/\{([^}]+)\}/g, () => {
75
86
  if (!args.length) throw new Error(`too few arguments for ${path}, received ${raw}`)
@@ -80,10 +91,10 @@ export class Internal<C extends Context = Context> {
80
91
  if (method === 'GET' || method === 'DELETE') {
81
92
  config.params = args[0]
82
93
  } else {
83
- config.data = this._buildData(args[0], route)
94
+ config.data = Internal._buildData(args[0], route)
84
95
  }
85
96
  } else if (args.length === 2 && method !== 'GET' && method !== 'DELETE') {
86
- config.data = this._buildData(args[0], route)
97
+ config.data = Internal._buildData(args[0], route)
87
98
  config.params = args[1]
88
99
  } else if (args.length > 1) {
89
100
  throw new Error(`too many arguments for ${path}, received ${raw}`)
@@ -91,8 +102,8 @@ export class Internal<C extends Context = Context> {
91
102
  if (route.type === 'binary') {
92
103
  config.responseType = 'arraybuffer'
93
104
  }
94
- const response = await this.bot.http(method, url, config)
95
- this._assertResponse(response)
105
+ const response = await bot.http(method, url, config)
106
+ Internal._assertResponse(bot, response)
96
107
  if (route.type === 'raw-json' || route.type === 'binary') {
97
108
  return response.data
98
109
  } else {
@@ -100,12 +111,18 @@ export class Internal<C extends Context = Context> {
100
111
  }
101
112
  }
102
113
 
103
- Internal.prototype[route.name] = function (this: Internal, ...args: any[]) {
114
+ let root = Internal._tree
115
+ const parts = route.name.split('.')
116
+ const lastPart = parts.pop()!
117
+ for (const part of parts) {
118
+ root = root[part] ??= Object.create(null)
119
+ }
120
+ root[lastPart] = function (this: LarkBot, ...args: any[]) {
104
121
  let promise: Promise<any> | undefined
105
122
  const result = {} as Paginated
106
123
  for (const key of ['then', 'catch', 'finally']) {
107
124
  result[key] = (...args2: any[]) => {
108
- return (promise ??= impl.apply(this, args))[key](...args2)
125
+ return (promise ??= impl(this, ...args))[key](...args2)
109
126
  }
110
127
  }
111
128
 
@@ -126,7 +143,7 @@ export class Internal<C extends Context = Context> {
126
143
  return this
127
144
  }
128
145
  result[Symbol.for('satori.pagination')] = async () => {
129
- const data = await impl.apply(this, iterArgs)
146
+ const data = await impl(this, ...iterArgs)
130
147
  iterArgs[argIndex].page_token = data[tokenKey]
131
148
  return {
132
149
  data: data[itemsKey],
package/src/message.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Context, Dict, h, MessageEncoder } from '@satorijs/core'
2
2
  import { LarkBot } from './bot'
3
- import { CreateImFileForm, Message } from './types'
3
+ import { Im, Message } from './types'
4
4
  import { EventPayload, extractIdType } from './utils'
5
5
  import { MessageContent } from './content'
6
6
 
@@ -11,8 +11,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
11
11
  private textContent = ''
12
12
  private richContent: MessageContent.RichText.Paragraph[] = []
13
13
  private card: MessageContent.Card | undefined
14
- private noteElements: MessageContent.Card.NoteElement.InnerElement[] | undefined
15
- private actionElements: MessageContent.Card.Element[] = []
14
+ private elements: MessageContent.Card.Element[] = []
16
15
  private isForm = false
17
16
 
18
17
  public editMessageIds: string[] | undefined
@@ -29,7 +28,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
29
28
  }
30
29
  } else if (this.referrer.type === 'card.action.trigger') {
31
30
  // cannot determine whether the card is in thread or not
32
- const { items: [message] } = await this.bot.internal.getImMessage(this.referrer.event.context.open_message_id)
31
+ const { items: [message] } = await this.bot.internal.im.message.get(this.referrer.event.context.open_message_id)
33
32
  if (message?.thread_id) {
34
33
  quote = {
35
34
  id: this.referrer.event.context.open_message_id,
@@ -43,18 +42,18 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
43
42
  if (!messageId) throw new Error('No message to edit')
44
43
  if (data.msg_type === 'interactive') {
45
44
  delete data.msg_type
46
- await this.bot.internal.patchImMessage(messageId, data)
45
+ await this.bot.internal.im.message.patch(messageId, data)
47
46
  } else {
48
- await this.bot.internal.updateImMessage(messageId, data)
47
+ await this.bot.internal.im.message.update(messageId, data)
49
48
  }
50
49
  } else if (quote?.id) {
51
- resp = await this.bot.internal.replyImMessage(quote.id, {
50
+ resp = await this.bot.internal.im.message.reply(quote.id, {
52
51
  ...data,
53
52
  reply_in_thread: quote.replyInThread,
54
53
  })
55
54
  } else {
56
55
  data.receive_id = this.channelId
57
- resp = await this.bot.internal.createImMessage(data, {
56
+ resp = await this.bot.internal.im.message.create(data, {
58
57
  receive_id_type: extractIdType(this.channelId),
59
58
  })
60
59
  }
@@ -79,20 +78,11 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
79
78
  }
80
79
  }
81
80
 
82
- private flushText(button = false) {
83
- if ((this.textContent || !button) && this.actionElements.length) {
84
- this.card!.elements.push({ tag: 'action', actions: this.actionElements, layout: 'flow' })
85
- this.actionElements = []
86
- }
87
- if (this.textContent) {
88
- this.richContent.push([{ tag: 'md', text: this.textContent }])
89
- if (this.noteElements) {
90
- this.noteElements.push({ tag: 'plain_text', content: this.textContent })
91
- } else if (this.card) {
92
- this.card.elements.push({ tag: 'markdown', content: this.textContent })
93
- }
94
- this.textContent = ''
95
- }
81
+ private flushText() {
82
+ if (!this.textContent) return
83
+ this.richContent.push([{ tag: 'md', text: this.textContent }])
84
+ this.elements.push({ tag: 'markdown', content: this.textContent })
85
+ this.textContent = ''
96
86
  }
97
87
 
98
88
  async flush() {
@@ -100,13 +90,11 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
100
90
  if (!this.card && !this.richContent.length) return
101
91
 
102
92
  if (this.card) {
103
- this.bot.logger.debug('card', JSON.stringify(this.card.elements))
93
+ // strip undefined properties
94
+ this.bot.logger.debug('card %o', JSON.parse(JSON.stringify(this.card)))
104
95
  await this.post({
105
96
  msg_type: 'interactive',
106
- content: JSON.stringify({
107
- header: this.card.header,
108
- elements: this.card.elements,
109
- }),
97
+ content: JSON.stringify(this.card),
110
98
  })
111
99
  } else {
112
100
  await this.post({
@@ -128,7 +116,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
128
116
 
129
117
  async createImage(url: string) {
130
118
  const { filename, type, data } = await this.bot.assetsQuester.file(url)
131
- const { image_key } = await this.bot.internal.createImImage({
119
+ const { image_key } = await this.bot.internal.im.image.create({
132
120
  image_type: 'message',
133
121
  image: new File([data], filename, { type }),
134
122
  })
@@ -149,7 +137,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
149
137
 
150
138
  const { filename, type, data } = await this.bot.assetsQuester.file(url)
151
139
 
152
- let file_type: CreateImFileForm['file_type']
140
+ let file_type: Im.File.CreateForm['file_type']
153
141
  if (_type === 'audio') {
154
142
  // FIXME: only support opus
155
143
  file_type = 'opus'
@@ -165,7 +153,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
165
153
  }
166
154
  }
167
155
 
168
- const form: CreateImFileForm = {
156
+ const form: Im.File.CreateForm = {
169
157
  file_type,
170
158
  file: new File([data], filename, { type }),
171
159
  file_name: filename,
@@ -174,21 +162,21 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
174
162
  form.duration = attrs.duration
175
163
  }
176
164
 
177
- const { file_key } = await this.bot.internal.createImFile(form)
165
+ const { file_key } = await this.bot.internal.im.file.create(form)
178
166
  await this.post({
179
167
  msg_type: _type === 'video' ? 'media' : _type,
180
168
  content: JSON.stringify({ file_key }),
181
169
  })
182
170
  }
183
171
 
184
- private createBehavior(attrs: Dict) {
172
+ private createBehaviors(attrs: Dict) {
185
173
  const behaviors: MessageContent.Card.ActionBehavior[] = []
186
174
  if (attrs.type === 'link') {
187
175
  behaviors.push({
188
176
  type: 'open_url',
189
177
  default_url: attrs.href,
190
178
  })
191
- } else if (attrs.type === 'input') {
179
+ } else if (attrs.type === 'input' || attrs.type === 'submit') {
192
180
  behaviors.push({
193
181
  type: 'callback',
194
182
  value: {
@@ -248,26 +236,24 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
248
236
  } else if (type === 'hr') {
249
237
  this.flushText()
250
238
  this.richContent.push([{ tag: 'hr' }])
251
- this.card?.elements.push({ tag: 'hr' })
239
+ this.elements.push({ tag: 'hr' })
252
240
  } else if (type === 'form') {
253
241
  this.flushText()
254
- const length = this.card?.elements.length
242
+ const parent = this.elements
243
+ parent.push({
244
+ tag: 'form',
245
+ name: attrs.name || 'Form',
246
+ elements: this.elements = [],
247
+ })
255
248
  this.isForm = true
256
249
  await this.render(children)
257
250
  this.isForm = false
258
- if (this.card?.elements.length > length) {
259
- const elements = this.card?.elements.splice(length)
260
- this.card.elements.push({
261
- tag: 'form',
262
- name: attrs.name || 'Form',
263
- elements,
264
- })
265
- }
251
+ this.elements = parent
266
252
  } else if (type === 'input') {
267
253
  if (attrs.type === 'checkbox') {
268
254
  this.flushText()
269
255
  await this.render(children)
270
- this.card?.elements.push({
256
+ this.elements.push({
271
257
  tag: 'checker',
272
258
  name: (attrs.argument ? '@@' : attrs.option ? `@${attrs.option}=` : '') + attrs.name,
273
259
  checked: attrs.value,
@@ -278,20 +264,17 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
278
264
  })
279
265
  this.textContent = ''
280
266
  } else if (attrs.type === 'submit') {
281
- this.flushText(true)
267
+ this.flushText()
282
268
  await this.render(children)
283
- this.card?.elements.push({
269
+ this.elements.push({
284
270
  tag: 'button',
285
271
  name: attrs.name,
286
272
  text: {
287
273
  tag: 'plain_text',
288
274
  content: this.textContent,
289
275
  },
290
- action_type: 'form_submit',
291
- value: {
292
- _satori_type: 'command',
293
- content: attrs.text,
294
- },
276
+ form_action_type: 'submit',
277
+ behaviors: this.createBehaviors(attrs),
295
278
  })
296
279
  this.textContent = ''
297
280
  } else {
@@ -311,18 +294,9 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
311
294
  default_value: attrs.value,
312
295
  disabled: attrs.disabled,
313
296
  required: attrs.required,
297
+ behaviors: this.createBehaviors(attrs),
314
298
  }
315
- if (this.isForm) {
316
- this.card?.elements.push(input)
317
- } else {
318
- this.card?.elements.push({
319
- tag: 'action',
320
- actions: [{
321
- ...input,
322
- behaviors: this.createBehavior(attrs),
323
- }],
324
- })
325
- }
299
+ this.elements.push(input)
326
300
  }
327
301
  } else if (type === 'select') {
328
302
  this.flushText()
@@ -338,6 +312,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
338
312
  content: attrs.placeholder,
339
313
  },
340
314
  options: [],
315
+ behaviors: this.createBehaviors(attrs),
341
316
  }
342
317
  for (const child of children) {
343
318
  if (child.type !== 'option') continue
@@ -351,29 +326,17 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
351
326
  })
352
327
  this.textContent = ''
353
328
  }
354
- if (this.isForm) {
355
- this.card?.elements.push(select)
356
- } else {
357
- this.card?.elements.push({
358
- tag: 'action',
359
- actions: [{
360
- ...select,
361
- behaviors: this.createBehavior(attrs),
362
- }],
363
- })
364
- }
329
+ this.elements.push(select)
365
330
  } else if (type === 'button') {
366
- this.card ??= { elements: [] }
367
- this.flushText(true)
331
+ this.flushText()
368
332
  await this.render(children)
369
- this.actionElements.push({
333
+ this.elements.push({
370
334
  tag: 'button',
371
335
  text: {
372
336
  tag: 'plain_text',
373
337
  content: this.textContent,
374
338
  },
375
339
  disabled: attrs.disabled,
376
- behaviors: this.createBehavior(attrs),
377
340
  type: attrs['lark:type'],
378
341
  size: attrs['lark:size'],
379
342
  width: attrs['lark:width'],
@@ -389,12 +352,24 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
389
352
  tag: 'plain_text',
390
353
  content: attrs['lark:disabled-tips'],
391
354
  },
355
+ behaviors: this.createBehaviors(attrs),
392
356
  })
393
357
  this.textContent = ''
394
- } else if (type === 'button-group') {
358
+ } else if (type === 'div') {
395
359
  this.flushText()
396
360
  await this.render(children)
397
- this.flushText()
361
+ this.elements.push({
362
+ tag: 'markdown',
363
+ text_align: attrs.align,
364
+ text_size: attrs.size,
365
+ content: this.textContent,
366
+ margin: attrs.margin,
367
+ icon: attrs.icon && {
368
+ tag: 'standard_icon',
369
+ token: attrs.icon,
370
+ },
371
+ })
372
+ this.textContent = ''
398
373
  } else if (type.startsWith('lark:') || type.startsWith('feishu:')) {
399
374
  const tag = type.slice(type.split(':', 1)[0].length + 1)
400
375
  if (tag === 'share-chat') {
@@ -424,7 +399,7 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
424
399
  } else if (tag === 'card') {
425
400
  await this.flush()
426
401
  this.card = {
427
- elements: [],
402
+ schema: '2.0',
428
403
  header: attrs.title && {
429
404
  template: attrs.color,
430
405
  ud_icon: attrs.icon && {
@@ -440,39 +415,15 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
440
415
  content: attrs.subtitle,
441
416
  },
442
417
  },
418
+ body: {
419
+ elements: this.elements = [],
420
+ },
443
421
  }
444
422
  await this.render(children, true)
445
- } else if (tag === 'div') {
446
- this.flushText()
447
- await this.render(children)
448
- this.card?.elements.push({
449
- tag: 'markdown',
450
- text_align: attrs.align,
451
- text_size: attrs.size,
452
- content: this.textContent,
453
- })
454
- this.textContent = ''
455
- } else if (tag === 'note') {
456
- this.flushText()
457
- this.noteElements = []
458
- await this.render(children)
459
- this.flushText()
460
- this.card?.elements.push({
461
- tag: 'note',
462
- elements: this.noteElements,
463
- })
464
- this.noteElements = undefined
465
- } else if (tag === 'icon') {
466
- this.flushText()
467
- this.noteElements?.push({
468
- tag: 'standard_icon',
469
- token: attrs.token,
470
- })
471
423
  } else if (tag === 'column-set') {
472
424
  this.flushText()
473
- const parent = this.card
474
425
  const columns: MessageContent.Card.ColumnElement[] = []
475
- parent?.elements.push({
426
+ this.elements.push({
476
427
  tag: 'column_set',
477
428
  margin: attrs.margin,
478
429
  flex_mode: attrs.flexMode,
@@ -481,12 +432,13 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
481
432
  background_style: attrs.backgroundStyle,
482
433
  columns,
483
434
  })
435
+ const parent = this.elements
484
436
  for (const child of children) {
485
437
  if (child.type !== 'lark:column' && child.type !== 'feishu:column') {
486
438
  // throw unexpected?
487
439
  continue
488
440
  }
489
- this.card = { elements: [] }
441
+ this.elements = []
490
442
  await this.render(child.children)
491
443
  this.flushText()
492
444
  columns.push({
@@ -497,11 +449,30 @@ export class LarkMessageEncoder<C extends Context = Context> extends MessageEnco
497
449
  vertical_align: child.attrs.verticalAlign ?? 'center',
498
450
  vertical_spacing: child.attrs.verticalSpacing ?? '0px',
499
451
  background_style: child.attrs.backgroundStyle,
500
- elements: this.card.elements,
452
+ elements: this.elements,
501
453
  })
502
454
  }
503
- this.card = parent
455
+ this.elements = parent
504
456
  }
457
+ } else if (type === 'button-group') {
458
+ this.flushText()
459
+ const parent = this.elements
460
+ this.elements = []
461
+ await this.render(children)
462
+ this.flushText()
463
+ parent.push({
464
+ tag: 'column_set',
465
+ margin: attrs.margin,
466
+ flex_mode: attrs.flexMode,
467
+ horizontal_align: attrs.horizontalAlign,
468
+ horizontal_spacing: attrs.horizontalSpacing,
469
+ background_style: attrs.backgroundStyle,
470
+ columns: this.elements.map((element) => ({
471
+ tag: 'column',
472
+ elements: [element],
473
+ })),
474
+ })
475
+ this.elements = parent
505
476
  } else {
506
477
  await this.render(children)
507
478
  }