spectrum-ts 0.3.0 → 0.5.0
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/dist/chunk-UZWRB3FZ.js +624 -0
- package/dist/index.d.ts +133 -3
- package/dist/index.js +131 -16
- package/dist/providers/imessage/index.d.ts +1 -1
- package/dist/providers/imessage/index.js +349 -36
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +275 -39
- package/dist/{types-DuE2hXuJ.d.ts → types-CfiD_00g.d.ts} +73 -7
- package/package.json +10 -3
- package/dist/chunk-V2PK557T.js +0 -73
- package/dist/chunk-ZRSCHSLZ.js +0 -44
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
-
asAttachment
|
|
3
|
-
|
|
4
|
-
import {
|
|
2
|
+
asAttachment,
|
|
3
|
+
asContact,
|
|
5
4
|
asCustom,
|
|
6
5
|
stream
|
|
7
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-UZWRB3FZ.js";
|
|
8
7
|
import {
|
|
9
8
|
asText,
|
|
10
9
|
definePlatform
|
|
@@ -16,17 +15,153 @@ import {
|
|
|
16
15
|
} from "@photon-ai/whatsapp-business";
|
|
17
16
|
|
|
18
17
|
// src/providers/whatsapp-business/messages.ts
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
import { extension as mimeExtension } from "mime-types";
|
|
19
|
+
var mapWaPhoneType = (type) => {
|
|
20
|
+
if (!type) {
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
const upper = type.toUpperCase();
|
|
24
|
+
if (upper === "CELL" || upper === "MOBILE" || upper === "IPHONE") {
|
|
25
|
+
return "mobile";
|
|
26
|
+
}
|
|
27
|
+
if (upper === "HOME") {
|
|
28
|
+
return "home";
|
|
29
|
+
}
|
|
30
|
+
if (upper === "WORK" || upper === "BUSINESS") {
|
|
31
|
+
return "work";
|
|
32
|
+
}
|
|
33
|
+
return "other";
|
|
34
|
+
};
|
|
35
|
+
var mapWaSimpleType = (type) => {
|
|
36
|
+
if (!type) {
|
|
37
|
+
return void 0;
|
|
38
|
+
}
|
|
39
|
+
const upper = type.toUpperCase();
|
|
40
|
+
if (upper === "HOME") {
|
|
41
|
+
return "home";
|
|
42
|
+
}
|
|
43
|
+
if (upper === "WORK" || upper === "BUSINESS") {
|
|
44
|
+
return "work";
|
|
45
|
+
}
|
|
46
|
+
return "other";
|
|
47
|
+
};
|
|
48
|
+
var waNameToSpectrum = (name) => {
|
|
49
|
+
const result = { formatted: name.formattedName };
|
|
50
|
+
if (name.firstName) {
|
|
51
|
+
result.first = name.firstName;
|
|
52
|
+
}
|
|
53
|
+
if (name.lastName) {
|
|
54
|
+
result.last = name.lastName;
|
|
55
|
+
}
|
|
56
|
+
if (name.middleName) {
|
|
57
|
+
result.middle = name.middleName;
|
|
58
|
+
}
|
|
59
|
+
if (name.prefix) {
|
|
60
|
+
result.prefix = name.prefix;
|
|
61
|
+
}
|
|
62
|
+
if (name.suffix) {
|
|
63
|
+
result.suffix = name.suffix;
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
67
|
+
var waPhoneToSpectrum = (phone) => {
|
|
68
|
+
const entry = { value: phone.phone };
|
|
69
|
+
const type = mapWaPhoneType(phone.type);
|
|
70
|
+
if (type) {
|
|
71
|
+
entry.type = type;
|
|
72
|
+
}
|
|
73
|
+
return entry;
|
|
74
|
+
};
|
|
75
|
+
var waEmailToSpectrum = (email) => {
|
|
76
|
+
const entry = { value: email.email };
|
|
77
|
+
const type = mapWaSimpleType(email.type);
|
|
78
|
+
if (type) {
|
|
79
|
+
entry.type = type;
|
|
80
|
+
}
|
|
81
|
+
return entry;
|
|
82
|
+
};
|
|
83
|
+
var waAddressToSpectrum = (address) => {
|
|
84
|
+
const entry = {};
|
|
85
|
+
if (address.street) {
|
|
86
|
+
entry.street = address.street;
|
|
87
|
+
}
|
|
88
|
+
if (address.city) {
|
|
89
|
+
entry.city = address.city;
|
|
90
|
+
}
|
|
91
|
+
if (address.state) {
|
|
92
|
+
entry.region = address.state;
|
|
93
|
+
}
|
|
94
|
+
if (address.zip) {
|
|
95
|
+
entry.postalCode = address.zip;
|
|
96
|
+
}
|
|
97
|
+
if (address.country) {
|
|
98
|
+
entry.country = address.country;
|
|
99
|
+
}
|
|
100
|
+
const type = mapWaSimpleType(address.type);
|
|
101
|
+
if (type) {
|
|
102
|
+
entry.type = type;
|
|
103
|
+
}
|
|
104
|
+
return entry;
|
|
105
|
+
};
|
|
106
|
+
var waOrgToSpectrum = (org) => {
|
|
107
|
+
const entry = {};
|
|
108
|
+
if (org.company) {
|
|
109
|
+
entry.name = org.company;
|
|
110
|
+
}
|
|
111
|
+
if (org.title) {
|
|
112
|
+
entry.title = org.title;
|
|
113
|
+
}
|
|
114
|
+
if (org.department) {
|
|
115
|
+
entry.department = org.department;
|
|
116
|
+
}
|
|
117
|
+
return entry;
|
|
118
|
+
};
|
|
119
|
+
var waContactToSpectrum = (card) => {
|
|
120
|
+
const input = { raw: card };
|
|
121
|
+
input.name = waNameToSpectrum(card.name);
|
|
122
|
+
if (card.phones.length > 0) {
|
|
123
|
+
input.phones = card.phones.map(waPhoneToSpectrum);
|
|
124
|
+
}
|
|
125
|
+
if (card.emails.length > 0) {
|
|
126
|
+
input.emails = card.emails.map(waEmailToSpectrum);
|
|
127
|
+
}
|
|
128
|
+
if (card.addresses.length > 0) {
|
|
129
|
+
input.addresses = card.addresses.map(waAddressToSpectrum);
|
|
130
|
+
}
|
|
131
|
+
if (card.org) {
|
|
132
|
+
input.org = waOrgToSpectrum(card.org);
|
|
133
|
+
}
|
|
134
|
+
if (card.urls.length > 0) {
|
|
135
|
+
input.urls = card.urls.map((u) => u.url);
|
|
136
|
+
}
|
|
137
|
+
if (card.birthday) {
|
|
138
|
+
input.birthday = card.birthday;
|
|
139
|
+
}
|
|
140
|
+
return asContact(input);
|
|
141
|
+
};
|
|
142
|
+
var toMessages = (client, msg) => {
|
|
143
|
+
const base = {
|
|
24
144
|
sender: { id: msg.from },
|
|
25
145
|
space: { id: msg.from },
|
|
26
146
|
timestamp: msg.timestamp
|
|
27
147
|
};
|
|
148
|
+
if (msg.content.type === "contacts") {
|
|
149
|
+
const multi = msg.content.contacts.length > 1;
|
|
150
|
+
return msg.content.contacts.map((card, index) => ({
|
|
151
|
+
...base,
|
|
152
|
+
id: multi ? `${msg.id}:${index}` : msg.id,
|
|
153
|
+
content: waContactToSpectrum(card)
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
return [
|
|
157
|
+
{
|
|
158
|
+
...base,
|
|
159
|
+
id: msg.id,
|
|
160
|
+
content: mapContent(client, msg.content)
|
|
161
|
+
}
|
|
162
|
+
];
|
|
28
163
|
};
|
|
29
|
-
var mapContent =
|
|
164
|
+
var mapContent = (client, content) => {
|
|
30
165
|
switch (content.type) {
|
|
31
166
|
case "text":
|
|
32
167
|
return asText(content.body);
|
|
@@ -34,16 +169,11 @@ var mapContent = async (client, content) => {
|
|
|
34
169
|
case "video":
|
|
35
170
|
case "audio":
|
|
36
171
|
case "document":
|
|
37
|
-
return
|
|
172
|
+
return lazyMedia(client, content.media);
|
|
38
173
|
case "sticker":
|
|
39
174
|
return asCustom({ whatsapp_type: "sticker", ...content.sticker });
|
|
40
175
|
case "location":
|
|
41
176
|
return asCustom({ whatsapp_type: "location", ...content.location });
|
|
42
|
-
case "contacts":
|
|
43
|
-
return asCustom({
|
|
44
|
-
whatsapp_type: "contacts",
|
|
45
|
-
contacts: content.contacts
|
|
46
|
-
});
|
|
47
177
|
case "reaction":
|
|
48
178
|
return asCustom({ whatsapp_type: "reaction", ...content.reaction });
|
|
49
179
|
case "interactive":
|
|
@@ -58,27 +188,26 @@ var mapContent = async (client, content) => {
|
|
|
58
188
|
return asCustom({ whatsapp_type: "unknown" });
|
|
59
189
|
}
|
|
60
190
|
};
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
throw new Error(`Media download failed: ${response.status}`);
|
|
67
|
-
}
|
|
68
|
-
const data = Buffer.from(await response.arrayBuffer());
|
|
69
|
-
return asAttachment({
|
|
70
|
-
data,
|
|
71
|
-
mimeType: media.mimeType,
|
|
72
|
-
name: media.filename ?? `media-${media.id}`
|
|
73
|
-
});
|
|
74
|
-
} catch {
|
|
75
|
-
return asCustom({
|
|
76
|
-
whatsapp_type: "media_error",
|
|
77
|
-
mediaId: media.id,
|
|
78
|
-
mimeType: media.mimeType
|
|
79
|
-
});
|
|
191
|
+
var fetchMedia = async (client, mediaId) => {
|
|
192
|
+
const { url } = await client.media.getUrl(mediaId);
|
|
193
|
+
const response = await fetch(url);
|
|
194
|
+
if (!response.ok) {
|
|
195
|
+
throw new Error(`Media download failed: ${response.status}`);
|
|
80
196
|
}
|
|
197
|
+
return response;
|
|
81
198
|
};
|
|
199
|
+
var lazyMedia = (client, media) => asAttachment({
|
|
200
|
+
name: media.filename ?? `media-${media.id}`,
|
|
201
|
+
mimeType: media.mimeType,
|
|
202
|
+
read: async () => Buffer.from(await (await fetchMedia(client, media.id)).arrayBuffer()),
|
|
203
|
+
stream: async () => {
|
|
204
|
+
const response = await fetchMedia(client, media.id);
|
|
205
|
+
if (!response.body) {
|
|
206
|
+
throw new Error("Media response missing body");
|
|
207
|
+
}
|
|
208
|
+
return response.body;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
82
211
|
var mimeToMediaType = (mimeType) => {
|
|
83
212
|
if (mimeType.startsWith("image/")) {
|
|
84
213
|
return "image";
|
|
@@ -91,6 +220,74 @@ var mimeToMediaType = (mimeType) => {
|
|
|
91
220
|
}
|
|
92
221
|
return "document";
|
|
93
222
|
};
|
|
223
|
+
var voiceFilename = (content) => {
|
|
224
|
+
if (content.name) {
|
|
225
|
+
return content.name;
|
|
226
|
+
}
|
|
227
|
+
const ext = mimeExtension(content.mimeType);
|
|
228
|
+
return ext ? `voice.${ext}` : "voice";
|
|
229
|
+
};
|
|
230
|
+
var spectrumPhoneTypeToWa = (type) => {
|
|
231
|
+
if (type === "mobile") {
|
|
232
|
+
return "CELL";
|
|
233
|
+
}
|
|
234
|
+
if (type === "home" || type === "work" || type === "other") {
|
|
235
|
+
return type.toUpperCase();
|
|
236
|
+
}
|
|
237
|
+
return void 0;
|
|
238
|
+
};
|
|
239
|
+
var spectrumSimpleTypeToWa = (type) => type ? type.toUpperCase() : void 0;
|
|
240
|
+
var spectrumNameToWa = (name) => ({
|
|
241
|
+
formattedName: name?.formatted ?? ([name?.first, name?.middle, name?.last].filter((p) => Boolean(p)).join(" ") || "Unknown"),
|
|
242
|
+
firstName: name?.first,
|
|
243
|
+
lastName: name?.last,
|
|
244
|
+
middleName: name?.middle,
|
|
245
|
+
prefix: name?.prefix,
|
|
246
|
+
suffix: name?.suffix
|
|
247
|
+
});
|
|
248
|
+
var isWhatsAppContactCard = (value) => {
|
|
249
|
+
if (!value || typeof value !== "object") {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
const raw = value;
|
|
253
|
+
const name = raw.name;
|
|
254
|
+
if (!name || typeof name !== "object" || typeof name.formattedName !== "string") {
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
return Array.isArray(raw.phones) && Array.isArray(raw.emails) && Array.isArray(raw.addresses) && Array.isArray(raw.urls);
|
|
258
|
+
};
|
|
259
|
+
var contactToWa = (contact) => {
|
|
260
|
+
if (isWhatsAppContactCard(contact.raw)) {
|
|
261
|
+
return contact.raw;
|
|
262
|
+
}
|
|
263
|
+
const card = {
|
|
264
|
+
name: spectrumNameToWa(contact.name),
|
|
265
|
+
phones: (contact.phones ?? []).map((p) => ({
|
|
266
|
+
phone: p.value,
|
|
267
|
+
type: spectrumPhoneTypeToWa(p.type)
|
|
268
|
+
})),
|
|
269
|
+
emails: (contact.emails ?? []).map((e) => ({
|
|
270
|
+
email: e.value,
|
|
271
|
+
type: spectrumSimpleTypeToWa(e.type)
|
|
272
|
+
})),
|
|
273
|
+
addresses: (contact.addresses ?? []).map((a) => ({
|
|
274
|
+
street: a.street,
|
|
275
|
+
city: a.city,
|
|
276
|
+
state: a.region,
|
|
277
|
+
zip: a.postalCode,
|
|
278
|
+
country: a.country,
|
|
279
|
+
type: spectrumSimpleTypeToWa(a.type)
|
|
280
|
+
})),
|
|
281
|
+
urls: (contact.urls ?? []).map((url) => ({ url })),
|
|
282
|
+
org: contact.org?.name || contact.org?.department || contact.org?.title ? {
|
|
283
|
+
company: contact.org.name,
|
|
284
|
+
department: contact.org.department,
|
|
285
|
+
title: contact.org.title
|
|
286
|
+
} : void 0,
|
|
287
|
+
birthday: contact.birthday
|
|
288
|
+
};
|
|
289
|
+
return card;
|
|
290
|
+
};
|
|
94
291
|
var messages = (client) => {
|
|
95
292
|
const eventStream = client.events.subscribe().filter(
|
|
96
293
|
(e) => e.type === "message"
|
|
@@ -99,8 +296,9 @@ var messages = (client) => {
|
|
|
99
296
|
(async () => {
|
|
100
297
|
try {
|
|
101
298
|
for await (const event of eventStream) {
|
|
102
|
-
const
|
|
103
|
-
|
|
299
|
+
for (const m of toMessages(client, event.message)) {
|
|
300
|
+
emit(m);
|
|
301
|
+
}
|
|
104
302
|
}
|
|
105
303
|
end();
|
|
106
304
|
} catch (e) {
|
|
@@ -117,7 +315,7 @@ var send = async (client, spaceId, content) => {
|
|
|
117
315
|
break;
|
|
118
316
|
case "attachment": {
|
|
119
317
|
const { mediaId } = await client.media.upload({
|
|
120
|
-
file: content.
|
|
318
|
+
file: await content.read(),
|
|
121
319
|
mimeType: content.mimeType,
|
|
122
320
|
filename: content.name
|
|
123
321
|
});
|
|
@@ -129,6 +327,24 @@ var send = async (client, spaceId, content) => {
|
|
|
129
327
|
});
|
|
130
328
|
break;
|
|
131
329
|
}
|
|
330
|
+
case "contact":
|
|
331
|
+
await client.messages.send({
|
|
332
|
+
to: spaceId,
|
|
333
|
+
contacts: [contactToWa(content)]
|
|
334
|
+
});
|
|
335
|
+
break;
|
|
336
|
+
case "voice": {
|
|
337
|
+
const { mediaId } = await client.media.upload({
|
|
338
|
+
file: await content.read(),
|
|
339
|
+
mimeType: content.mimeType,
|
|
340
|
+
filename: voiceFilename(content)
|
|
341
|
+
});
|
|
342
|
+
await client.messages.send({
|
|
343
|
+
to: spaceId,
|
|
344
|
+
audio: { id: mediaId }
|
|
345
|
+
});
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
132
348
|
default:
|
|
133
349
|
break;
|
|
134
350
|
}
|
|
@@ -150,7 +366,7 @@ var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
|
150
366
|
break;
|
|
151
367
|
case "attachment": {
|
|
152
368
|
const { mediaId } = await client.media.upload({
|
|
153
|
-
file: content.
|
|
369
|
+
file: await content.read(),
|
|
154
370
|
mimeType: content.mimeType,
|
|
155
371
|
filename: content.name
|
|
156
372
|
});
|
|
@@ -163,6 +379,26 @@ var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
|
163
379
|
});
|
|
164
380
|
break;
|
|
165
381
|
}
|
|
382
|
+
case "contact":
|
|
383
|
+
await client.messages.send({
|
|
384
|
+
to: spaceId,
|
|
385
|
+
replyTo: messageId,
|
|
386
|
+
contacts: [contactToWa(content)]
|
|
387
|
+
});
|
|
388
|
+
break;
|
|
389
|
+
case "voice": {
|
|
390
|
+
const { mediaId } = await client.media.upload({
|
|
391
|
+
file: await content.read(),
|
|
392
|
+
mimeType: content.mimeType,
|
|
393
|
+
filename: voiceFilename(content)
|
|
394
|
+
});
|
|
395
|
+
await client.messages.send({
|
|
396
|
+
to: spaceId,
|
|
397
|
+
replyTo: messageId,
|
|
398
|
+
audio: { id: mediaId }
|
|
399
|
+
});
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
166
402
|
default:
|
|
167
403
|
break;
|
|
168
404
|
}
|
|
@@ -9,9 +9,75 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
|
|
|
9
9
|
raw: z__default.ZodUnknown;
|
|
10
10
|
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
11
11
|
type: z__default.ZodLiteral<"attachment">;
|
|
12
|
-
data: z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
|
|
13
|
-
mimeType: z__default.ZodString;
|
|
14
12
|
name: z__default.ZodString;
|
|
13
|
+
mimeType: z__default.ZodString;
|
|
14
|
+
size: z__default.ZodOptional<z__default.ZodNumber>;
|
|
15
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
16
|
+
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
17
|
+
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
18
|
+
type: z__default.ZodLiteral<"contact">;
|
|
19
|
+
user: z__default.ZodOptional<z__default.ZodObject<{
|
|
20
|
+
__platform: z__default.ZodString;
|
|
21
|
+
id: z__default.ZodString;
|
|
22
|
+
}, z__default.core.$strip>>;
|
|
23
|
+
name: z__default.ZodOptional<z__default.ZodObject<{
|
|
24
|
+
formatted: z__default.ZodOptional<z__default.ZodString>;
|
|
25
|
+
first: z__default.ZodOptional<z__default.ZodString>;
|
|
26
|
+
last: z__default.ZodOptional<z__default.ZodString>;
|
|
27
|
+
middle: z__default.ZodOptional<z__default.ZodString>;
|
|
28
|
+
prefix: z__default.ZodOptional<z__default.ZodString>;
|
|
29
|
+
suffix: z__default.ZodOptional<z__default.ZodString>;
|
|
30
|
+
}, z__default.core.$strip>>;
|
|
31
|
+
phones: z__default.ZodOptional<z__default.ZodArray<z__default.ZodObject<{
|
|
32
|
+
value: z__default.ZodString;
|
|
33
|
+
type: z__default.ZodOptional<z__default.ZodEnum<{
|
|
34
|
+
mobile: "mobile";
|
|
35
|
+
home: "home";
|
|
36
|
+
work: "work";
|
|
37
|
+
other: "other";
|
|
38
|
+
}>>;
|
|
39
|
+
}, z__default.core.$strip>>>;
|
|
40
|
+
emails: z__default.ZodOptional<z__default.ZodArray<z__default.ZodObject<{
|
|
41
|
+
value: z__default.ZodString;
|
|
42
|
+
type: z__default.ZodOptional<z__default.ZodEnum<{
|
|
43
|
+
home: "home";
|
|
44
|
+
work: "work";
|
|
45
|
+
other: "other";
|
|
46
|
+
}>>;
|
|
47
|
+
}, z__default.core.$strip>>>;
|
|
48
|
+
addresses: z__default.ZodOptional<z__default.ZodArray<z__default.ZodObject<{
|
|
49
|
+
street: z__default.ZodOptional<z__default.ZodString>;
|
|
50
|
+
city: z__default.ZodOptional<z__default.ZodString>;
|
|
51
|
+
region: z__default.ZodOptional<z__default.ZodString>;
|
|
52
|
+
postalCode: z__default.ZodOptional<z__default.ZodString>;
|
|
53
|
+
country: z__default.ZodOptional<z__default.ZodString>;
|
|
54
|
+
type: z__default.ZodOptional<z__default.ZodEnum<{
|
|
55
|
+
home: "home";
|
|
56
|
+
work: "work";
|
|
57
|
+
other: "other";
|
|
58
|
+
}>>;
|
|
59
|
+
}, z__default.core.$strip>>>;
|
|
60
|
+
org: z__default.ZodOptional<z__default.ZodObject<{
|
|
61
|
+
name: z__default.ZodOptional<z__default.ZodString>;
|
|
62
|
+
title: z__default.ZodOptional<z__default.ZodString>;
|
|
63
|
+
department: z__default.ZodOptional<z__default.ZodString>;
|
|
64
|
+
}, z__default.core.$strip>>;
|
|
65
|
+
urls: z__default.ZodOptional<z__default.ZodArray<z__default.ZodString>>;
|
|
66
|
+
birthday: z__default.ZodOptional<z__default.ZodString>;
|
|
67
|
+
note: z__default.ZodOptional<z__default.ZodString>;
|
|
68
|
+
photo: z__default.ZodOptional<z__default.ZodObject<{
|
|
69
|
+
mimeType: z__default.ZodString;
|
|
70
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
71
|
+
}, z__default.core.$strip>>;
|
|
72
|
+
raw: z__default.ZodOptional<z__default.ZodUnknown>;
|
|
73
|
+
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
74
|
+
type: z__default.ZodLiteral<"voice">;
|
|
75
|
+
name: z__default.ZodOptional<z__default.ZodString>;
|
|
76
|
+
mimeType: z__default.ZodString;
|
|
77
|
+
duration: z__default.ZodOptional<z__default.ZodNumber>;
|
|
78
|
+
size: z__default.ZodOptional<z__default.ZodNumber>;
|
|
79
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
80
|
+
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
15
81
|
}, z__default.core.$strip>], "type">;
|
|
16
82
|
type Content = z__default.infer<typeof contentSchema>;
|
|
17
83
|
interface ContentBuilder {
|
|
@@ -19,6 +85,11 @@ interface ContentBuilder {
|
|
|
19
85
|
}
|
|
20
86
|
type ContentInput = string | ContentBuilder;
|
|
21
87
|
|
|
88
|
+
interface User {
|
|
89
|
+
readonly __platform: string;
|
|
90
|
+
readonly id: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
22
93
|
interface Space<_Def = unknown> {
|
|
23
94
|
readonly __platform: string;
|
|
24
95
|
readonly id: string;
|
|
@@ -28,11 +99,6 @@ interface Space<_Def = unknown> {
|
|
|
28
99
|
stopTyping(): Promise<void>;
|
|
29
100
|
}
|
|
30
101
|
|
|
31
|
-
interface User {
|
|
32
|
-
readonly __platform: string;
|
|
33
|
-
readonly id: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
102
|
interface Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
|
|
37
103
|
content: Content;
|
|
38
104
|
readonly id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -19,17 +19,24 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@photon-ai/advanced-imessage": "^0.4.
|
|
22
|
+
"@photon-ai/advanced-imessage": "^0.4.3",
|
|
23
|
+
"@photon-ai/imessage-kit": "^3.0.0-rc.2",
|
|
23
24
|
"@photon-ai/whatsapp-business": "^0.1.1",
|
|
24
|
-
"@photon-ai/imessage-kit": "^3.0.0-rc.1",
|
|
25
25
|
"@repeaterjs/repeater": "^3.0.6",
|
|
26
26
|
"better-grpc": "^0.3.2",
|
|
27
27
|
"mime-types": "^3.0.1",
|
|
28
28
|
"type-fest": "^5.4.1",
|
|
29
|
+
"vcf": "^2.1.2",
|
|
29
30
|
"zod": "^4.2.1"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
33
|
+
"ffmpeg-static": "^5",
|
|
32
34
|
"typescript": "^5"
|
|
33
35
|
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"ffmpeg-static": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
34
41
|
"license": "MIT"
|
|
35
42
|
}
|
package/dist/chunk-V2PK557T.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/content/custom.ts
|
|
2
|
-
import z from "zod";
|
|
3
|
-
var customSchema = z.object({
|
|
4
|
-
type: z.literal("custom"),
|
|
5
|
-
raw: z.unknown()
|
|
6
|
-
});
|
|
7
|
-
var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
|
|
8
|
-
function custom(raw) {
|
|
9
|
-
return {
|
|
10
|
-
build: async () => asCustom(raw)
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// src/utils/stream.ts
|
|
15
|
-
import { Repeater } from "@repeaterjs/repeater";
|
|
16
|
-
function stream(setup) {
|
|
17
|
-
const repeater = new Repeater(async (push, stop) => {
|
|
18
|
-
const emit = (value) => {
|
|
19
|
-
Promise.resolve(push(value)).catch((error) => {
|
|
20
|
-
stop(error);
|
|
21
|
-
return void 0;
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
const end = (error) => {
|
|
25
|
-
stop(error);
|
|
26
|
-
};
|
|
27
|
-
const cleanup = await setup(emit, end);
|
|
28
|
-
try {
|
|
29
|
-
await stop;
|
|
30
|
-
} finally {
|
|
31
|
-
await cleanup?.();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
return Object.assign(repeater, {
|
|
35
|
-
close: async () => {
|
|
36
|
-
await repeater.return(void 0);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function mergeStreams(streams) {
|
|
41
|
-
return stream((emit, end) => {
|
|
42
|
-
if (streams.length === 0) {
|
|
43
|
-
end();
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
let openStreams = streams.length;
|
|
47
|
-
const workers = streams.map(async (source) => {
|
|
48
|
-
try {
|
|
49
|
-
for await (const value of source) {
|
|
50
|
-
emit(value);
|
|
51
|
-
}
|
|
52
|
-
} catch (error) {
|
|
53
|
-
end(error);
|
|
54
|
-
} finally {
|
|
55
|
-
openStreams -= 1;
|
|
56
|
-
if (openStreams === 0) {
|
|
57
|
-
end();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
return async () => {
|
|
62
|
-
await Promise.allSettled(streams.map((source) => source.close()));
|
|
63
|
-
await Promise.allSettled(workers);
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export {
|
|
69
|
-
asCustom,
|
|
70
|
-
custom,
|
|
71
|
-
stream,
|
|
72
|
-
mergeStreams
|
|
73
|
-
};
|
package/dist/chunk-ZRSCHSLZ.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// src/content/attachment.ts
|
|
2
|
-
import { readFile } from "fs/promises";
|
|
3
|
-
import { basename } from "path";
|
|
4
|
-
import { lookup as lookupMimeType } from "mime-types";
|
|
5
|
-
import z from "zod";
|
|
6
|
-
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
7
|
-
var attachmentSchema = z.object({
|
|
8
|
-
type: z.literal("attachment"),
|
|
9
|
-
data: z.instanceof(Buffer),
|
|
10
|
-
mimeType: z.string().nonempty(),
|
|
11
|
-
name: z.string().nonempty()
|
|
12
|
-
});
|
|
13
|
-
var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
|
|
14
|
-
var resolveAttachmentMimeType = (name, mimeType) => {
|
|
15
|
-
if (mimeType) {
|
|
16
|
-
return mimeType;
|
|
17
|
-
}
|
|
18
|
-
const resolvedMimeType = lookupMimeType(name);
|
|
19
|
-
if (!resolvedMimeType) {
|
|
20
|
-
throw new Error(
|
|
21
|
-
`Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
return resolvedMimeType;
|
|
25
|
-
};
|
|
26
|
-
var asAttachment = (input) => attachmentSchema.parse({ type: "attachment", ...input });
|
|
27
|
-
function attachment(input, options) {
|
|
28
|
-
return {
|
|
29
|
-
build: async () => {
|
|
30
|
-
const data = typeof input === "string" ? await readFile(input) : input;
|
|
31
|
-
const name = resolveAttachmentName(input, options?.name);
|
|
32
|
-
return asAttachment({
|
|
33
|
-
data,
|
|
34
|
-
mimeType: resolveAttachmentMimeType(name, options?.mimeType),
|
|
35
|
-
name
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
asAttachment,
|
|
43
|
-
attachment
|
|
44
|
-
};
|