@juzi/wechaty 1.0.23 → 1.0.26

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 (77) hide show
  1. package/dist/cjs/src/config.d.ts +2 -0
  2. package/dist/cjs/src/config.d.ts.map +1 -1
  3. package/dist/cjs/src/config.js +3 -1
  4. package/dist/cjs/src/config.js.map +1 -1
  5. package/dist/cjs/src/package-json.js +4 -4
  6. package/dist/cjs/src/pure-functions/update.d.ts +1 -0
  7. package/dist/cjs/src/pure-functions/update.d.ts.map +1 -1
  8. package/dist/cjs/src/pure-functions/update.js +12 -1
  9. package/dist/cjs/src/pure-functions/update.js.map +1 -1
  10. package/dist/cjs/src/schemas/wechaty-events.d.ts +8 -2
  11. package/dist/cjs/src/schemas/wechaty-events.d.ts.map +1 -1
  12. package/dist/cjs/src/schemas/wechaty-events.js.map +1 -1
  13. package/dist/cjs/src/user-modules/contact.d.ts.map +1 -1
  14. package/dist/cjs/src/user-modules/contact.js +7 -20
  15. package/dist/cjs/src/user-modules/contact.js.map +1 -1
  16. package/dist/cjs/src/user-modules/tag-group.d.ts +55 -20
  17. package/dist/cjs/src/user-modules/tag-group.d.ts.map +1 -1
  18. package/dist/cjs/src/user-modules/tag-group.js +113 -44
  19. package/dist/cjs/src/user-modules/tag-group.js.map +1 -1
  20. package/dist/cjs/src/user-modules/tag.d.ts +58 -24
  21. package/dist/cjs/src/user-modules/tag.d.ts.map +1 -1
  22. package/dist/cjs/src/user-modules/tag.js +142 -51
  23. package/dist/cjs/src/user-modules/tag.js.map +1 -1
  24. package/dist/cjs/src/wechaty/wechaty-base.d.ts +7 -7
  25. package/dist/cjs/src/wechaty-mixins/gerror-mixin.d.ts +1 -1
  26. package/dist/cjs/src/wechaty-mixins/io-mixin.d.ts +2 -2
  27. package/dist/cjs/src/wechaty-mixins/login-mixin.d.ts +5 -5
  28. package/dist/cjs/src/wechaty-mixins/misc-mixin.d.ts +5 -5
  29. package/dist/cjs/src/wechaty-mixins/plugin-mixin.d.ts +6 -6
  30. package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts +32 -6
  31. package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
  32. package/dist/cjs/src/wechaty-mixins/puppet-mixin.js +92 -10
  33. package/dist/cjs/src/wechaty-mixins/puppet-mixin.js.map +1 -1
  34. package/dist/cjs/src/wechaty-mixins/wechatify-user-module-mixin.d.ts +1 -1
  35. package/dist/esm/src/config.d.ts +2 -0
  36. package/dist/esm/src/config.d.ts.map +1 -1
  37. package/dist/esm/src/config.js +2 -0
  38. package/dist/esm/src/config.js.map +1 -1
  39. package/dist/esm/src/package-json.js +4 -4
  40. package/dist/esm/src/pure-functions/update.d.ts +1 -0
  41. package/dist/esm/src/pure-functions/update.d.ts.map +1 -1
  42. package/dist/esm/src/pure-functions/update.js +10 -0
  43. package/dist/esm/src/pure-functions/update.js.map +1 -1
  44. package/dist/esm/src/schemas/wechaty-events.d.ts +8 -2
  45. package/dist/esm/src/schemas/wechaty-events.d.ts.map +1 -1
  46. package/dist/esm/src/schemas/wechaty-events.js.map +1 -1
  47. package/dist/esm/src/user-modules/contact.d.ts.map +1 -1
  48. package/dist/esm/src/user-modules/contact.js +7 -20
  49. package/dist/esm/src/user-modules/contact.js.map +1 -1
  50. package/dist/esm/src/user-modules/tag-group.d.ts +55 -20
  51. package/dist/esm/src/user-modules/tag-group.d.ts.map +1 -1
  52. package/dist/esm/src/user-modules/tag-group.js +114 -45
  53. package/dist/esm/src/user-modules/tag-group.js.map +1 -1
  54. package/dist/esm/src/user-modules/tag.d.ts +58 -24
  55. package/dist/esm/src/user-modules/tag.d.ts.map +1 -1
  56. package/dist/esm/src/user-modules/tag.js +120 -52
  57. package/dist/esm/src/user-modules/tag.js.map +1 -1
  58. package/dist/esm/src/wechaty/wechaty-base.d.ts +7 -7
  59. package/dist/esm/src/wechaty-mixins/gerror-mixin.d.ts +1 -1
  60. package/dist/esm/src/wechaty-mixins/io-mixin.d.ts +2 -2
  61. package/dist/esm/src/wechaty-mixins/login-mixin.d.ts +5 -5
  62. package/dist/esm/src/wechaty-mixins/misc-mixin.d.ts +5 -5
  63. package/dist/esm/src/wechaty-mixins/plugin-mixin.d.ts +6 -6
  64. package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts +32 -6
  65. package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
  66. package/dist/esm/src/wechaty-mixins/puppet-mixin.js +94 -12
  67. package/dist/esm/src/wechaty-mixins/puppet-mixin.js.map +1 -1
  68. package/dist/esm/src/wechaty-mixins/wechatify-user-module-mixin.d.ts +1 -1
  69. package/package.json +3 -3
  70. package/src/config.ts +3 -0
  71. package/src/package-json.ts +4 -4
  72. package/src/pure-functions/update.ts +11 -0
  73. package/src/schemas/wechaty-events.ts +7 -0
  74. package/src/user-modules/contact.ts +7 -20
  75. package/src/user-modules/tag-group.ts +147 -53
  76. package/src/user-modules/tag.ts +126 -58
  77. package/src/wechaty-mixins/puppet-mixin.ts +106 -12
