spectrum-ts 1.9.2 → 1.11.3
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-XZSBR26X.js → chunk-3BTOWGQL.js} +96 -510
- package/dist/{chunk-N3ZKMTSG.js → chunk-AYB6DT76.js} +8 -6
- package/dist/{chunk-TN54TDTQ.js → chunk-EW5XWI3Y.js} +1 -1
- package/dist/{chunk-7O5BCLGQ.js → chunk-G7TWBZUE.js} +107 -35
- package/dist/chunk-KO67KDBD.js +61 -0
- package/dist/chunk-LCJMR75R.js +457 -0
- package/dist/{chunk-OR3VGVML.js → chunk-PUMFTTA4.js} +8 -4
- package/dist/chunk-T2TBVX6C.js +524 -0
- package/dist/{chunk-HWADNTQF.js → chunk-YKWKZ2PZ.js} +4 -59
- package/dist/{chunk-5NHNMN4H.js → chunk-YM4OAVPX.js} +1 -1
- package/dist/index.d.ts +41 -30
- package/dist/index.js +13 -9
- package/dist/providers/imessage/index.d.ts +30 -3
- package/dist/providers/imessage/index.js +10 -6
- package/dist/providers/index.d.ts +3 -1
- package/dist/providers/index.js +13 -7
- package/dist/providers/slack/index.d.ts +47 -0
- package/dist/providers/slack/index.js +8 -0
- package/dist/providers/terminal/index.d.ts +10 -10
- package/dist/providers/terminal/index.js +4 -3
- package/dist/providers/whatsapp-business/index.d.ts +2 -2
- package/dist/providers/whatsapp-business/index.js +5 -3
- package/dist/{types-lUyzRurY.d.ts → types-Dd3RC_60.d.ts} +93 -52
- package/package.json +12 -1
|
@@ -93,458 +93,11 @@ function attachment(input, options) {
|
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
// src/utils/vcard.ts
|
|
97
|
-
import vCard from "vcf";
|
|
98
|
-
var asPropertyArray = (prop) => {
|
|
99
|
-
if (!prop) {
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
const arr = Array.isArray(prop) ? prop : [prop];
|
|
103
|
-
return arr;
|
|
104
|
-
};
|
|
105
|
-
var propString = (prop) => {
|
|
106
|
-
const [first] = asPropertyArray(prop);
|
|
107
|
-
const value = first?.valueOf().trim();
|
|
108
|
-
return value ? value : void 0;
|
|
109
|
-
};
|
|
110
|
-
var paramTypes = (prop) => {
|
|
111
|
-
const { type } = prop;
|
|
112
|
-
if (!type) {
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
return (Array.isArray(type) ? type : [type]).map((t) => t.toLowerCase());
|
|
116
|
-
};
|
|
117
|
-
var mapPhoneType = (prop) => {
|
|
118
|
-
const types = paramTypes(prop);
|
|
119
|
-
if (types.some((t) => t === "cell" || t === "mobile" || t === "iphone")) {
|
|
120
|
-
return "mobile";
|
|
121
|
-
}
|
|
122
|
-
if (types.includes("home")) {
|
|
123
|
-
return "home";
|
|
124
|
-
}
|
|
125
|
-
if (types.includes("work")) {
|
|
126
|
-
return "work";
|
|
127
|
-
}
|
|
128
|
-
if (types.length > 0) {
|
|
129
|
-
return "other";
|
|
130
|
-
}
|
|
131
|
-
return;
|
|
132
|
-
};
|
|
133
|
-
var mapSimpleType = (prop) => {
|
|
134
|
-
const types = paramTypes(prop);
|
|
135
|
-
if (types.includes("home")) {
|
|
136
|
-
return "home";
|
|
137
|
-
}
|
|
138
|
-
if (types.includes("work")) {
|
|
139
|
-
return "work";
|
|
140
|
-
}
|
|
141
|
-
if (types.length > 0) {
|
|
142
|
-
return "other";
|
|
143
|
-
}
|
|
144
|
-
return;
|
|
145
|
-
};
|
|
146
|
-
var splitStructured = (value) => value.split(";").map((part) => part.trim());
|
|
147
|
-
var extractName = (card) => {
|
|
148
|
-
const fn = propString(card.data.fn);
|
|
149
|
-
const n = propString(card.data.n);
|
|
150
|
-
if (!(fn || n)) {
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const result = {};
|
|
154
|
-
if (fn) {
|
|
155
|
-
result.formatted = fn;
|
|
156
|
-
}
|
|
157
|
-
if (n) {
|
|
158
|
-
const [last, first, middle, prefix, suffix] = splitStructured(n);
|
|
159
|
-
if (first) {
|
|
160
|
-
result.first = first;
|
|
161
|
-
}
|
|
162
|
-
if (last) {
|
|
163
|
-
result.last = last;
|
|
164
|
-
}
|
|
165
|
-
if (middle) {
|
|
166
|
-
result.middle = middle;
|
|
167
|
-
}
|
|
168
|
-
if (prefix) {
|
|
169
|
-
result.prefix = prefix;
|
|
170
|
-
}
|
|
171
|
-
if (suffix) {
|
|
172
|
-
result.suffix = suffix;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return result;
|
|
176
|
-
};
|
|
177
|
-
var extractPhones = (card) => {
|
|
178
|
-
const props = asPropertyArray(card.data.tel);
|
|
179
|
-
if (props.length === 0) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
return props.map((p) => {
|
|
183
|
-
const entry = { value: p.valueOf().trim() };
|
|
184
|
-
const type = mapPhoneType(p);
|
|
185
|
-
if (type) {
|
|
186
|
-
entry.type = type;
|
|
187
|
-
}
|
|
188
|
-
return entry;
|
|
189
|
-
});
|
|
190
|
-
};
|
|
191
|
-
var extractEmails = (card) => {
|
|
192
|
-
const props = asPropertyArray(card.data.email);
|
|
193
|
-
if (props.length === 0) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
return props.map((p) => {
|
|
197
|
-
const entry = { value: p.valueOf().trim() };
|
|
198
|
-
const type = mapSimpleType(p);
|
|
199
|
-
if (type) {
|
|
200
|
-
entry.type = type;
|
|
201
|
-
}
|
|
202
|
-
return entry;
|
|
203
|
-
});
|
|
204
|
-
};
|
|
205
|
-
var extractAddresses = (card) => {
|
|
206
|
-
const props = asPropertyArray(card.data.adr);
|
|
207
|
-
if (props.length === 0) {
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
return props.map((p) => {
|
|
211
|
-
const [, , street, city, region, postalCode, country] = splitStructured(
|
|
212
|
-
p.valueOf()
|
|
213
|
-
);
|
|
214
|
-
const entry = {};
|
|
215
|
-
if (street) {
|
|
216
|
-
entry.street = street;
|
|
217
|
-
}
|
|
218
|
-
if (city) {
|
|
219
|
-
entry.city = city;
|
|
220
|
-
}
|
|
221
|
-
if (region) {
|
|
222
|
-
entry.region = region;
|
|
223
|
-
}
|
|
224
|
-
if (postalCode) {
|
|
225
|
-
entry.postalCode = postalCode;
|
|
226
|
-
}
|
|
227
|
-
if (country) {
|
|
228
|
-
entry.country = country;
|
|
229
|
-
}
|
|
230
|
-
const type = mapSimpleType(p);
|
|
231
|
-
if (type) {
|
|
232
|
-
entry.type = type;
|
|
233
|
-
}
|
|
234
|
-
return entry;
|
|
235
|
-
});
|
|
236
|
-
};
|
|
237
|
-
var extractOrg = (card) => {
|
|
238
|
-
const orgStr = propString(card.data.org);
|
|
239
|
-
const title = propString(card.data.title);
|
|
240
|
-
if (!(orgStr || title)) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
const result = {};
|
|
244
|
-
if (orgStr) {
|
|
245
|
-
const [name, department] = splitStructured(orgStr);
|
|
246
|
-
if (name) {
|
|
247
|
-
result.name = name;
|
|
248
|
-
}
|
|
249
|
-
if (department) {
|
|
250
|
-
result.department = department;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
if (title) {
|
|
254
|
-
result.title = title;
|
|
255
|
-
}
|
|
256
|
-
return result;
|
|
257
|
-
};
|
|
258
|
-
var extractUrls = (card) => {
|
|
259
|
-
const props = asPropertyArray(card.data.url);
|
|
260
|
-
if (props.length === 0) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
return props.map((p) => p.valueOf().trim());
|
|
264
|
-
};
|
|
265
|
-
var photoMimeFromType = (type) => {
|
|
266
|
-
if (!type) {
|
|
267
|
-
return "image/jpeg";
|
|
268
|
-
}
|
|
269
|
-
const lower = type.toLowerCase();
|
|
270
|
-
if (lower.startsWith("image/")) {
|
|
271
|
-
return lower;
|
|
272
|
-
}
|
|
273
|
-
return `image/${lower}`;
|
|
274
|
-
};
|
|
275
|
-
var DATA_URI_PATTERN = /^data:([^;,]+);base64,(.*)$/i;
|
|
276
|
-
var extractPhoto = (card) => {
|
|
277
|
-
const [prop] = asPropertyArray(card.data.photo);
|
|
278
|
-
if (!prop) {
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
const value = prop.valueOf();
|
|
282
|
-
const dataUriMatch = DATA_URI_PATTERN.exec(value);
|
|
283
|
-
if (dataUriMatch) {
|
|
284
|
-
const [, mimeType, base64] = dataUriMatch;
|
|
285
|
-
const buf2 = Buffer.from(base64 ?? "", "base64");
|
|
286
|
-
return {
|
|
287
|
-
mimeType: mimeType ?? "image/jpeg",
|
|
288
|
-
read: async () => buf2
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
const type = Array.isArray(prop.type) ? prop.type[0] : prop.type;
|
|
292
|
-
const buf = Buffer.from(value, "base64");
|
|
293
|
-
return {
|
|
294
|
-
mimeType: photoMimeFromType(type),
|
|
295
|
-
read: async () => buf
|
|
296
|
-
};
|
|
297
|
-
};
|
|
298
|
-
var normalizeVCardInput = (vcf) => {
|
|
299
|
-
const withoutBom = vcf.charCodeAt(0) === 65279 ? vcf.slice(1) : vcf;
|
|
300
|
-
return withoutBom.replace(/\r\n|\r|\n/g, "\r\n");
|
|
301
|
-
};
|
|
302
|
-
var fromVCard = (vcf) => {
|
|
303
|
-
const [card] = vCard.parse(normalizeVCardInput(vcf));
|
|
304
|
-
if (!card) {
|
|
305
|
-
throw new Error("Invalid vCard: no cards parsed");
|
|
306
|
-
}
|
|
307
|
-
const input = { raw: vcf };
|
|
308
|
-
const name = extractName(card);
|
|
309
|
-
if (name) {
|
|
310
|
-
input.name = name;
|
|
311
|
-
}
|
|
312
|
-
const phones = extractPhones(card);
|
|
313
|
-
if (phones) {
|
|
314
|
-
input.phones = phones;
|
|
315
|
-
}
|
|
316
|
-
const emails = extractEmails(card);
|
|
317
|
-
if (emails) {
|
|
318
|
-
input.emails = emails;
|
|
319
|
-
}
|
|
320
|
-
const addresses = extractAddresses(card);
|
|
321
|
-
if (addresses) {
|
|
322
|
-
input.addresses = addresses;
|
|
323
|
-
}
|
|
324
|
-
const org = extractOrg(card);
|
|
325
|
-
if (org) {
|
|
326
|
-
input.org = org;
|
|
327
|
-
}
|
|
328
|
-
const urls = extractUrls(card);
|
|
329
|
-
if (urls) {
|
|
330
|
-
input.urls = urls;
|
|
331
|
-
}
|
|
332
|
-
const birthday = propString(card.data.bday);
|
|
333
|
-
if (birthday) {
|
|
334
|
-
input.birthday = birthday;
|
|
335
|
-
}
|
|
336
|
-
const note = propString(card.data.note);
|
|
337
|
-
if (note) {
|
|
338
|
-
input.note = note;
|
|
339
|
-
}
|
|
340
|
-
const photo = extractPhoto(card);
|
|
341
|
-
if (photo) {
|
|
342
|
-
input.photo = photo;
|
|
343
|
-
}
|
|
344
|
-
return input;
|
|
345
|
-
};
|
|
346
|
-
var formattedNameFor = (name) => {
|
|
347
|
-
if (name?.formatted) {
|
|
348
|
-
return name.formatted;
|
|
349
|
-
}
|
|
350
|
-
const parts = [name?.first, name?.middle, name?.last].filter(
|
|
351
|
-
(p) => Boolean(p)
|
|
352
|
-
);
|
|
353
|
-
if (parts.length > 0) {
|
|
354
|
-
return parts.join(" ");
|
|
355
|
-
}
|
|
356
|
-
return "Unknown";
|
|
357
|
-
};
|
|
358
|
-
var phoneTypeParam = (type) => {
|
|
359
|
-
if (type === "mobile") {
|
|
360
|
-
return "CELL";
|
|
361
|
-
}
|
|
362
|
-
if (type === "home" || type === "work" || type === "other") {
|
|
363
|
-
return type.toUpperCase();
|
|
364
|
-
}
|
|
365
|
-
return;
|
|
366
|
-
};
|
|
367
|
-
var simpleTypeParam = (type) => type ? type.toUpperCase() : void 0;
|
|
368
|
-
var photoTypeParam = (mimeType) => {
|
|
369
|
-
const sub = mimeType.split("/")[1] ?? "jpeg";
|
|
370
|
-
return sub.toUpperCase();
|
|
371
|
-
};
|
|
372
|
-
var writeName = (card, name) => {
|
|
373
|
-
card.set("fn", formattedNameFor(name));
|
|
374
|
-
if (!name) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
if (name.first || name.last || name.middle || name.prefix || name.suffix) {
|
|
378
|
-
card.set(
|
|
379
|
-
"n",
|
|
380
|
-
[
|
|
381
|
-
name.last ?? "",
|
|
382
|
-
name.first ?? "",
|
|
383
|
-
name.middle ?? "",
|
|
384
|
-
name.prefix ?? "",
|
|
385
|
-
name.suffix ?? ""
|
|
386
|
-
].join(";")
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
};
|
|
390
|
-
var writePhones = (card, phones) => {
|
|
391
|
-
for (const phone of phones ?? []) {
|
|
392
|
-
const type = phoneTypeParam(phone.type);
|
|
393
|
-
card.add("tel", phone.value, type ? { type } : void 0);
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
var writeEmails = (card, emails) => {
|
|
397
|
-
for (const email of emails ?? []) {
|
|
398
|
-
const type = simpleTypeParam(email.type);
|
|
399
|
-
card.add("email", email.value, type ? { type } : void 0);
|
|
400
|
-
}
|
|
401
|
-
};
|
|
402
|
-
var writeAddresses = (card, addresses) => {
|
|
403
|
-
for (const addr of addresses ?? []) {
|
|
404
|
-
const value = [
|
|
405
|
-
"",
|
|
406
|
-
"",
|
|
407
|
-
addr.street ?? "",
|
|
408
|
-
addr.city ?? "",
|
|
409
|
-
addr.region ?? "",
|
|
410
|
-
addr.postalCode ?? "",
|
|
411
|
-
addr.country ?? ""
|
|
412
|
-
].join(";");
|
|
413
|
-
const type = simpleTypeParam(addr.type);
|
|
414
|
-
card.add("adr", value, type ? { type } : void 0);
|
|
415
|
-
}
|
|
416
|
-
};
|
|
417
|
-
var writeOrg = (card, org) => {
|
|
418
|
-
if (!org) {
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
if (org.name || org.department) {
|
|
422
|
-
card.set("org", [org.name ?? "", org.department ?? ""].join(";"));
|
|
423
|
-
}
|
|
424
|
-
if (org.title) {
|
|
425
|
-
card.set("title", org.title);
|
|
426
|
-
}
|
|
427
|
-
};
|
|
428
|
-
var writeUrls = (card, urls) => {
|
|
429
|
-
for (const url of urls ?? []) {
|
|
430
|
-
card.add("url", url);
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
var writePhoto = async (card, photo) => {
|
|
434
|
-
if (!photo) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
const buf = await photo.read();
|
|
438
|
-
card.set("photo", buf.toString("base64"), {
|
|
439
|
-
encoding: "b",
|
|
440
|
-
type: photoTypeParam(photo.mimeType)
|
|
441
|
-
});
|
|
442
|
-
};
|
|
443
|
-
var toVCard = async (contact2) => {
|
|
444
|
-
if (typeof contact2.raw === "string" && contact2.raw.startsWith("BEGIN:VCARD")) {
|
|
445
|
-
return contact2.raw;
|
|
446
|
-
}
|
|
447
|
-
const card = new vCard();
|
|
448
|
-
writeName(card, contact2.name);
|
|
449
|
-
writePhones(card, contact2.phones);
|
|
450
|
-
writeEmails(card, contact2.emails);
|
|
451
|
-
writeAddresses(card, contact2.addresses);
|
|
452
|
-
writeOrg(card, contact2.org);
|
|
453
|
-
writeUrls(card, contact2.urls);
|
|
454
|
-
if (contact2.birthday) {
|
|
455
|
-
card.set("bday", contact2.birthday);
|
|
456
|
-
}
|
|
457
|
-
if (contact2.note) {
|
|
458
|
-
card.set("note", contact2.note);
|
|
459
|
-
}
|
|
460
|
-
await writePhoto(card, contact2.photo);
|
|
461
|
-
return card.toString();
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
// src/content/contact.ts
|
|
465
|
-
import vCard2 from "vcf";
|
|
466
|
-
import z3 from "zod";
|
|
467
|
-
var userRefSchema = z3.object({
|
|
468
|
-
__platform: z3.string(),
|
|
469
|
-
id: z3.string()
|
|
470
|
-
});
|
|
471
|
-
var nameSchema = z3.object({
|
|
472
|
-
formatted: z3.string().optional(),
|
|
473
|
-
first: z3.string().optional(),
|
|
474
|
-
last: z3.string().optional(),
|
|
475
|
-
middle: z3.string().optional(),
|
|
476
|
-
prefix: z3.string().optional(),
|
|
477
|
-
suffix: z3.string().optional()
|
|
478
|
-
});
|
|
479
|
-
var phoneTypeSchema = z3.enum(["mobile", "home", "work", "other"]);
|
|
480
|
-
var emailTypeSchema = z3.enum(["home", "work", "other"]);
|
|
481
|
-
var addressTypeSchema = z3.enum(["home", "work", "other"]);
|
|
482
|
-
var phoneSchema = z3.object({
|
|
483
|
-
value: z3.string(),
|
|
484
|
-
type: phoneTypeSchema.optional()
|
|
485
|
-
});
|
|
486
|
-
var emailSchema = z3.object({
|
|
487
|
-
value: z3.string(),
|
|
488
|
-
type: emailTypeSchema.optional()
|
|
489
|
-
});
|
|
490
|
-
var addressSchema = z3.object({
|
|
491
|
-
street: z3.string().optional(),
|
|
492
|
-
city: z3.string().optional(),
|
|
493
|
-
region: z3.string().optional(),
|
|
494
|
-
postalCode: z3.string().optional(),
|
|
495
|
-
country: z3.string().optional(),
|
|
496
|
-
type: addressTypeSchema.optional()
|
|
497
|
-
});
|
|
498
|
-
var orgSchema = z3.object({
|
|
499
|
-
name: z3.string().optional(),
|
|
500
|
-
title: z3.string().optional(),
|
|
501
|
-
department: z3.string().optional()
|
|
502
|
-
});
|
|
503
|
-
var photoSchema = z3.object({
|
|
504
|
-
mimeType: z3.string(),
|
|
505
|
-
read: readSchema
|
|
506
|
-
});
|
|
507
|
-
var contactSchema = z3.object({
|
|
508
|
-
type: z3.literal("contact"),
|
|
509
|
-
user: userRefSchema.optional(),
|
|
510
|
-
name: nameSchema.optional(),
|
|
511
|
-
phones: z3.array(phoneSchema).optional(),
|
|
512
|
-
emails: z3.array(emailSchema).optional(),
|
|
513
|
-
addresses: z3.array(addressSchema).optional(),
|
|
514
|
-
org: orgSchema.optional(),
|
|
515
|
-
urls: z3.array(z3.string()).optional(),
|
|
516
|
-
birthday: z3.string().optional(),
|
|
517
|
-
note: z3.string().optional(),
|
|
518
|
-
photo: photoSchema.optional(),
|
|
519
|
-
raw: z3.unknown().optional()
|
|
520
|
-
});
|
|
521
|
-
var asContact = (input) => contactSchema.parse({ type: "contact", ...input });
|
|
522
|
-
var isUser = (value) => typeof value === "object" && value !== null && "__platform" in value && "id" in value && typeof value.__platform === "string" && typeof value.id === "string";
|
|
523
|
-
function contact(input, details) {
|
|
524
|
-
return {
|
|
525
|
-
build: async () => {
|
|
526
|
-
if (typeof input === "string") {
|
|
527
|
-
return asContact(fromVCard(input));
|
|
528
|
-
}
|
|
529
|
-
if (input instanceof vCard2) {
|
|
530
|
-
return asContact(fromVCard(input.toString()));
|
|
531
|
-
}
|
|
532
|
-
if (isUser(input)) {
|
|
533
|
-
return asContact({
|
|
534
|
-
user: { __platform: input.__platform, id: input.id },
|
|
535
|
-
...details
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
return asContact(input);
|
|
539
|
-
}
|
|
540
|
-
};
|
|
541
|
-
}
|
|
542
|
-
|
|
543
96
|
// src/content/custom.ts
|
|
544
|
-
import
|
|
545
|
-
var customSchema =
|
|
546
|
-
type:
|
|
547
|
-
raw:
|
|
97
|
+
import z3 from "zod";
|
|
98
|
+
var customSchema = z3.object({
|
|
99
|
+
type: z3.literal("custom"),
|
|
100
|
+
raw: z3.unknown()
|
|
548
101
|
});
|
|
549
102
|
var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
|
|
550
103
|
function custom(raw) {
|
|
@@ -554,10 +107,10 @@ function custom(raw) {
|
|
|
554
107
|
}
|
|
555
108
|
|
|
556
109
|
// src/content/text.ts
|
|
557
|
-
import
|
|
558
|
-
var textSchema =
|
|
559
|
-
type:
|
|
560
|
-
text:
|
|
110
|
+
import z4 from "zod";
|
|
111
|
+
var textSchema = z4.object({
|
|
112
|
+
type: z4.literal("text"),
|
|
113
|
+
text: z4.string().nonempty()
|
|
561
114
|
});
|
|
562
115
|
var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
|
|
563
116
|
function text(text2) {
|
|
@@ -572,15 +125,15 @@ var resolveContents = (items) => Promise.all(
|
|
|
572
125
|
);
|
|
573
126
|
|
|
574
127
|
// src/content/edit.ts
|
|
575
|
-
import
|
|
128
|
+
import z5 from "zod";
|
|
576
129
|
var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
577
130
|
var isContent = (v) => typeof v === "object" && v !== null && "type" in v && typeof v.type === "string";
|
|
578
|
-
var editSchema =
|
|
579
|
-
type:
|
|
580
|
-
content:
|
|
131
|
+
var editSchema = z5.object({
|
|
132
|
+
type: z5.literal("edit"),
|
|
133
|
+
content: z5.custom(isContent, {
|
|
581
134
|
message: "edit content must be a Content value"
|
|
582
135
|
}),
|
|
583
|
-
target:
|
|
136
|
+
target: z5.custom(isMessage, {
|
|
584
137
|
message: "edit target must be a Message"
|
|
585
138
|
})
|
|
586
139
|
});
|
|
@@ -588,6 +141,11 @@ var asEdit = (input) => editSchema.parse({ type: "edit", ...input });
|
|
|
588
141
|
function edit(content, target) {
|
|
589
142
|
return {
|
|
590
143
|
build: async () => {
|
|
144
|
+
if (target.direction !== "outbound") {
|
|
145
|
+
throw new Error(
|
|
146
|
+
`edit() target must be an outbound message (got direction "${target.direction}", message id "${target.id}")`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
591
149
|
const [resolved] = await resolveContents([content]);
|
|
592
150
|
if (!resolved) {
|
|
593
151
|
throw new Error("edit() requires content");
|
|
@@ -601,12 +159,12 @@ function edit(content, target) {
|
|
|
601
159
|
}
|
|
602
160
|
|
|
603
161
|
// src/content/reaction.ts
|
|
604
|
-
import
|
|
162
|
+
import z6 from "zod";
|
|
605
163
|
var isMessage2 = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
606
|
-
var reactionSchema =
|
|
607
|
-
type:
|
|
608
|
-
emoji:
|
|
609
|
-
target:
|
|
164
|
+
var reactionSchema = z6.object({
|
|
165
|
+
type: z6.literal("reaction"),
|
|
166
|
+
emoji: z6.string().min(1),
|
|
167
|
+
target: z6.custom(isMessage2, {
|
|
610
168
|
message: "reaction target must be a Message"
|
|
611
169
|
})
|
|
612
170
|
});
|
|
@@ -623,15 +181,15 @@ function reaction(emoji, target) {
|
|
|
623
181
|
}
|
|
624
182
|
|
|
625
183
|
// src/content/reply.ts
|
|
626
|
-
import
|
|
184
|
+
import z7 from "zod";
|
|
627
185
|
var isMessage3 = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
628
186
|
var isContent2 = (v) => typeof v === "object" && v !== null && "type" in v && typeof v.type === "string";
|
|
629
|
-
var replySchema =
|
|
630
|
-
type:
|
|
631
|
-
content:
|
|
187
|
+
var replySchema = z7.object({
|
|
188
|
+
type: z7.literal("reply"),
|
|
189
|
+
content: z7.custom(isContent2, {
|
|
632
190
|
message: "reply content must be a Content value"
|
|
633
191
|
}),
|
|
634
|
-
target:
|
|
192
|
+
target: z7.custom(isMessage3, {
|
|
635
193
|
message: "reply target must be a Message"
|
|
636
194
|
})
|
|
637
195
|
});
|
|
@@ -652,10 +210,10 @@ function reply(content, target) {
|
|
|
652
210
|
}
|
|
653
211
|
|
|
654
212
|
// src/content/typing.ts
|
|
655
|
-
import
|
|
656
|
-
var typingSchema =
|
|
657
|
-
type:
|
|
658
|
-
state:
|
|
213
|
+
import z8 from "zod";
|
|
214
|
+
var typingSchema = z8.object({
|
|
215
|
+
type: z8.literal("typing"),
|
|
216
|
+
state: z8.enum(["start", "stop"])
|
|
659
217
|
});
|
|
660
218
|
function typing(state = "start") {
|
|
661
219
|
return {
|
|
@@ -860,8 +418,20 @@ var RESERVED_SPACE_KEYS = /* @__PURE__ */ new Set([
|
|
|
860
418
|
"stopTyping",
|
|
861
419
|
"responding"
|
|
862
420
|
]);
|
|
863
|
-
var
|
|
864
|
-
|
|
421
|
+
var RESERVED_MESSAGE_KEYS = /* @__PURE__ */ new Set([
|
|
422
|
+
"content",
|
|
423
|
+
"direction",
|
|
424
|
+
"edit",
|
|
425
|
+
"id",
|
|
426
|
+
"platform",
|
|
427
|
+
"react",
|
|
428
|
+
"reply",
|
|
429
|
+
"sender",
|
|
430
|
+
"space",
|
|
431
|
+
"timestamp"
|
|
432
|
+
]);
|
|
433
|
+
var warnReservedAction = (scope, name, platform) => {
|
|
434
|
+
const body = `[spectrum-ts] ${platform} declared ${scope} action "${name}" which collides with a reserved ${scope === "space" ? "Space" : "Message"} key; skipping.`;
|
|
865
435
|
console.warn(
|
|
866
436
|
supportsAnsiColor() ? `${ANSI_YELLOW}${body}${ANSI_RESET}` : body
|
|
867
437
|
);
|
|
@@ -1110,10 +680,12 @@ function buildSpace(params) {
|
|
|
1110
680
|
if (declaredActions) {
|
|
1111
681
|
for (const [name, factory] of Object.entries(declaredActions)) {
|
|
1112
682
|
if (RESERVED_SPACE_KEYS.has(name)) {
|
|
1113
|
-
warnReservedAction(name, definition.name);
|
|
683
|
+
warnReservedAction("space", name, definition.name);
|
|
1114
684
|
continue;
|
|
1115
685
|
}
|
|
1116
|
-
platformActions[name] = (...args) =>
|
|
686
|
+
platformActions[name] = async (...args) => {
|
|
687
|
+
await factory(space, ...args);
|
|
688
|
+
};
|
|
1117
689
|
}
|
|
1118
690
|
}
|
|
1119
691
|
space = {
|
|
@@ -1146,10 +718,6 @@ function buildSpace(params) {
|
|
|
1146
718
|
function buildMessage(params) {
|
|
1147
719
|
const { definition, space } = params;
|
|
1148
720
|
let self;
|
|
1149
|
-
const react = async (emoji) => {
|
|
1150
|
-
const target = requireBuiltMessage("react");
|
|
1151
|
-
await space.send(reaction(emoji, target));
|
|
1152
|
-
};
|
|
1153
721
|
const requireBuiltMessage = (action) => {
|
|
1154
722
|
if (!self) {
|
|
1155
723
|
throw new Error(
|
|
@@ -1158,46 +726,68 @@ function buildMessage(params) {
|
|
|
1158
726
|
}
|
|
1159
727
|
return self;
|
|
1160
728
|
};
|
|
729
|
+
const react = async (emoji) => {
|
|
730
|
+
const target = requireBuiltMessage("react");
|
|
731
|
+
await space.send(reaction(emoji, target));
|
|
732
|
+
};
|
|
1161
733
|
async function reply2(...content) {
|
|
1162
734
|
const target = requireBuiltMessage("reply");
|
|
1163
735
|
const wrapped = content.map((c) => reply(c, target));
|
|
1164
736
|
return space.send(...wrapped);
|
|
1165
737
|
}
|
|
1166
|
-
const
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
738
|
+
const edit2 = async (newContent) => {
|
|
739
|
+
const target = requireBuiltMessage("edit");
|
|
740
|
+
if (target.direction !== "outbound") {
|
|
741
|
+
throw new Error(
|
|
742
|
+
`cannot edit message ${target.id}: only outbound messages can be edited (direction: "${target.direction}")`
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
await space.send(edit(newContent, target));
|
|
746
|
+
};
|
|
747
|
+
const buildSenderWithPlatform = () => {
|
|
748
|
+
if (params.sender === void 0) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (params.direction === "outbound") {
|
|
752
|
+
return {
|
|
753
|
+
...params.sender,
|
|
754
|
+
__platform: definition.name,
|
|
755
|
+
kind: "agent"
|
|
756
|
+
};
|
|
757
|
+
}
|
|
758
|
+
return { ...params.sender, __platform: definition.name };
|
|
759
|
+
};
|
|
760
|
+
const senderWithPlatform = buildSenderWithPlatform();
|
|
761
|
+
const messagePlatformActions = {};
|
|
762
|
+
const declaredMessageActions = definition.message?.actions;
|
|
763
|
+
if (declaredMessageActions) {
|
|
764
|
+
for (const [name, factory] of Object.entries(declaredMessageActions)) {
|
|
765
|
+
if (RESERVED_MESSAGE_KEYS.has(name)) {
|
|
766
|
+
warnReservedAction("message", name, definition.name);
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
messagePlatformActions[name] = async (...args) => {
|
|
770
|
+
const target = requireBuiltMessage(name);
|
|
771
|
+
await factory(target, ...args);
|
|
772
|
+
};
|
|
773
|
+
}
|
|
1186
774
|
}
|
|
1187
|
-
const
|
|
775
|
+
const message = {
|
|
1188
776
|
...params.extras,
|
|
777
|
+
...messagePlatformActions,
|
|
1189
778
|
id: params.id,
|
|
1190
779
|
content: params.content,
|
|
1191
|
-
direction:
|
|
780
|
+
direction: params.direction,
|
|
1192
781
|
platform: definition.name,
|
|
1193
782
|
react,
|
|
1194
783
|
reply: reply2,
|
|
784
|
+
edit: edit2,
|
|
1195
785
|
sender: senderWithPlatform,
|
|
1196
786
|
space,
|
|
1197
787
|
timestamp: params.timestamp
|
|
1198
788
|
};
|
|
1199
|
-
self =
|
|
1200
|
-
return
|
|
789
|
+
self = message;
|
|
790
|
+
return message;
|
|
1201
791
|
}
|
|
1202
792
|
|
|
1203
793
|
// src/platform/define.ts
|
|
@@ -1435,10 +1025,6 @@ export {
|
|
|
1435
1025
|
attachmentSchema,
|
|
1436
1026
|
asAttachment,
|
|
1437
1027
|
attachment,
|
|
1438
|
-
fromVCard,
|
|
1439
|
-
toVCard,
|
|
1440
|
-
asContact,
|
|
1441
|
-
contact,
|
|
1442
1028
|
asCustom,
|
|
1443
1029
|
custom,
|
|
1444
1030
|
textSchema,
|