@kodelyth/zalo 2026.5.39 → 2026.5.42

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 (97) hide show
  1. package/README.md +50 -0
  2. package/api.ts +8 -0
  3. package/channel-plugin-api.ts +1 -0
  4. package/contract-api.ts +5 -0
  5. package/dist/actions.runtime-C61oPfyd.js +5 -0
  6. package/dist/api.js +5 -0
  7. package/dist/channel-D8ylaEdN.js +367 -0
  8. package/dist/channel-plugin-api.js +2 -0
  9. package/dist/channel.runtime-sf-rx5n-.js +105 -0
  10. package/dist/contract-api.js +3 -0
  11. package/dist/group-access-DTQVR6Nd.js +15 -0
  12. package/dist/index.js +22 -0
  13. package/dist/monitor-CQ1bjGih.js +825 -0
  14. package/dist/monitor.webhook-CDxUxa9l.js +175 -0
  15. package/dist/runtime-api-CxXTp1Q2.js +23 -0
  16. package/dist/runtime-api.js +2 -0
  17. package/dist/secret-contract-CRFukr2n.js +87 -0
  18. package/dist/secret-contract-api.js +2 -0
  19. package/dist/send-CGAqdfSA.js +270 -0
  20. package/dist/setup-api.js +30 -0
  21. package/dist/setup-core-Dr75wK6l.js +287 -0
  22. package/dist/setup-entry.js +15 -0
  23. package/dist/setup-surface-C8zxrnzG.js +216 -0
  24. package/dist/test-api.js +2 -0
  25. package/index.test.ts +15 -0
  26. package/index.ts +20 -0
  27. package/klaw.plugin.json +2 -509
  28. package/package.json +4 -4
  29. package/runtime-api.test.ts +10 -0
  30. package/runtime-api.ts +71 -0
  31. package/secret-contract-api.ts +5 -0
  32. package/setup-api.ts +34 -0
  33. package/setup-entry.ts +13 -0
  34. package/src/accounts.test.ts +95 -0
  35. package/src/accounts.ts +65 -0
  36. package/src/actions.runtime.ts +5 -0
  37. package/src/actions.test.ts +32 -0
  38. package/src/actions.ts +62 -0
  39. package/src/api.test.ts +166 -0
  40. package/src/api.ts +265 -0
  41. package/src/approval-auth.test.ts +17 -0
  42. package/src/approval-auth.ts +25 -0
  43. package/src/channel.directory.test.ts +56 -0
  44. package/src/channel.runtime.ts +89 -0
  45. package/src/channel.startup.test.ts +121 -0
  46. package/src/channel.ts +309 -0
  47. package/src/config-schema.test.ts +30 -0
  48. package/src/config-schema.ts +29 -0
  49. package/src/group-access.ts +23 -0
  50. package/src/monitor-durable.test.ts +49 -0
  51. package/src/monitor-durable.ts +38 -0
  52. package/src/monitor.group-policy.test.ts +213 -0
  53. package/src/monitor.image.polling.test.ts +113 -0
  54. package/src/monitor.lifecycle.test.ts +194 -0
  55. package/src/monitor.pairing.lifecycle.test.ts +139 -0
  56. package/src/monitor.polling.media-reply.test.ts +433 -0
  57. package/src/monitor.reply-once.lifecycle.test.ts +178 -0
  58. package/src/monitor.ts +1009 -0
  59. package/src/monitor.types.ts +4 -0
  60. package/src/monitor.webhook.test.ts +808 -0
  61. package/src/monitor.webhook.ts +278 -0
  62. package/src/outbound-media.test.ts +186 -0
  63. package/src/outbound-media.ts +236 -0
  64. package/src/outbound-payload.contract.test.ts +143 -0
  65. package/src/probe.ts +45 -0
  66. package/src/proxy.ts +18 -0
  67. package/src/runtime-api.ts +71 -0
  68. package/src/runtime-support.ts +82 -0
  69. package/src/runtime.ts +9 -0
  70. package/src/secret-contract.ts +109 -0
  71. package/src/secret-input.ts +5 -0
  72. package/src/send.test.ts +150 -0
  73. package/src/send.ts +207 -0
  74. package/src/session-route.ts +32 -0
  75. package/src/setup-allow-from.ts +97 -0
  76. package/src/setup-core.ts +152 -0
  77. package/src/setup-status.test.ts +33 -0
  78. package/src/setup-surface.test.ts +193 -0
  79. package/src/setup-surface.ts +294 -0
  80. package/src/status-issues.test.ts +17 -0
  81. package/src/status-issues.ts +34 -0
  82. package/src/test-support/lifecycle-test-support.ts +456 -0
  83. package/src/test-support/monitor-mocks-test-support.ts +209 -0
  84. package/src/token.test.ts +92 -0
  85. package/src/token.ts +79 -0
  86. package/src/types.ts +50 -0
  87. package/test-api.ts +1 -0
  88. package/tsconfig.json +16 -0
  89. package/api.js +0 -7
  90. package/channel-plugin-api.js +0 -7
  91. package/contract-api.js +0 -7
  92. package/index.js +0 -7
  93. package/runtime-api.js +0 -7
  94. package/secret-contract-api.js +0 -7
  95. package/setup-api.js +0 -7
  96. package/setup-entry.js +0 -7
  97. package/test-api.js +0 -7