@@ -18,60 +18,69 @@
18
18
  *
19
19
  */
20
20
  import type * as PUPPET from '@juzi/wechaty-puppet'
21
+ import type { TagGroupQueryFilter } from '@juzi/wechaty-puppet/dist/esm/src/schemas/tag.js'
21
22
 
22
23
  import type { Constructor } from 'clone-class'
24
+ import { concurrencyExecuter } from 'rx-queue'
23
25
  import { log } from '../config.js'
26
+ import { poolifyMixin } from '../user-mixins/poolify.js'
24
27
 
25
28
  import { validationMixin } from '../user-mixins/validation.js'
26
29
  import {
27
- wechatifyMixinBase,
30
+ wechatifyMixin,
28
31
  } from '../user-mixins/wechatify.js'
29
32
  import type { TagInterface } from './tag.js'
30
33
 
31
- class TagGroupMixin extends wechatifyMixinBase() {
34
+ const MixinBase = wechatifyMixin(
35
+ poolifyMixin(
36
+ Object,
37
+ )<TagGroupImplInterface>(),
38
+ )
39
+
40
+ class TagGroupMixin extends MixinBase {
32
41
 
33
42
  /**
34
43
  *
35
- * Create
44
+ * Instance properties
45
+ * @ignore
36
46
  *
37
47
  */
38
- static create (payload: PUPPET.payloads.TagGroup): TagGroupInterface {
39
- log.verbose('TagGroup', 'create()')
40
-
41
- return new this(payload)
42
- }
48
+ payload?: PUPPET.payloads.TagGroup
43
49
 
44
50
  /**
45
51
  * @hideconstructor
46
52
  */
47
53
  constructor (
48
- public readonly payload: PUPPET.payloads.TagGroup,
54
+ public readonly id: string,
49
55
  ) {
50
56
  super()
51
57
  log.silly('TagGroup', 'constructor()')
52
58
  }
53
59
 
54
- id (): string {
55
- return this.payload.id
56
- }
57
-
58
60
  name (): string {
59
- return this.payload.name
61
+ return (this.payload && this.payload.name) || ''
60
62
  }
61
63
 
62
- private static pool: TagGroupInterface[] = []
64
+ static async list (): Promise<TagGroupInterface[]> {
65
+ log.verbose('TagGroup', 'list()')
63
66
 
64
- static async list (forceSync = false): Promise<TagGroupInterface[]> {
65
- log.verbose('TagGroup', 'list(%s)', forceSync)
67
+ try {
68
+ const tagGroupIds = await this.wechaty.puppet.tagGroupList()
66
69
 
67
- if (this.pool.length > 0 && !forceSync) {
68
- return this.pool
69
- }
70
+ const idToTagGroup = async (id: string) => this.find({ id }).catch(e => this.wechaty.emitError(e))
71
+
72
+ const CONCURRENCY = 17
73
+ const tagGroupIterator = concurrencyExecuter(CONCURRENCY)(idToTagGroup)(tagGroupIds)
74
+
75
+ const tagGroupList: TagGroupInterface[] = []
76
+ for await (const tagGroup of tagGroupIterator) {
77
+ if (tagGroup) {
78
+ tagGroupList.push(tagGroup)
79
+ }
80
+ }
81
+
82
+ return tagGroupList
70
83
 
71
- try {
72
- const payloads = await this.wechaty.puppet.tagGroupList()
73
- this.pool = payloads.map(payload => new this(payload))
74
- return this.pool
75
84
  } catch (e) {
76
85
  this.wechaty.emitError(e)
77
86
  log.error('TagGroup', 'list() exception: %s', (e as Error).message)
@@ -79,31 +88,13 @@ class TagGroupMixin extends wechatifyMixinBase() {
79
88
  }
80
89
  }
81
90
 
82
- static async sync (): Promise<void> {
83
- log.verbose('TagGroup', 'sync()')
84
-
85
- await this.list(true)
86
- }
87
-
88
- static load (tagGroupId: string): TagGroupInterface | undefined {
89
- log.verbose('TagGroup', 'load(%s)', tagGroupId)
90
-
91
- for (const item of this.pool) {
92
- if (item.id() === tagGroupId) {
93
- return item
94
- }
95
- }
96
- return undefined
97
- }
98
-
99
91
  static async createTagGroup (name: string): Promise<TagGroupInterface | void> {
100
92
  log.verbose('TagGroup', 'createTagGroup(%s, %s)', name)
101
93
 
102
94
  try {
103
- const payload = await this.wechaty.puppet.tagGroupAdd(name)
104
- if (payload) {
105
- const newTagGroup = new this(payload)
106
- this.pool.push(newTagGroup)
95
+ const groupId = await this.wechaty.puppet.tagGroupAdd(name)
96
+ if (groupId) {
97
+ const newTagGroup = await this.find({ id: groupId })
107
98
  return newTagGroup
108
99
  }
109
100
  } catch (e) {
@@ -116,8 +107,7 @@ class TagGroupMixin extends wechatifyMixinBase() {
116
107
  log.verbose('TagGroup', 'deleteTagGroup(%s)', tagGroup)
117
108
 
118
109
  try {
119
- await this.wechaty.puppet.tagGroupDelete(tagGroup.id())
120
- this.pool.splice(this.pool.indexOf(tagGroup), 1)
110
+ await this.wechaty.puppet.tagGroupDelete(tagGroup.id)
121
111
  } catch (e) {
122
112
  this.wechaty.emitError(e)
123
113
  log.error('TagGroup', 'deleteTagGroup() exception: %s', (e as Error).message)
@@ -125,25 +115,129 @@ class TagGroupMixin extends wechatifyMixinBase() {
125
115
  }
126
116
 
127
117
  async tags (): Promise<TagInterface[]> {
128
- return (await this.wechaty.Tag.list()).filter(tag => tag.groupId() === this.id())
118
+ log.verbose('TagGroup', 'tags(%s)', this)
119
+ try {
120
+ const tagIdList = await this.wechaty.puppet.tagGroupTagList(this.id)
121
+
122
+ const idToTag = async (tagId: string) => this.wechaty.Tag.find({ id: tagId }).catch(e => this.wechaty.emitError(e))
123
+
124
+ const CONCURRENCY = 17
125
+ const tagIterator = concurrencyExecuter(CONCURRENCY)(idToTag)(tagIdList)
126
+
127
+ const tagList: TagInterface[] = []
128
+ for await (const tag of tagIterator) {
129
+ if (tag) {
130
+ tagList.push(tag)
131
+ }
132
+ }
133
+ return tagList
134
+
135
+ } catch (e) {
136
+ this.wechaty.emitError(e)
137
+ log.error('TagGroup', 'list() exception: %s', (e as Error).message)
138
+ return []
139
+ }
140
+
141
+ }
142
+
143
+ static async find (filter: TagGroupQueryFilter): Promise<TagGroupInterface | undefined> {
144
+ log.silly('TagGroup', 'find(%s)', JSON.stringify(filter))
145
+
146
+ if (filter.id) {
147
+ const tagGroup = (this.wechaty.TagGroup as any as typeof TagGroupImpl).load(filter.id)
148
+
149
+ try {
150
+ await tagGroup.ready()
151
+ } catch (e) {
152
+ this.wechaty.emitError(e)
153
+ return undefined
154
+ }
155
+ return tagGroup
156
+ }
157
+
158
+ if (filter.name) {
159
+ const tagGroups = (await this.wechaty.TagGroup.list()).filter(tagGroup => tagGroup.name() === filter.name)
160
+ if (tagGroups.length > 0) {
161
+ return tagGroups[0]
162
+ }
163
+ }
164
+
165
+ return undefined
166
+ // TODO: use a puppet method to find tag, like how contact and room do it
167
+ }
168
+
169
+ /**
170
+ * Force reload data for TagGroup, Sync data from low-level API again.
171
+ *
172
+ * @returns {Promise<this>}
173
+ * @example
174
+ * await tagGroup.sync()
175
+ */
176
+ async sync (): Promise<void> {
177
+ await this.wechaty.puppet.tagGroupPayloadDirty(this.id)
178
+ await this.ready(true)
179
+ }
180
+
181
+ /**
182
+ * @ignore
183
+ */
184
+ isReady (): boolean {
185
+ return !!(this.payload)
186
+ }
187
+
188
+ /**
189
+ * `ready()` is For FrameWork ONLY!
190
+ *
191
+ * Please not to use `ready()` at the user land.
192
+ * If you want to sync data, use `sync()` instead.
193
+ *
194
+ * @ignore
195
+ */
196
+ async ready (
197
+ forceSync = false,
198
+ ): Promise<void> {
199
+ log.silly('TagGroup', 'ready() @ %s with TagGroup="%s"', this.wechaty.puppet, this.id)
200
+
201
+ if (!forceSync && this.isReady()) { // already ready
202
+ log.silly('TagGroup', 'ready() isReady() true')
203
+ return
204
+ }
205
+
206
+ try {
207
+ this.payload = await this.wechaty.puppet.tagGroupPayload(this.id)
208
+ } catch (e) {
209
+ this.wechaty.emitError(e)
210
+ log.verbose('TagGroup', 'ready() this.wechaty.puppet.tagGroupPayload(%s) exception: %s',
211
+ this.id,
212
+ (e as Error).message,
213
+ )
214
+ throw e
215
+ }
129
216
  }
130
217
 
131
218
  override toString () {
132
- return `<TagGroup#${this.name() || this.id()}>`
219
+ return `<TagGroup#${this.name() || this.id}>`
133
220
  }
134
221
 
135
222
  }
136
223
 
137
- class TagGroupImpl extends validationMixin(TagGroupMixin)<TagGroupInterface>() { }
138
- interface TagGroupInterface extends TagGroupImpl { }
224
+ class TagGroupImplBase extends validationMixin(TagGroupMixin)<TagGroupImplInterface>() { }
225
+ interface TagGroupImplInterface extends TagGroupImplBase { }
226
+
227
+ type TagGroupProtectedProperty =
228
+ | 'ready'
229
+
230
+ type TagGroupInterface = Omit<TagGroupImplInterface, TagGroupProtectedProperty>
231
+ class TagGroupImpl extends validationMixin(TagGroupImplBase)<TagGroupInterface>() { }
139
232
 
140
233
  type TagGroupConstructor = Constructor<
141
- TagGroupInterface,
142
- typeof TagGroupImpl
234
+ TagGroupImplInterface,
235
+ Omit<typeof TagGroupImpl, 'load'>
143
236
  >
144
237
 
145
238
  export type {
146
239
  TagGroupConstructor,
240
+ TagGroupProtectedProperty,
147
241
  TagGroupInterface,
148
242
  }
149
243
  export {
@@ -17,75 +17,83 @@
17
17
  * limitations under the License.
18
18
  *
19
19
  */
20
- import type * as PUPPET from '@juzi/wechaty-puppet'
21
- import type { TagIdentifier } from '@juzi/wechaty-puppet/filters'
20
+ import * as PUPPET from '@juzi/wechaty-puppet'
21
+ import type { TagQueryFilter } from '@juzi/wechaty-puppet/dist/esm/src/schemas/tag.js'
22
22
 
23
23
  import type { Constructor } from 'clone-class'
24
+ import { concurrencyExecuter } from 'rx-queue'
24
25
  import { log } from '../config.js'
26
+ import { poolifyMixin } from '../user-mixins/poolify.js'
25
27
 
26
28
  import { validationMixin } from '../user-mixins/validation.js'
27
29
  import {
28
- wechatifyMixinBase,
30
+ wechatifyMixin,
29
31
  } from '../user-mixins/wechatify.js'
30
32
  import type { ContactInterface } from './contact.js'
31
33
  import type { TagGroupInterface } from './tag-group.js'
32
34
 
33
- class TagMixin extends wechatifyMixinBase() {
35
+ const MixinBase = wechatifyMixin(
36
+ poolifyMixin(
37
+ Object,
38
+ )<TagImplInterface>(),
39
+ )
40
+
41
+ class TagMixin extends MixinBase {
34
42
 
35
43
  /**
36
44
  *
37
- * Create
45
+ * Instance properties
46
+ * @ignore
38
47
  *
39
48
  */
40
- static create (payload: PUPPET.payloads.Tag): TagInterface {
41
- log.verbose('Tag', 'create()')
42
-
43
- return new this(payload)
44
- }
49
+ payload?: PUPPET.payloads.Tag
45
50
 
46
51
  /**
47
52
  * @hideconstructor
48
53
  */
49
54
  constructor (
50
- public readonly payload: PUPPET.payloads.Tag,
55
+ public readonly id: string,
51
56
  ) {
52
57
  super()
53
58
  log.silly('Tag', 'constructor()')
54
59
  }
55
60
 
56
- id (): string {
57
- return this.payload.id
61
+ type (): PUPPET.types.Tag {
62
+ return (this.payload && this.payload.type) || PUPPET.types.Tag.Unspecific
58
63
  }
59
64
 
60
- type (): PUPPET.types.Tag {
61
- return this.payload.type
65
+ name (): string {
66
+ return (this.payload && this.payload.name) || ''
62
67
  }
63
68
 
64
69
  groupId (): string {
65
- return this.payload.groupId || ''
70
+ return (this.payload && this.payload.groupId) || ''
66
71
  }
67
72
 
68
- name (): string {
69
- return this.payload.name
73
+ async group (): Promise<TagGroupInterface | undefined> {
74
+ return this.payload?.groupId ? this.wechaty.TagGroup.find({ id: this.payload.groupId }) : undefined
70
75
  }
71
76
 
72
- group (): TagGroupInterface | undefined {
73
- return this.wechaty.TagGroup.load(this.groupId())
74
- }
77
+ static async list (): Promise<TagInterface[]> {
78
+ log.verbose('Tag', 'list()')
75
79
 
76
- private static pool: TagInterface[] = []
80
+ try {
81
+ const tagIdList = await this.wechaty.puppet.tagTagList()
77
82
 
78
- static async list (forceSync = false): Promise<TagInterface[]> {
79
- log.verbose('Tag', 'list(%s)', forceSync)
83
+ const idToTag = async (id: string) => this.find({ id }).catch(e => this.wechaty.emitError(e))
80
84
 
81
- if (this.pool.length > 0 && !forceSync) {
82
- return this.pool
83
- }
85
+ const CONCURRENCY = 17
86
+ const tagIterator = concurrencyExecuter(CONCURRENCY)(idToTag)(tagIdList)
87
+
88
+ const tagList: TagInterface[] = []
89
+ for await (const tag of tagIterator) {
90
+ if (tag) {
91
+ tagList.push(tag)
92
+ }
93
+ }
94
+
95
+ return tagList
84
96
 
85
- try {
86
- const payloads = await this.wechaty.puppet.tagTagList()
87
- this.pool = payloads.map(payload => new this(payload))
88
- return this.pool
89
97
  } catch (e) {
90
98
  this.wechaty.emitError(e)
91
99
  log.error('Tag', 'list() exception: %s', (e as Error).message)
@@ -93,28 +101,86 @@ class TagMixin extends wechatifyMixinBase() {
93
101
  }
94
102
  }
95
103
 
96
- static async sync (): Promise<void> {
97
- log.verbose('Tag', 'sync()')
104
+ static async find (filter: TagQueryFilter): Promise<TagInterface | undefined> {
105
+ log.silly('Tag', 'find(%s)', JSON.stringify(filter))
98
106
 
99
- await this.list(true)
100
- }
107
+ if (filter.id) {
108
+ const tag = (this.wechaty.Tag as any as typeof TagImpl).load(filter.id)
101
109
 
102
- static load (tag: TagIdentifier): TagInterface | undefined {
103
- log.verbose('TagGroup', 'load(%s)', tag)
110
+ try {
111
+ await tag.ready()
112
+ } catch (e) {
113
+ this.wechaty.emitError(e)
114
+ return undefined
115
+ }
116
+ return tag
117
+ }
104
118
 
105
- for (const item of this.pool) {
106
- if (item.id() === tag.id && (item.groupId() === tag.groupId || (!item.groupId() && !tag.groupId))) {
107
- return item
119
+ if (filter.name) {
120
+ const tags = (await this.wechaty.Tag.list()).filter(t => t.name() === filter.name)
121
+ if (tags.length > 0) {
122
+ return tags[0]
108
123
  }
109
124
  }
125
+
110
126
  return undefined
127
+ // TODO: use a puppet method to find tag, like how contact and room do it
128
+ }
129
+
130
+ /**
131
+ * Force reload data for Tag, Sync data from low-level API again.
132
+ *
133
+ * @returns {Promise<this>}
134
+ * @example
135
+ * await tag.sync()
136
+ */
137
+ async sync (): Promise<void> {
138
+ await this.wechaty.puppet.tagPayloadDirty(this.id)
139
+ await this.ready(true)
140
+ }
141
+
142
+ /**
143
+ * @ignore
144
+ */
145
+ isReady (): boolean {
146
+ return !!(this.payload && this.payload.name)
147
+ }
148
+
149
+ /**
150
+ * `ready()` is For FrameWork ONLY!
151
+ *
152
+ * Please not to use `ready()` at the user land.
153
+ * If you want to sync data, use `sync()` instead.
154
+ *
155
+ * @ignore
156
+ */
157
+ async ready (
158
+ forceSync = false,
159
+ ): Promise<void> {
160
+ log.silly('Tag', 'ready() @ %s with Tag key="%s"', this.wechaty.puppet, this.id)
161
+
162
+ if (!forceSync && this.isReady()) { // already ready
163
+ log.silly('Tag', 'ready() isReady() true')
164
+ return
165
+ }
166
+
167
+ try {
168
+ this.payload = await this.wechaty.puppet.tagPayload(this.id)
169
+
170
+ } catch (e) {
171
+ this.wechaty.emitError(e)
172
+ log.verbose('Tag', 'ready() this.wechaty.puppet.tagPayload(%s) exception: %s',
173
+ this.id,
174
+ (e as Error).message,
175
+ )
176
+ throw e
177
+ }
111
178
  }
112
179
 
113
180
  async contactList (): Promise<ContactInterface[]> {
114
181
  log.verbose('Tag', 'contactList() for tag : %s', this)
115
182
 
116
- const tag = { id: this.id(), groupId: this.groupId() } as TagIdentifier
117
- const contactIds = await this.wechaty.puppet.tagTagContactList(tag)
183
+ const contactIds = await this.wechaty.puppet.tagTagContactList(this.id)
118
184
  const contactPromises = contactIds.map(id => this.wechaty.Contact.find({ id })) as Promise<ContactInterface>[]
119
185
  return Promise.all(contactPromises)
120
186
  }
@@ -122,40 +188,35 @@ class TagMixin extends wechatifyMixinBase() {
122
188
  async tag (contacts: ContactInterface | ContactInterface[]): Promise<void> {
123
189
  log.verbose('Tag', 'tag(%s) for tag : %s', contacts, this)
124
190
 
125
- const tag = { id: this.id(), groupId: this.groupId() } as TagIdentifier
126
191
  let contactIds: string[]
127
192
  if (Array.isArray(contacts)) {
128
193
  contactIds = contacts.map(c => c.id)
129
194
  } else {
130
195
  contactIds = [contacts.id]
131
196
  }
132
- await this.wechaty.puppet.tagContactTagAdd([tag], contactIds)
197
+ await this.wechaty.puppet.tagContactTagAdd([this.id], contactIds)
133
198
  }
134
199
 
135
200
  static async createTag (name: string, tagGroup?: TagGroupInterface): Promise<TagInterface | void> {
136
201
  log.verbose('Tag', 'createTag(%s, %s)', tagGroup, name)
137
202
 
138
203
  try {
139
- const payload = await this.wechaty.puppet.tagTagAdd(name, tagGroup?.name())
140
- if (payload) {
141
- const newTag = new this(payload)
142
- this.pool.push(newTag)
204
+ const tagId = await this.wechaty.puppet.tagTagAdd(name, tagGroup?.name())
205
+ if (tagId) {
206
+ const newTag = await this.find({ id: tagId })
143
207
  return newTag
144
208
  }
145
209
  } catch (e) {
146
210
  this.wechaty.emitError(e)
147
- log.error('Contact', 'createTag() exception: %s', (e as Error).message)
211
+ log.error('Tag', 'createTag() exception: %s', (e as Error).message)
148
212
  }
149
213
  }
150
214
 
151
215
  static async deleteTag (tagInstance: TagInterface): Promise<void> {
152
216
  log.verbose('Tag', 'deleteTag(%s, %s)', tagInstance)
153
217
 
154
- const tag = { id: tagInstance.id(), groupId: tagInstance.groupId() } as TagIdentifier
155
-
156
218
  try {
157
- await this.wechaty.puppet.tagTagDelete(tag)
158
- this.pool.splice(this.pool.indexOf(tagInstance), 1)
219
+ await this.wechaty.puppet.tagTagDelete(tagInstance.id)
159
220
  } catch (e) {
160
221
  this.wechaty.emitError(e)
161
222
  log.error('Tag', 'deleteTag() exception: %s', (e as Error).message)
@@ -163,21 +224,28 @@ class TagMixin extends wechatifyMixinBase() {
163
224
  }
164
225
 
165
226
  override toString () {
166
- return `<Tag#${this.name() || this.id()}>`
227
+ return `<Tag#${this.name() || this.id}>`
167
228
  }
168
229
 
169
230
  }
170
231
 
171
- class TagImpl extends validationMixin(TagMixin)<TagInterface>() {}
172
- interface TagInterface extends TagImpl {}
232
+ class TagImplBase extends validationMixin(TagMixin)<TagImplInterface>() {}
233
+ interface TagImplInterface extends TagImplBase {}
234
+
235
+ type TagProtectedProperty =
236
+ | 'ready'
237
+
238
+ type TagInterface = Omit<TagImplInterface, TagProtectedProperty>
239
+ class TagImpl extends validationMixin(TagImplBase)<TagInterface>() {}
173
240
 
174
241
  type TagConstructor = Constructor<
175
- TagInterface,
176
- typeof TagImpl
242
+ TagImplInterface,
243
+ Omit<typeof TagImpl, 'load'>
177
244
  >
178
245
 
179
246
  export type {
180
247
  TagConstructor,
248
+ TagProtectedProperty,
181
249
  TagInterface,
182
250
  }
183
251
  export {