spectrum-ts 0.9.0 → 1.0.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-2Y5GBI6W.js +129 -0
- package/dist/chunk-7Q7KJKGL.js +117 -0
- package/dist/{chunk-6ZOLTQDN.js → chunk-LAGNM6I7.js} +39 -11
- package/dist/chunk-XMAI2AAN.js +1221 -0
- package/dist/index.d.ts +43 -7
- package/dist/index.js +49 -155
- package/dist/providers/imessage/index.d.ts +16 -7
- package/dist/providers/imessage/index.js +345 -60
- package/dist/providers/terminal/index.d.ts +109 -9
- package/dist/providers/terminal/index.js +813 -32
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +15 -10
- package/dist/{types-B8g0pvfg.d.ts → types-D5KhSXLy.d.ts} +27 -2
- package/package.json +1 -1
- package/dist/chunk-CZIWNTXP.js +0 -710
- package/dist/chunk-PLJI5FTO.js +0 -513
package/dist/chunk-PLJI5FTO.js
DELETED
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
// src/content/text.ts
|
|
2
|
-
import z from "zod";
|
|
3
|
-
var textSchema = z.object({
|
|
4
|
-
type: z.literal("text"),
|
|
5
|
-
text: z.string().nonempty()
|
|
6
|
-
});
|
|
7
|
-
var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
|
|
8
|
-
function text(text2) {
|
|
9
|
-
return {
|
|
10
|
-
build: async () => asText(text2)
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// src/content/resolve.ts
|
|
15
|
-
var resolveContents = (items) => Promise.all(
|
|
16
|
-
items.map((c) => typeof c === "string" ? text(c).build() : c.build())
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
// src/utils/errors.ts
|
|
20
|
-
var composeMessage = (opts) => {
|
|
21
|
-
const platform = opts.platform ?? "platform";
|
|
22
|
-
const subject = opts.kind === "content" ? `content type "${opts.contentType ?? "unknown"}"` : `action "${opts.action ?? "unknown"}"`;
|
|
23
|
-
const detail = opts.detail ? `: ${opts.detail}` : "";
|
|
24
|
-
return `${platform} does not support ${subject}${detail}`;
|
|
25
|
-
};
|
|
26
|
-
var UnsupportedError = class _UnsupportedError extends Error {
|
|
27
|
-
kind;
|
|
28
|
-
platform;
|
|
29
|
-
contentType;
|
|
30
|
-
action;
|
|
31
|
-
detail;
|
|
32
|
-
constructor(opts) {
|
|
33
|
-
super(composeMessage(opts));
|
|
34
|
-
this.name = "UnsupportedError";
|
|
35
|
-
this.kind = opts.kind;
|
|
36
|
-
this.platform = opts.platform;
|
|
37
|
-
this.contentType = opts.contentType;
|
|
38
|
-
this.action = opts.action;
|
|
39
|
-
this.detail = opts.detail;
|
|
40
|
-
}
|
|
41
|
-
static content(contentType, platform, detail) {
|
|
42
|
-
return new _UnsupportedError({
|
|
43
|
-
kind: "content",
|
|
44
|
-
contentType,
|
|
45
|
-
platform,
|
|
46
|
-
detail
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
static action(action, platform, detail) {
|
|
50
|
-
return new _UnsupportedError({ kind: "action", action, platform, detail });
|
|
51
|
-
}
|
|
52
|
-
withPlatform(platform) {
|
|
53
|
-
if (this.platform) {
|
|
54
|
-
return this;
|
|
55
|
-
}
|
|
56
|
-
return new _UnsupportedError({
|
|
57
|
-
kind: this.kind,
|
|
58
|
-
platform,
|
|
59
|
-
contentType: this.contentType,
|
|
60
|
-
action: this.action,
|
|
61
|
-
detail: this.detail
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// src/platform/build.ts
|
|
67
|
-
var ANSI_YELLOW = "\x1B[33m";
|
|
68
|
-
var ANSI_RESET = "\x1B[0m";
|
|
69
|
-
var supportsAnsiColor = () => {
|
|
70
|
-
if (typeof process === "undefined") {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (process.env.NO_COLOR) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
const force = process.env.FORCE_COLOR;
|
|
77
|
-
if (force !== void 0) {
|
|
78
|
-
return force !== "" && force !== "0" && force !== "false";
|
|
79
|
-
}
|
|
80
|
-
return Boolean(process.stderr?.isTTY);
|
|
81
|
-
};
|
|
82
|
-
var warnUnsupported = (err, fallbackPlatform) => {
|
|
83
|
-
const platform = err.platform ?? fallbackPlatform;
|
|
84
|
-
const subject = err.kind === "content" ? `content type "${err.contentType ?? "unknown"}"` : `action "${err.action ?? "unknown"}"`;
|
|
85
|
-
const detail = err.detail ? `: ${err.detail}` : "";
|
|
86
|
-
const body = `[spectrum-ts] ${platform} does not support ${subject}${detail}; skipping.`;
|
|
87
|
-
console.warn(
|
|
88
|
-
supportsAnsiColor() ? `${ANSI_YELLOW}${body}${ANSI_RESET}` : body
|
|
89
|
-
);
|
|
90
|
-
};
|
|
91
|
-
function buildSpace(params) {
|
|
92
|
-
const { spaceRef, extras, typingCtx, definition, client, config } = params;
|
|
93
|
-
let space;
|
|
94
|
-
async function dispatchReaction(item) {
|
|
95
|
-
try {
|
|
96
|
-
if (!definition.actions.reactToMessage) {
|
|
97
|
-
throw UnsupportedError.action("react", definition.name);
|
|
98
|
-
}
|
|
99
|
-
await definition.actions.reactToMessage({
|
|
100
|
-
space: spaceRef,
|
|
101
|
-
messageId: item.target,
|
|
102
|
-
reaction: item.emoji,
|
|
103
|
-
client,
|
|
104
|
-
config
|
|
105
|
-
});
|
|
106
|
-
} catch (err) {
|
|
107
|
-
if (err instanceof UnsupportedError) {
|
|
108
|
-
warnUnsupported(err, definition.name);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
throw err;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
async function dispatchSend(item) {
|
|
115
|
-
let sendResult;
|
|
116
|
-
try {
|
|
117
|
-
sendResult = await definition.actions.send({
|
|
118
|
-
...typingCtx,
|
|
119
|
-
content: item
|
|
120
|
-
});
|
|
121
|
-
} catch (err) {
|
|
122
|
-
if (err instanceof UnsupportedError) {
|
|
123
|
-
warnUnsupported(err, definition.name);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
if (!sendResult?.id) {
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Platform "${definition.name}" send did not return a message id`
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
return buildMessage({
|
|
134
|
-
id: sendResult.id,
|
|
135
|
-
content: item,
|
|
136
|
-
sender: sendResult.sender,
|
|
137
|
-
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
138
|
-
extras: {},
|
|
139
|
-
spaceRef,
|
|
140
|
-
space,
|
|
141
|
-
definition,
|
|
142
|
-
client,
|
|
143
|
-
config,
|
|
144
|
-
direction: "outbound"
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
async function sendImpl(...content) {
|
|
148
|
-
const resolved = await resolveContents(content);
|
|
149
|
-
const results = [];
|
|
150
|
-
for (const item of resolved) {
|
|
151
|
-
if (item.type === "reaction") {
|
|
152
|
-
await dispatchReaction(item);
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
const sent = await dispatchSend(item);
|
|
156
|
-
if (sent) {
|
|
157
|
-
results.push(sent);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (content.length === 1) {
|
|
161
|
-
return results[0];
|
|
162
|
-
}
|
|
163
|
-
return results;
|
|
164
|
-
}
|
|
165
|
-
space = {
|
|
166
|
-
...extras,
|
|
167
|
-
...spaceRef,
|
|
168
|
-
send: sendImpl,
|
|
169
|
-
edit: async (message, newContent) => {
|
|
170
|
-
await message.edit(newContent);
|
|
171
|
-
},
|
|
172
|
-
startTyping: async () => {
|
|
173
|
-
await definition.actions.startTyping?.(typingCtx);
|
|
174
|
-
},
|
|
175
|
-
stopTyping: async () => {
|
|
176
|
-
await definition.actions.stopTyping?.(typingCtx);
|
|
177
|
-
},
|
|
178
|
-
responding: async (fn) => {
|
|
179
|
-
await definition.actions.startTyping?.(typingCtx);
|
|
180
|
-
try {
|
|
181
|
-
return await fn();
|
|
182
|
-
} finally {
|
|
183
|
-
await definition.actions.stopTyping?.(typingCtx).catch(() => {
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
return space;
|
|
189
|
-
}
|
|
190
|
-
function buildMessage(params) {
|
|
191
|
-
const { definition, client, config, spaceRef, space } = params;
|
|
192
|
-
const react = async (reaction) => {
|
|
193
|
-
if (!definition.actions.reactToMessage) {
|
|
194
|
-
warnUnsupported(
|
|
195
|
-
UnsupportedError.action("react", definition.name),
|
|
196
|
-
definition.name
|
|
197
|
-
);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
try {
|
|
201
|
-
await definition.actions.reactToMessage({
|
|
202
|
-
space: spaceRef,
|
|
203
|
-
messageId: params.id,
|
|
204
|
-
reaction,
|
|
205
|
-
client,
|
|
206
|
-
config
|
|
207
|
-
});
|
|
208
|
-
} catch (err) {
|
|
209
|
-
if (err instanceof UnsupportedError) {
|
|
210
|
-
warnUnsupported(err, definition.name);
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
throw err;
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
async function reply(...content) {
|
|
217
|
-
if (!definition.actions.replyToMessage) {
|
|
218
|
-
warnUnsupported(
|
|
219
|
-
UnsupportedError.action("reply", definition.name),
|
|
220
|
-
definition.name
|
|
221
|
-
);
|
|
222
|
-
return content.length === 1 ? void 0 : [];
|
|
223
|
-
}
|
|
224
|
-
const resolved = await resolveContents(content);
|
|
225
|
-
const results = [];
|
|
226
|
-
for (const item of resolved) {
|
|
227
|
-
let sendResult;
|
|
228
|
-
try {
|
|
229
|
-
sendResult = await definition.actions.replyToMessage({
|
|
230
|
-
space: spaceRef,
|
|
231
|
-
messageId: params.id,
|
|
232
|
-
content: item,
|
|
233
|
-
client,
|
|
234
|
-
config
|
|
235
|
-
});
|
|
236
|
-
} catch (err) {
|
|
237
|
-
if (err instanceof UnsupportedError) {
|
|
238
|
-
warnUnsupported(err, definition.name);
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
throw err;
|
|
242
|
-
}
|
|
243
|
-
if (!sendResult?.id) {
|
|
244
|
-
throw new Error(
|
|
245
|
-
`Platform "${definition.name}" reply did not return a message id`
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
results.push(
|
|
249
|
-
buildMessage({
|
|
250
|
-
id: sendResult.id,
|
|
251
|
-
content: item,
|
|
252
|
-
sender: sendResult.sender,
|
|
253
|
-
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
254
|
-
extras: {},
|
|
255
|
-
spaceRef,
|
|
256
|
-
space,
|
|
257
|
-
definition,
|
|
258
|
-
client,
|
|
259
|
-
config,
|
|
260
|
-
direction: "outbound"
|
|
261
|
-
})
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
if (content.length === 1) {
|
|
265
|
-
return results[0];
|
|
266
|
-
}
|
|
267
|
-
return results;
|
|
268
|
-
}
|
|
269
|
-
const senderWithPlatform = params.sender === void 0 ? void 0 : { ...params.sender, __platform: definition.name };
|
|
270
|
-
if (params.direction === "outbound") {
|
|
271
|
-
return {
|
|
272
|
-
...params.extras,
|
|
273
|
-
id: params.id,
|
|
274
|
-
content: params.content,
|
|
275
|
-
direction: "outbound",
|
|
276
|
-
platform: definition.name,
|
|
277
|
-
react,
|
|
278
|
-
reply,
|
|
279
|
-
edit: async (newContent) => {
|
|
280
|
-
if (!definition.actions.editMessage) {
|
|
281
|
-
warnUnsupported(
|
|
282
|
-
UnsupportedError.action("edit", definition.name),
|
|
283
|
-
definition.name
|
|
284
|
-
);
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
const [resolved] = await resolveContents([newContent]);
|
|
288
|
-
if (!resolved) {
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
try {
|
|
292
|
-
await definition.actions.editMessage({
|
|
293
|
-
space: spaceRef,
|
|
294
|
-
messageId: params.id,
|
|
295
|
-
content: resolved,
|
|
296
|
-
client,
|
|
297
|
-
config
|
|
298
|
-
});
|
|
299
|
-
} catch (err) {
|
|
300
|
-
if (err instanceof UnsupportedError) {
|
|
301
|
-
warnUnsupported(err, definition.name);
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
throw err;
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
sender: senderWithPlatform,
|
|
308
|
-
space,
|
|
309
|
-
timestamp: params.timestamp
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
return {
|
|
313
|
-
...params.extras,
|
|
314
|
-
id: params.id,
|
|
315
|
-
content: params.content,
|
|
316
|
-
direction: "inbound",
|
|
317
|
-
platform: definition.name,
|
|
318
|
-
react,
|
|
319
|
-
reply,
|
|
320
|
-
sender: senderWithPlatform,
|
|
321
|
-
space,
|
|
322
|
-
timestamp: params.timestamp
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// src/platform/define.ts
|
|
327
|
-
function createPlatformInstance(def, runtime) {
|
|
328
|
-
const isPlatformUser = (value) => {
|
|
329
|
-
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
330
|
-
};
|
|
331
|
-
const resolveUserID = async (userID) => {
|
|
332
|
-
const resolved = await def.user.resolve({
|
|
333
|
-
input: { userID },
|
|
334
|
-
client: runtime.client,
|
|
335
|
-
config: runtime.config
|
|
336
|
-
});
|
|
337
|
-
return {
|
|
338
|
-
...resolved,
|
|
339
|
-
__platform: def.name
|
|
340
|
-
};
|
|
341
|
-
};
|
|
342
|
-
const resolveStringUsers = async (args) => {
|
|
343
|
-
const convertArg = async (arg) => {
|
|
344
|
-
if (typeof arg === "string") {
|
|
345
|
-
return await resolveUserID(arg);
|
|
346
|
-
}
|
|
347
|
-
if (Array.isArray(arg)) {
|
|
348
|
-
return await Promise.all(arg.map(convertArg));
|
|
349
|
-
}
|
|
350
|
-
return arg;
|
|
351
|
-
};
|
|
352
|
-
return await Promise.all(args.map(convertArg));
|
|
353
|
-
};
|
|
354
|
-
const normalizeSpaceArgs = (args) => {
|
|
355
|
-
if (args.length === 0) {
|
|
356
|
-
return { users: [], params: void 0 };
|
|
357
|
-
}
|
|
358
|
-
const [first, ...rest] = args;
|
|
359
|
-
if (Array.isArray(first)) {
|
|
360
|
-
return {
|
|
361
|
-
users: first,
|
|
362
|
-
params: rest[0]
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
if (!isPlatformUser(first)) {
|
|
366
|
-
return {
|
|
367
|
-
users: [],
|
|
368
|
-
params: first
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
const last = args.at(-1);
|
|
372
|
-
if (last !== void 0 && !isPlatformUser(last)) {
|
|
373
|
-
return {
|
|
374
|
-
users: args.slice(0, -1),
|
|
375
|
-
params: last
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
return {
|
|
379
|
-
users: args,
|
|
380
|
-
params: void 0
|
|
381
|
-
};
|
|
382
|
-
};
|
|
383
|
-
const base = {
|
|
384
|
-
async user(userID) {
|
|
385
|
-
const resolved = await def.user.resolve({
|
|
386
|
-
input: { userID },
|
|
387
|
-
client: runtime.client,
|
|
388
|
-
config: runtime.config
|
|
389
|
-
});
|
|
390
|
-
return {
|
|
391
|
-
...resolved,
|
|
392
|
-
__platform: def.name
|
|
393
|
-
};
|
|
394
|
-
},
|
|
395
|
-
async space(...args) {
|
|
396
|
-
const convertedArgs = await resolveStringUsers(args);
|
|
397
|
-
const { users, params } = normalizeSpaceArgs(convertedArgs);
|
|
398
|
-
let parsedParams = params;
|
|
399
|
-
if (params !== void 0 && def.space.params) {
|
|
400
|
-
parsedParams = def.space.params.parse(params);
|
|
401
|
-
}
|
|
402
|
-
const resolved = await def.space.resolve({
|
|
403
|
-
input: { users, params: parsedParams },
|
|
404
|
-
client: runtime.client,
|
|
405
|
-
config: runtime.config
|
|
406
|
-
});
|
|
407
|
-
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
408
|
-
const spaceRef = {
|
|
409
|
-
id: parsedSpace.id,
|
|
410
|
-
__platform: def.name
|
|
411
|
-
};
|
|
412
|
-
const typingCtx = {
|
|
413
|
-
space: spaceRef,
|
|
414
|
-
client: runtime.client,
|
|
415
|
-
config: runtime.config
|
|
416
|
-
};
|
|
417
|
-
return buildSpace({
|
|
418
|
-
spaceRef,
|
|
419
|
-
extras: parsedSpace,
|
|
420
|
-
typingCtx,
|
|
421
|
-
definition: def,
|
|
422
|
-
client: runtime.client,
|
|
423
|
-
config: runtime.config
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
};
|
|
427
|
-
const eventProperties = {};
|
|
428
|
-
for (const eventName of Object.keys(def.events)) {
|
|
429
|
-
if (eventName === "messages") {
|
|
430
|
-
continue;
|
|
431
|
-
}
|
|
432
|
-
const producer = def.events[eventName];
|
|
433
|
-
if (producer) {
|
|
434
|
-
eventProperties[eventName] = producer({
|
|
435
|
-
client: runtime.client,
|
|
436
|
-
config: runtime.config
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
return Object.assign(base, eventProperties);
|
|
441
|
-
}
|
|
442
|
-
function definePlatform(name, def) {
|
|
443
|
-
const fullDef = { name, ...def };
|
|
444
|
-
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
445
|
-
const narrowSpectrum = (spectrum) => {
|
|
446
|
-
const cached = platformCache.get(spectrum);
|
|
447
|
-
if (cached) {
|
|
448
|
-
return cached;
|
|
449
|
-
}
|
|
450
|
-
const runtime = spectrum.__internal.platforms.get(name);
|
|
451
|
-
if (!runtime) {
|
|
452
|
-
throw new Error(`Platform "${name}" is not registered`);
|
|
453
|
-
}
|
|
454
|
-
const instance = createPlatformInstance(
|
|
455
|
-
fullDef,
|
|
456
|
-
runtime
|
|
457
|
-
);
|
|
458
|
-
platformCache.set(spectrum, instance);
|
|
459
|
-
return instance;
|
|
460
|
-
};
|
|
461
|
-
const narrowSpace = (input) => {
|
|
462
|
-
if (input.__platform !== name) {
|
|
463
|
-
throw new Error(
|
|
464
|
-
`Expected space from "${name}", got "${input.__platform}"`
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
return input;
|
|
468
|
-
};
|
|
469
|
-
const narrowMessage = (input) => {
|
|
470
|
-
if (input.platform !== name) {
|
|
471
|
-
throw new Error(
|
|
472
|
-
`Expected message from "${name}", got "${input.platform}"`
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
return input;
|
|
476
|
-
};
|
|
477
|
-
const narrower = ((input) => {
|
|
478
|
-
if ("__providers" in input && "__internal" in input) {
|
|
479
|
-
return narrowSpectrum(input);
|
|
480
|
-
}
|
|
481
|
-
if ("__platform" in input && "send" in input) {
|
|
482
|
-
return narrowSpace(input);
|
|
483
|
-
}
|
|
484
|
-
if ("platform" in input && "sender" in input && "space" in input) {
|
|
485
|
-
return narrowMessage(input);
|
|
486
|
-
}
|
|
487
|
-
throw new Error("Invalid input to platform narrowing function");
|
|
488
|
-
});
|
|
489
|
-
narrower.config = (config) => {
|
|
490
|
-
const resolvedConfig = config ?? {};
|
|
491
|
-
return {
|
|
492
|
-
__tag: "PlatformProviderConfig",
|
|
493
|
-
__def: void 0,
|
|
494
|
-
__name: name,
|
|
495
|
-
config: resolvedConfig,
|
|
496
|
-
__definition: fullDef
|
|
497
|
-
};
|
|
498
|
-
};
|
|
499
|
-
if (def.static) {
|
|
500
|
-
Object.assign(narrower, def.static);
|
|
501
|
-
}
|
|
502
|
-
return narrower;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
export {
|
|
506
|
-
asText,
|
|
507
|
-
text,
|
|
508
|
-
resolveContents,
|
|
509
|
-
UnsupportedError,
|
|
510
|
-
buildSpace,
|
|
511
|
-
buildMessage,
|
|
512
|
-
definePlatform
|
|
513
|
-
};
|