package/klaw.plugin.json CHANGED
@@ -3,520 +3,13 @@
3
3
  "activation": {
4
4
  "onStartup": false
5
5
  },
6
- "channels": [
7
- "zalo"
8
- ],
6
+ "channels": ["zalo"],
9
7
  "channelEnvVars": {
10
- "zalo": [
11
- "ZALO_BOT_TOKEN",
12
- "ZALO_WEBHOOK_SECRET"
13
- ]
8
+ "zalo": ["ZALO_BOT_TOKEN", "ZALO_WEBHOOK_SECRET"]
14
9
  },
15
10
  "configSchema": {
16
11
  "type": "object",
17
12
  "additionalProperties": false,
18
13
  "properties": {}
19
- },
20
- "channelConfigs": {
21
- "zalo": {
22
- "schema": {
23
- "$schema": "http://json-schema.org/draft-07/schema#",
24
- "type": "object",
25
- "properties": {
26
- "name": {
27
- "type": "string"
28
- },
29
- "enabled": {
30
- "type": "boolean"
31
- },
32
- "markdown": {
33
- "type": "object",
34
- "properties": {
35
- "tables": {
36
- "type": "string",
37
- "enum": [
38
- "off",
39
- "bullets",
40
- "code",
41
- "block"
42
- ]
43
- }
44
- },
45
- "additionalProperties": false
46
- },
47
- "botToken": {
48
- "anyOf": [
49
- {
50
- "type": "string"
51
- },
52
- {
53
- "oneOf": [
54
- {
55
- "type": "object",
56
- "properties": {
57
- "source": {
58
- "type": "string",
59
- "const": "env"
60
- },
61
- "provider": {
62
- "type": "string",
63
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
64
- },
65
- "id": {
66
- "type": "string",
67
- "pattern": "^[A-Z][A-Z0-9_]{0,127}$"
68
- }
69
- },
70
- "required": [
71
- "source",
72
- "provider",
73
- "id"
74
- ],
75
- "additionalProperties": false
76
- },
77
- {
78
- "type": "object",
79
- "properties": {
80
- "source": {
81
- "type": "string",
82
- "const": "file"
83
- },
84
- "provider": {
85
- "type": "string",
86
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
87
- },
88
- "id": {
89
- "type": "string"
90
- }
91
- },
92
- "required": [
93
- "source",
94
- "provider",
95
- "id"
96
- ],
97
- "additionalProperties": false
98
- },
99
- {
100
- "type": "object",
101
- "properties": {
102
- "source": {
103
- "type": "string",
104
- "const": "exec"
105
- },
106
- "provider": {
107
- "type": "string",
108
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
109
- },
110
- "id": {
111
- "type": "string"
112
- }
113
- },
114
- "required": [
115
- "source",
116
- "provider",
117
- "id"
118
- ],
119
- "additionalProperties": false
120
- }
121
- ]
122
- }
123
- ]
124
- },
125
- "tokenFile": {
126
- "type": "string"
127
- },
128
- "webhookUrl": {
129
- "type": "string"
130
- },
131
- "webhookSecret": {
132
- "anyOf": [
133
- {
134
- "type": "string"
135
- },
136
- {
137
- "oneOf": [
138
- {
139
- "type": "object",
140
- "properties": {
141
- "source": {
142
- "type": "string",
143
- "const": "env"
144
- },
145
- "provider": {
146
- "type": "string",
147
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
148
- },
149
- "id": {
150
- "type": "string",
151
- "pattern": "^[A-Z][A-Z0-9_]{0,127}$"
152
- }
153
- },
154
- "required": [
155
- "source",
156
- "provider",
157
- "id"
158
- ],
159
- "additionalProperties": false
160
- },
161
- {
162
- "type": "object",
163
- "properties": {
164
- "source": {
165
- "type": "string",
166
- "const": "file"
167
- },
168
- "provider": {
169
- "type": "string",
170
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
171
- },
172
- "id": {
173
- "type": "string"
174
- }
175
- },
176
- "required": [
177
- "source",
178
- "provider",
179
- "id"
180
- ],
181
- "additionalProperties": false
182
- },
183
- {
184
- "type": "object",
185
- "properties": {
186
- "source": {
187
- "type": "string",
188
- "const": "exec"
189
- },
190
- "provider": {
191
- "type": "string",
192
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
193
- },
194
- "id": {
195
- "type": "string"
196
- }
197
- },
198
- "required": [
199
- "source",
200
- "provider",
201
- "id"
202
- ],
203
- "additionalProperties": false
204
- }
205
- ]
206
- }
207
- ]
208
- },
209
- "webhookPath": {
210
- "type": "string"
211
- },
212
- "dmPolicy": {
213
- "type": "string",
214
- "enum": [
215
- "pairing",
216
- "allowlist",
217
- "open",
218
- "disabled"
219
- ]
220
- },
221
- "allowFrom": {
222
- "type": "array",
223
- "items": {
224
- "anyOf": [
225
- {
226
- "type": "string"
227
- },
228
- {
229
- "type": "number"
230
- }
231
- ]
232
- }
233
- },
234
- "groupPolicy": {
235
- "type": "string",
236
- "enum": [
237
- "open",
238
- "disabled",
239
- "allowlist"
240
- ]
241
- },
242
- "groupAllowFrom": {
243
- "type": "array",
244
- "items": {
245
- "anyOf": [
246
- {
247
- "type": "string"
248
- },
249
- {
250
- "type": "number"
251
- }
252
- ]
253
- }
254
- },
255
- "mediaMaxMb": {
256
- "type": "number"
257
- },
258
- "proxy": {
259
- "type": "string"
260
- },
261
- "responsePrefix": {
262
- "type": "string"
263
- },
264
- "accounts": {
265
- "type": "object",
266
- "properties": {},
267
- "additionalProperties": {
268
- "type": "object",
269
- "properties": {
270
- "name": {
271
- "type": "string"
272
- },
273
- "enabled": {
274
- "type": "boolean"
275
- },
276
- "markdown": {
277
- "type": "object",
278
- "properties": {
279
- "tables": {
280
- "type": "string",
281
- "enum": [
282
- "off",
283
- "bullets",
284
- "code",
285
- "block"
286
- ]
287
- }
288
- },
289
- "additionalProperties": false
290
- },
291
- "botToken": {
292
- "anyOf": [
293
- {
294
- "type": "string"
295
- },
296
- {
297
- "oneOf": [
298
- {
299
- "type": "object",
300
- "properties": {
301
- "source": {
302
- "type": "string",
303
- "const": "env"
304
- },
305
- "provider": {
306
- "type": "string",
307
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
308
- },
309
- "id": {
310
- "type": "string",
311
- "pattern": "^[A-Z][A-Z0-9_]{0,127}$"
312
- }
313
- },
314
- "required": [
315
- "source",
316
- "provider",
317
- "id"
318
- ],
319
- "additionalProperties": false
320
- },
321
- {
322
- "type": "object",
323
- "properties": {
324
- "source": {
325
- "type": "string",
326
- "const": "file"
327
- },
328
- "provider": {
329
- "type": "string",
330
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
331
- },
332
- "id": {
333
- "type": "string"
334
- }
335
- },
336
- "required": [
337
- "source",
338
- "provider",
339
- "id"
340
- ],
341
- "additionalProperties": false
342
- },
343
- {
344
- "type": "object",
345
- "properties": {
346
- "source": {
347
- "type": "string",
348
- "const": "exec"
349
- },
350
- "provider": {
351
- "type": "string",
352
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
353
- },
354
- "id": {
355
- "type": "string"
356
- }
357
- },
358
- "required": [
359
- "source",
360
- "provider",
361
- "id"
362
- ],
363
- "additionalProperties": false
364
- }
365
- ]
366
- }
367
- ]
368
- },
369
- "tokenFile": {
370
- "type": "string"
371
- },
372
- "webhookUrl": {
373
- "type": "string"
374
- },
375
- "webhookSecret": {
376
- "anyOf": [
377
- {
378
- "type": "string"
379
- },
380
- {
381
- "oneOf": [
382
- {
383
- "type": "object",
384
- "properties": {
385
- "source": {
386
- "type": "string",
387
- "const": "env"
388
- },
389
- "provider": {
390
- "type": "string",
391
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
392
- },
393
- "id": {
394
- "type": "string",
395
- "pattern": "^[A-Z][A-Z0-9_]{0,127}$"
396
- }
397
- },
398
- "required": [
399
- "source",
400
- "provider",
401
- "id"
402
- ],
403
- "additionalProperties": false
404
- },
405
- {
406
- "type": "object",
407
- "properties": {
408
- "source": {
409
- "type": "string",
410
- "const": "file"
411
- },
412
- "provider": {
413
- "type": "string",
414
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
415
- },
416
- "id": {
417
- "type": "string"
418
- }
419
- },
420
- "required": [
421
- "source",
422
- "provider",
423
- "id"
424
- ],
425
- "additionalProperties": false
426
- },
427
- {
428
- "type": "object",
429
- "properties": {
430
- "source": {
431
- "type": "string",
432
- "const": "exec"
433
- },
434
- "provider": {
435
- "type": "string",
436
- "pattern": "^[a-z][a-z0-9_-]{0,63}$"
437
- },
438
- "id": {
439
- "type": "string"
440
- }
441
- },
442
- "required": [
443
- "source",
444
- "provider",
445
- "id"
446
- ],
447
- "additionalProperties": false
448
- }
449
- ]
450
- }
451
- ]
452
- },
453
- "webhookPath": {
454
- "type": "string"
455
- },
456
- "dmPolicy": {
457
- "type": "string",
458
- "enum": [
459
- "pairing",
460
- "allowlist",
461
- "open",
462
- "disabled"
463
- ]
464
- },
465
- "allowFrom": {
466
- "type": "array",
467
- "items": {
468
- "anyOf": [
469
- {
470
- "type": "string"
471
- },
472
- {
473
- "type": "number"
474
- }
475
- ]
476
- }
477
- },
478
- "groupPolicy": {
479
- "type": "string",
480
- "enum": [
481
- "open",
482
- "disabled",
483
- "allowlist"
484
- ]
485
- },
486
- "groupAllowFrom": {
487
- "type": "array",
488
- "items": {
489
- "anyOf": [
490
- {
491
- "type": "string"
492
- },
493
- {
494
- "type": "number"
495
- }
496
- ]
497
- }
498
- },
499
- "mediaMaxMb": {
500
- "type": "number"
501
- },
502
- "proxy": {
503
- "type": "string"
504
- },
505
- "responsePrefix": {
506
- "type": "string"
507
- }
508
- },
509
- "additionalProperties": false
510
- }
511
- },
512
- "defaultAccount": {
513
- "type": "string"
514
- }
515
- },
516
- "additionalProperties": false
517
- },
518
- "label": "Zalo",
519
- "description": "Vietnam-focused messaging platform with Bot API."
520
- }
521
14
  }
