spectrum-ts 0.8.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-H5XYVRHM.js → chunk-HU2EOF3K.js} +41 -11
- package/dist/{chunk-ZNUORCLB.js → chunk-OIXH5S65.js} +17 -0
- package/dist/{chunk-4O6MQC5Z.js → chunk-U6WCQVVX.js} +198 -38
- package/dist/index.d.ts +1979 -3
- package/dist/index.js +1963 -30
- package/dist/providers/imessage/index.d.ts +17 -17
- package/dist/providers/imessage/index.js +399 -62
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/terminal/index.js +1 -1
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +15 -6
- package/dist/{types-DLrsDzV-.d.ts → types-D5KhSXLy.d.ts} +30 -1
- package/package.json +1 -1
|
@@ -2,10 +2,38 @@ import {
|
|
|
2
2
|
bufferToStream,
|
|
3
3
|
readSchema,
|
|
4
4
|
streamSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OIXH5S65.js";
|
|
6
|
+
import {
|
|
7
|
+
resolveContents
|
|
8
|
+
} from "./chunk-U6WCQVVX.js";
|
|
6
9
|
|
|
7
|
-
// src/content/
|
|
10
|
+
// src/content/group.ts
|
|
8
11
|
import z from "zod";
|
|
12
|
+
var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
13
|
+
var groupSchema = z.object({
|
|
14
|
+
type: z.literal("group"),
|
|
15
|
+
items: z.array(z.custom(isMessage)).min(2)
|
|
16
|
+
});
|
|
17
|
+
var asGroup = (input) => groupSchema.parse({ type: "group", items: input.items });
|
|
18
|
+
var stubOutboundMessage = (content) => ({ id: "", content });
|
|
19
|
+
function group(...items) {
|
|
20
|
+
return {
|
|
21
|
+
build: async () => {
|
|
22
|
+
const resolved = await resolveContents(items);
|
|
23
|
+
const members = [];
|
|
24
|
+
for (const item of resolved) {
|
|
25
|
+
if (item.type === "group" || item.type === "reaction") {
|
|
26
|
+
throw new Error(`group() cannot contain "${item.type}" items`);
|
|
27
|
+
}
|
|
28
|
+
members.push(stubOutboundMessage(item));
|
|
29
|
+
}
|
|
30
|
+
return asGroup({ items: members });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/content/richlink.ts
|
|
36
|
+
import z2 from "zod";
|
|
9
37
|
|
|
10
38
|
// src/utils/link-metadata.ts
|
|
11
39
|
import ogs from "open-graph-scraper";
|
|
@@ -76,22 +104,22 @@ var fetchImage = async (url) => {
|
|
|
76
104
|
};
|
|
77
105
|
|
|
78
106
|
// src/content/richlink.ts
|
|
79
|
-
var richlinkCoverSchema =
|
|
80
|
-
mimeType:
|
|
107
|
+
var richlinkCoverSchema = z2.object({
|
|
108
|
+
mimeType: z2.string().min(1).optional(),
|
|
81
109
|
read: readSchema,
|
|
82
110
|
stream: streamSchema
|
|
83
111
|
});
|
|
84
|
-
var optionalStringAccessor =
|
|
112
|
+
var optionalStringAccessor = z2.function({
|
|
85
113
|
input: [],
|
|
86
|
-
output:
|
|
114
|
+
output: z2.promise(z2.string().min(1).optional())
|
|
87
115
|
});
|
|
88
|
-
var coverAccessor =
|
|
116
|
+
var coverAccessor = z2.function({
|
|
89
117
|
input: [],
|
|
90
|
-
output:
|
|
118
|
+
output: z2.promise(richlinkCoverSchema.optional())
|
|
91
119
|
});
|
|
92
|
-
var richlinkSchema =
|
|
93
|
-
type:
|
|
94
|
-
url:
|
|
120
|
+
var richlinkSchema = z2.object({
|
|
121
|
+
type: z2.literal("richlink"),
|
|
122
|
+
url: z2.url(),
|
|
95
123
|
title: optionalStringAccessor,
|
|
96
124
|
summary: optionalStringAccessor,
|
|
97
125
|
cover: coverAccessor
|
|
@@ -136,6 +164,8 @@ function richlink(url) {
|
|
|
136
164
|
}
|
|
137
165
|
|
|
138
166
|
export {
|
|
167
|
+
asGroup,
|
|
168
|
+
group,
|
|
139
169
|
asRichlink,
|
|
140
170
|
richlink
|
|
141
171
|
};
|
|
@@ -553,6 +553,21 @@ function custom(raw) {
|
|
|
553
553
|
};
|
|
554
554
|
}
|
|
555
555
|
|
|
556
|
+
// src/content/reaction.ts
|
|
557
|
+
import z5 from "zod";
|
|
558
|
+
var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
559
|
+
var reactionSchema = z5.object({
|
|
560
|
+
type: z5.literal("reaction"),
|
|
561
|
+
emoji: z5.string().min(1),
|
|
562
|
+
target: z5.custom(isMessage, {
|
|
563
|
+
message: "reaction target must be a Message"
|
|
564
|
+
})
|
|
565
|
+
});
|
|
566
|
+
var asReaction = (input) => reactionSchema.parse({ type: "reaction", ...input });
|
|
567
|
+
function reaction(emoji, target) {
|
|
568
|
+
return { build: async () => asReaction({ emoji, target }) };
|
|
569
|
+
}
|
|
570
|
+
|
|
556
571
|
// src/utils/stream.ts
|
|
557
572
|
import { Repeater } from "@repeaterjs/repeater";
|
|
558
573
|
function stream(setup) {
|
|
@@ -688,6 +703,8 @@ export {
|
|
|
688
703
|
contact,
|
|
689
704
|
asCustom,
|
|
690
705
|
custom,
|
|
706
|
+
asReaction,
|
|
707
|
+
reaction,
|
|
691
708
|
stream,
|
|
692
709
|
mergeStreams,
|
|
693
710
|
SpectrumCloudError,
|
|
@@ -88,37 +88,117 @@ var warnUnsupported = (err, fallbackPlatform) => {
|
|
|
88
88
|
supportsAnsiColor() ? `${ANSI_YELLOW}${body}${ANSI_RESET}` : body
|
|
89
89
|
);
|
|
90
90
|
};
|
|
91
|
+
var providerMessageCoreKeys = /* @__PURE__ */ new Set([
|
|
92
|
+
"content",
|
|
93
|
+
"id",
|
|
94
|
+
"sender",
|
|
95
|
+
"space",
|
|
96
|
+
"timestamp"
|
|
97
|
+
]);
|
|
98
|
+
var extractExtras = (raw, definition) => {
|
|
99
|
+
const entries = Object.entries(raw).filter(
|
|
100
|
+
([key]) => !providerMessageCoreKeys.has(key)
|
|
101
|
+
);
|
|
102
|
+
const extra = Object.fromEntries(entries);
|
|
103
|
+
return definition.message?.schema ? definition.message.schema.parse(extra) : extra;
|
|
104
|
+
};
|
|
105
|
+
function wrapProviderMessage(raw, ctx) {
|
|
106
|
+
const wrappedContent = wrapNestedContent(raw.content, ctx);
|
|
107
|
+
return buildMessage({
|
|
108
|
+
id: raw.id,
|
|
109
|
+
content: wrappedContent,
|
|
110
|
+
sender: raw.sender,
|
|
111
|
+
timestamp: raw.timestamp ?? /* @__PURE__ */ new Date(),
|
|
112
|
+
extras: extractExtras(raw, ctx.definition),
|
|
113
|
+
spaceRef: ctx.spaceRef,
|
|
114
|
+
space: ctx.space,
|
|
115
|
+
definition: ctx.definition,
|
|
116
|
+
client: ctx.client,
|
|
117
|
+
config: ctx.config,
|
|
118
|
+
direction: "inbound"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
var wrapNestedContent = (content, ctx) => {
|
|
122
|
+
if (content.type === "reaction") {
|
|
123
|
+
const target = content.target;
|
|
124
|
+
if (isRawProviderRecord(target)) {
|
|
125
|
+
return {
|
|
126
|
+
...content,
|
|
127
|
+
target: wrapProviderMessage(target, ctx)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return content;
|
|
131
|
+
}
|
|
132
|
+
if (content.type === "group") {
|
|
133
|
+
const items = content.items.map((item) => {
|
|
134
|
+
const raw = item;
|
|
135
|
+
return isRawProviderRecord(raw) ? wrapProviderMessage(raw, ctx) : item;
|
|
136
|
+
});
|
|
137
|
+
return { ...content, items };
|
|
138
|
+
}
|
|
139
|
+
return content;
|
|
140
|
+
};
|
|
141
|
+
var isRawProviderRecord = (v) => {
|
|
142
|
+
if (typeof v !== "object" || v === null) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
const record = v;
|
|
146
|
+
return "id" in record && "content" in record && typeof record.react !== "function" && typeof record.reply !== "function";
|
|
147
|
+
};
|
|
91
148
|
function buildSpace(params) {
|
|
92
149
|
const { spaceRef, extras, typingCtx, definition, client, config } = params;
|
|
93
150
|
let space;
|
|
94
|
-
async function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
let sendResult;
|
|
99
|
-
try {
|
|
100
|
-
sendResult = await definition.actions.send({
|
|
101
|
-
...typingCtx,
|
|
102
|
-
content: item
|
|
103
|
-
});
|
|
104
|
-
} catch (err) {
|
|
105
|
-
if (err instanceof UnsupportedError) {
|
|
106
|
-
warnUnsupported(err, definition.name);
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
throw err;
|
|
151
|
+
async function dispatchReaction(item) {
|
|
152
|
+
try {
|
|
153
|
+
if (!definition.actions.reactToMessage) {
|
|
154
|
+
throw UnsupportedError.action("react", definition.name);
|
|
110
155
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
156
|
+
await definition.actions.reactToMessage({
|
|
157
|
+
space: spaceRef,
|
|
158
|
+
target: item.target,
|
|
159
|
+
reaction: item.emoji,
|
|
160
|
+
client,
|
|
161
|
+
config
|
|
162
|
+
});
|
|
163
|
+
} catch (err) {
|
|
164
|
+
if (err instanceof UnsupportedError) {
|
|
165
|
+
warnUnsupported(err, definition.name);
|
|
166
|
+
return;
|
|
115
167
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
168
|
+
throw err;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function dispatchSend(item) {
|
|
172
|
+
let sendResult;
|
|
173
|
+
try {
|
|
174
|
+
sendResult = await definition.actions.send({
|
|
175
|
+
...typingCtx,
|
|
176
|
+
content: item
|
|
177
|
+
});
|
|
178
|
+
} catch (err) {
|
|
179
|
+
if (err instanceof UnsupportedError) {
|
|
180
|
+
warnUnsupported(err, definition.name);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
if (!sendResult?.id) {
|
|
186
|
+
throw new Error(
|
|
187
|
+
`Platform "${definition.name}" send did not return a message id`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
const outboundContent = item.type === "group" && sendResult.groupMembers ? {
|
|
191
|
+
...item,
|
|
192
|
+
items: item.items.map((stub, idx) => {
|
|
193
|
+
const member = sendResult?.groupMembers?.[idx];
|
|
194
|
+
if (!member?.id) {
|
|
195
|
+
return stub;
|
|
196
|
+
}
|
|
197
|
+
return buildMessage({
|
|
198
|
+
id: member.id,
|
|
199
|
+
content: stub.content,
|
|
200
|
+
sender: member.sender,
|
|
201
|
+
timestamp: member.timestamp ?? /* @__PURE__ */ new Date(),
|
|
122
202
|
extras: {},
|
|
123
203
|
spaceRef,
|
|
124
204
|
space,
|
|
@@ -126,14 +206,75 @@ function buildSpace(params) {
|
|
|
126
206
|
client,
|
|
127
207
|
config,
|
|
128
208
|
direction: "outbound"
|
|
129
|
-
})
|
|
130
|
-
)
|
|
209
|
+
});
|
|
210
|
+
})
|
|
211
|
+
} : item;
|
|
212
|
+
return buildMessage({
|
|
213
|
+
id: sendResult.id,
|
|
214
|
+
content: outboundContent,
|
|
215
|
+
sender: sendResult.sender,
|
|
216
|
+
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
217
|
+
extras: {},
|
|
218
|
+
spaceRef,
|
|
219
|
+
space,
|
|
220
|
+
definition,
|
|
221
|
+
client,
|
|
222
|
+
config,
|
|
223
|
+
direction: "outbound"
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async function sendImpl(...content) {
|
|
227
|
+
const resolved = await resolveContents(content);
|
|
228
|
+
const results = [];
|
|
229
|
+
for (const item of resolved) {
|
|
230
|
+
if (item.type === "reaction") {
|
|
231
|
+
await dispatchReaction(item);
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const sent = await dispatchSend(item);
|
|
235
|
+
if (sent) {
|
|
236
|
+
results.push(sent);
|
|
237
|
+
}
|
|
131
238
|
}
|
|
132
239
|
if (content.length === 1) {
|
|
133
240
|
return results[0];
|
|
134
241
|
}
|
|
135
242
|
return results;
|
|
136
243
|
}
|
|
244
|
+
async function getMessageImpl(id) {
|
|
245
|
+
if (!definition.actions.getMessage) {
|
|
246
|
+
warnUnsupported(
|
|
247
|
+
UnsupportedError.action("getMessage", definition.name),
|
|
248
|
+
definition.name
|
|
249
|
+
);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
let raw;
|
|
253
|
+
try {
|
|
254
|
+
raw = await definition.actions.getMessage({
|
|
255
|
+
space: spaceRef,
|
|
256
|
+
messageId: id,
|
|
257
|
+
client,
|
|
258
|
+
config
|
|
259
|
+
});
|
|
260
|
+
} catch (err) {
|
|
261
|
+
if (err instanceof UnsupportedError) {
|
|
262
|
+
warnUnsupported(err, definition.name);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
throw err;
|
|
266
|
+
}
|
|
267
|
+
if (!raw) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
return wrapProviderMessage(raw, {
|
|
271
|
+
client,
|
|
272
|
+
config,
|
|
273
|
+
definition,
|
|
274
|
+
space,
|
|
275
|
+
spaceRef
|
|
276
|
+
});
|
|
277
|
+
}
|
|
137
278
|
space = {
|
|
138
279
|
...extras,
|
|
139
280
|
...spaceRef,
|
|
@@ -141,6 +282,7 @@ function buildSpace(params) {
|
|
|
141
282
|
edit: async (message, newContent) => {
|
|
142
283
|
await message.edit(newContent);
|
|
143
284
|
},
|
|
285
|
+
getMessage: getMessageImpl,
|
|
144
286
|
startTyping: async () => {
|
|
145
287
|
await definition.actions.startTyping?.(typingCtx);
|
|
146
288
|
},
|
|
@@ -161,6 +303,7 @@ function buildSpace(params) {
|
|
|
161
303
|
}
|
|
162
304
|
function buildMessage(params) {
|
|
163
305
|
const { definition, client, config, spaceRef, space } = params;
|
|
306
|
+
let self;
|
|
164
307
|
const react = async (reaction) => {
|
|
165
308
|
if (!definition.actions.reactToMessage) {
|
|
166
309
|
warnUnsupported(
|
|
@@ -169,13 +312,26 @@ function buildMessage(params) {
|
|
|
169
312
|
);
|
|
170
313
|
return;
|
|
171
314
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
315
|
+
if (!self) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
"react() called before message construction completed (internal bug)"
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
try {
|
|
321
|
+
await definition.actions.reactToMessage({
|
|
322
|
+
space: spaceRef,
|
|
323
|
+
target: self,
|
|
324
|
+
reaction,
|
|
325
|
+
client,
|
|
326
|
+
config
|
|
327
|
+
});
|
|
328
|
+
} catch (err) {
|
|
329
|
+
if (err instanceof UnsupportedError) {
|
|
330
|
+
warnUnsupported(err, definition.name);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
throw err;
|
|
334
|
+
}
|
|
179
335
|
};
|
|
180
336
|
async function reply(...content) {
|
|
181
337
|
if (!definition.actions.replyToMessage) {
|
|
@@ -232,7 +388,7 @@ function buildMessage(params) {
|
|
|
232
388
|
}
|
|
233
389
|
const senderWithPlatform = params.sender === void 0 ? void 0 : { ...params.sender, __platform: definition.name };
|
|
234
390
|
if (params.direction === "outbound") {
|
|
235
|
-
|
|
391
|
+
const outbound = {
|
|
236
392
|
...params.extras,
|
|
237
393
|
id: params.id,
|
|
238
394
|
content: params.content,
|
|
@@ -272,8 +428,10 @@ function buildMessage(params) {
|
|
|
272
428
|
space,
|
|
273
429
|
timestamp: params.timestamp
|
|
274
430
|
};
|
|
431
|
+
self = outbound;
|
|
432
|
+
return outbound;
|
|
275
433
|
}
|
|
276
|
-
|
|
434
|
+
const inbound = {
|
|
277
435
|
...params.extras,
|
|
278
436
|
id: params.id,
|
|
279
437
|
content: params.content,
|
|
@@ -285,6 +443,8 @@ function buildMessage(params) {
|
|
|
285
443
|
space,
|
|
286
444
|
timestamp: params.timestamp
|
|
287
445
|
};
|
|
446
|
+
self = inbound;
|
|
447
|
+
return inbound;
|
|
288
448
|
}
|
|
289
449
|
|
|
290
450
|
// src/platform/define.ts
|
|
@@ -471,7 +631,7 @@ export {
|
|
|
471
631
|
text,
|
|
472
632
|
resolveContents,
|
|
473
633
|
UnsupportedError,
|
|
634
|
+
wrapProviderMessage,
|
|
474
635
|
buildSpace,
|
|
475
|
-
buildMessage,
|
|
476
636
|
definePlatform
|
|
477
637
|
};
|