522
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kodelyth/zalo",
3
- "version": "2026.5.39",
3
+ "version": "2026.5.42",
4
4
  "description": "Klaw Zalo channel plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  "type": "module",
10
10
  "devDependencies": {
11
11
  "@kodelyth/plugin-sdk": "1.0.1",
12
- "@kodelyth/klaw": "2026.5.41"
12
+ "@kodelyth/klaw": "2026.5.42"
13
13
  },
14
14
  "peerDependencies": {
15
15
  "@kodelyth/klaw": ">=2026.5.19"
@@ -21,9 +21,9 @@
21
21
  },
22
22
  "klaw": {
23
23
  "extensions": [
24
- "./index.js"
24
+ "./index.ts"
25
25
  ],
26
- "setupEntry": "./setup-entry.js",
26
+ "setupEntry": "./setup-entry.ts",
27
27
  "channel": {
28
28
  "id": "zalo",
29
29
  "label": "Zalo",
@@ -0,0 +1,10 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import * as runtime from "./runtime-api.js";
3
+
4
+ describe("zalo runtime api", () => {
5
+ it("loads the narrow runtime api without reentering setup surfaces", () => {
6
+ expect(Object.hasOwn(runtime, "zaloPlugin")).toBe(false);
7
+ expect(Object.hasOwn(runtime, "zaloSetupWizard")).toBe(false);
8
+ expect(typeof runtime.setZaloRuntime).toBe("function");
9
+ });
10
+ });
package/runtime-api.ts ADDED
@@ -0,0 +1,71 @@
1
+ export {
2
+ addWildcardAllowFrom,
3
+ applyAccountNameToChannelSection,
4
+ applyBasicWebhookRequestGuards,
5
+ applySetupAccountConfigPatch,
6
+ type BaseProbeResult,
7
+ type BaseTokenResolution,
8
+ buildBaseAccountStatusSnapshot,
9
+ buildChannelConfigSchema,
10
+ buildSecretInputSchema,
11
+ buildSingleChannelSecretPromptState,
12
+ buildTokenChannelStatusSummary,
13
+ type ChannelAccountSnapshot,
14
+ type ChannelMessageActionAdapter,
15
+ type ChannelMessageActionName,
16
+ type ChannelPlugin,
17
+ type ChannelStatusIssue,
18
+ chunkTextForOutbound,
19
+ createChannelPairingController,
20
+ createChannelMessageReplyPipeline,
21
+ createDedupeCache,
22
+ createFixedWindowRateLimiter,
23
+ createWebhookAnomalyTracker,
24
+ DEFAULT_ACCOUNT_ID,
25
+ deliverTextOrMediaReply,
26
+ formatAllowFromLowercase,
27
+ formatPairingApproveHint,
28
+ type GroupPolicy,
29
+ hasConfiguredSecretInput,
30
+ isNormalizedSenderAllowed,
31
+ isNumericTargetId,
32
+ jsonResult,
33
+ logTypingFailure,
34
+ type MarkdownTableMode,
35
+ mergeAllowFromEntries,
36
+ migrateBaseNameToDefaultAccount,
37
+ normalizeAccountId,
38
+ normalizeResolvedSecretInputString,
39
+ normalizeSecretInputString,
40
+ type KlawConfig,
41
+ type OutboundReplyPayload,
42
+ PAIRING_APPROVED_MESSAGE,
43
+ type PluginRuntime,
44
+ promptSingleChannelSecretInput,
45
+ readJsonWebhookBodyOrReject,
46
+ readStringParam,
47
+ registerPluginHttpRoute,
48
+ type RegisterWebhookPluginRouteOptions,
49
+ registerWebhookTarget,
50
+ type RegisterWebhookTargetOptions,
51
+ registerWebhookTargetWithPluginRoute,
52
+ type ReplyPayload,
53
+ resolveClientIp,
54
+ resolveDefaultGroupPolicy,
55
+ resolveInboundRouteEnvelopeBuilderWithRuntime,
56
+ resolveOpenProviderRuntimeGroupPolicy,
57
+ resolveWebhookPath,
58
+ resolveWebhookTargetWithAuthOrRejectSync,
59
+ runSingleChannelSecretStep,
60
+ type RuntimeEnv,
61
+ type SecretInput,
62
+ sendPayloadWithChunkedTextAndMedia,
63
+ setTopLevelChannelDmPolicyWithAllowFrom,
64
+ setZaloRuntime,
65
+ waitForAbortSignal,
66
+ warnMissingProviderGroupPolicyFallbackOnce,
67
+ WEBHOOK_ANOMALY_COUNTER_DEFAULTS,
68
+ WEBHOOK_RATE_LIMIT_DEFAULTS,
69
+ withResolvedWebhookRequestPipeline,
70
+ type WizardPrompter,
71
+ } from "./src/runtime-api.js";
@@ -0,0 +1,5 @@
1
+ export {
2
+ channelSecrets,
3
+ collectRuntimeConfigAssignments,
4
+ secretTargetRegistryEntries,
5
+ } from "./src/secret-contract.js";
package/setup-api.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { loadBundledEntryExportSync } from "klaw/plugin-sdk/channel-entry-contract";
2
+
3
+ type SetupSurfaceModule = typeof import("./src/setup-surface.js");
4
+
5
+ function createLazyObjectValue<T extends object>(load: () => T): T {
6
+ return new Proxy({} as T, {
7
+ get(_target, property, receiver) {
8
+ return Reflect.get(load(), property, receiver);
9
+ },
10
+ has(_target, property) {
11
+ return property in load();
12
+ },
13
+ ownKeys() {
14
+ return Reflect.ownKeys(load());
15
+ },
16
+ getOwnPropertyDescriptor(_target, property) {
17
+ const descriptor = Object.getOwnPropertyDescriptor(load(), property);
18
+ return descriptor ? { ...descriptor, configurable: true } : undefined;
19
+ },
20
+ });
21
+ }
22
+
23
+ function loadSetupSurfaceModule(): SetupSurfaceModule {
24
+ return loadBundledEntryExportSync<SetupSurfaceModule>(import.meta.url, {
25
+ specifier: "./src/setup-surface.js",
26
+ });
27
+ }
28
+
29
+ export { zaloDmPolicy, zaloSetupAdapter, createZaloSetupWizardProxy } from "./src/setup-core.js";
30
+ export { resolveZaloRuntimeGroupPolicy } from "./src/group-access.js";
31
+
32
+ export const zaloSetupWizard: SetupSurfaceModule["zaloSetupWizard"] = createLazyObjectValue(
33
+ () => loadSetupSurfaceModule().zaloSetupWizard as object,
34
+ ) as SetupSurfaceModule["zaloSetupWizard"];
package/setup-entry.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { defineBundledChannelSetupEntry } from "klaw/plugin-sdk/channel-entry-contract";
2
+
3
+ export default defineBundledChannelSetupEntry({
4
+ importMetaUrl: import.meta.url,
5
+ plugin: {
6
+ specifier: "./api.js",
7
+ exportName: "zaloPlugin",
8
+ },
9
+ secrets: {
10
+ specifier: "./secret-contract-api.js",
11
+ exportName: "channelSecrets",
12
+ },
13
+ });