spectrum-ts 0.5.0 → 0.6.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-XZTTLPHE.js +341 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +28 -66
- package/dist/providers/imessage/index.d.ts +1 -1
- package/dist/providers/imessage/index.js +97 -48
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/terminal/index.js +7 -3
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +57 -46
- package/dist/{types-CfiD_00g.d.ts → types-DZMHfgYQ.d.ts} +33 -8
- package/package.json +1 -1
- package/dist/chunk-XEEDIGVK.js +0 -199
|
@@ -0,0 +1,341 @@
|
|
|
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/platform/build.ts
|
|
20
|
+
function buildSpace(params) {
|
|
21
|
+
const { spaceRef, extras, typingCtx, definition, client, config } = params;
|
|
22
|
+
let space;
|
|
23
|
+
async function sendImpl(...content) {
|
|
24
|
+
const resolved = await resolveContents(content);
|
|
25
|
+
const results = [];
|
|
26
|
+
for (const item of resolved) {
|
|
27
|
+
const sendResult = await definition.actions.send({
|
|
28
|
+
...typingCtx,
|
|
29
|
+
content: item
|
|
30
|
+
});
|
|
31
|
+
if (!sendResult?.id) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Platform "${definition.name}" send did not return a message id`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
results.push(
|
|
37
|
+
buildMessage({
|
|
38
|
+
id: sendResult.id,
|
|
39
|
+
content: item,
|
|
40
|
+
sender: sendResult.sender,
|
|
41
|
+
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
42
|
+
extras: {},
|
|
43
|
+
spaceRef,
|
|
44
|
+
space,
|
|
45
|
+
definition,
|
|
46
|
+
client,
|
|
47
|
+
config,
|
|
48
|
+
direction: "outbound"
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return content.length === 1 && results[0] ? results[0] : results;
|
|
53
|
+
}
|
|
54
|
+
space = {
|
|
55
|
+
...extras,
|
|
56
|
+
...spaceRef,
|
|
57
|
+
send: sendImpl,
|
|
58
|
+
edit: async (message, newContent) => {
|
|
59
|
+
await message.edit(newContent);
|
|
60
|
+
},
|
|
61
|
+
startTyping: async () => {
|
|
62
|
+
await definition.actions.startTyping?.(typingCtx);
|
|
63
|
+
},
|
|
64
|
+
stopTyping: async () => {
|
|
65
|
+
await definition.actions.stopTyping?.(typingCtx);
|
|
66
|
+
},
|
|
67
|
+
responding: async (fn) => {
|
|
68
|
+
await definition.actions.startTyping?.(typingCtx);
|
|
69
|
+
try {
|
|
70
|
+
return await fn();
|
|
71
|
+
} finally {
|
|
72
|
+
await definition.actions.stopTyping?.(typingCtx).catch(() => {
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
return space;
|
|
78
|
+
}
|
|
79
|
+
function buildMessage(params) {
|
|
80
|
+
const { definition, client, config, spaceRef, space } = params;
|
|
81
|
+
const react = async (reaction) => {
|
|
82
|
+
if (!definition.actions.reactToMessage) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
await definition.actions.reactToMessage({
|
|
86
|
+
space: spaceRef,
|
|
87
|
+
messageId: params.id,
|
|
88
|
+
reaction,
|
|
89
|
+
client,
|
|
90
|
+
config
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
async function reply(...content) {
|
|
94
|
+
if (!definition.actions.replyToMessage) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Platform "${definition.name}" does not support replying to messages`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const resolved = await resolveContents(content);
|
|
100
|
+
const results = [];
|
|
101
|
+
for (const item of resolved) {
|
|
102
|
+
const sendResult = await definition.actions.replyToMessage({
|
|
103
|
+
space: spaceRef,
|
|
104
|
+
messageId: params.id,
|
|
105
|
+
content: item,
|
|
106
|
+
client,
|
|
107
|
+
config
|
|
108
|
+
});
|
|
109
|
+
if (!sendResult?.id) {
|
|
110
|
+
throw new Error(
|
|
111
|
+
`Platform "${definition.name}" reply did not return a message id`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
results.push(
|
|
115
|
+
buildMessage({
|
|
116
|
+
id: sendResult.id,
|
|
117
|
+
content: item,
|
|
118
|
+
sender: sendResult.sender,
|
|
119
|
+
timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
|
|
120
|
+
extras: {},
|
|
121
|
+
spaceRef,
|
|
122
|
+
space,
|
|
123
|
+
definition,
|
|
124
|
+
client,
|
|
125
|
+
config,
|
|
126
|
+
direction: "outbound"
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
return content.length === 1 && results[0] ? results[0] : results;
|
|
131
|
+
}
|
|
132
|
+
const senderWithPlatform = params.sender === void 0 ? void 0 : { ...params.sender, __platform: definition.name };
|
|
133
|
+
if (params.direction === "outbound") {
|
|
134
|
+
return {
|
|
135
|
+
...params.extras,
|
|
136
|
+
id: params.id,
|
|
137
|
+
content: params.content,
|
|
138
|
+
direction: "outbound",
|
|
139
|
+
platform: definition.name,
|
|
140
|
+
react,
|
|
141
|
+
reply,
|
|
142
|
+
edit: async (newContent) => {
|
|
143
|
+
if (!definition.actions.editMessage) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
`Platform "${definition.name}" does not support editing messages`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
const [resolved] = await resolveContents([newContent]);
|
|
149
|
+
if (!resolved) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
await definition.actions.editMessage({
|
|
153
|
+
space: spaceRef,
|
|
154
|
+
messageId: params.id,
|
|
155
|
+
content: resolved,
|
|
156
|
+
client,
|
|
157
|
+
config
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
sender: senderWithPlatform,
|
|
161
|
+
space,
|
|
162
|
+
timestamp: params.timestamp
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
...params.extras,
|
|
167
|
+
id: params.id,
|
|
168
|
+
content: params.content,
|
|
169
|
+
direction: "inbound",
|
|
170
|
+
platform: definition.name,
|
|
171
|
+
react,
|
|
172
|
+
reply,
|
|
173
|
+
sender: senderWithPlatform,
|
|
174
|
+
space,
|
|
175
|
+
timestamp: params.timestamp
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/platform/define.ts
|
|
180
|
+
function createPlatformInstance(def, runtime) {
|
|
181
|
+
const isPlatformUser = (value) => {
|
|
182
|
+
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
183
|
+
};
|
|
184
|
+
const normalizeSpaceArgs = (args) => {
|
|
185
|
+
if (args.length === 0) {
|
|
186
|
+
return { users: [], params: void 0 };
|
|
187
|
+
}
|
|
188
|
+
const [first, ...rest] = args;
|
|
189
|
+
if (Array.isArray(first)) {
|
|
190
|
+
return {
|
|
191
|
+
users: first,
|
|
192
|
+
params: rest[0]
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (!isPlatformUser(first)) {
|
|
196
|
+
return {
|
|
197
|
+
users: [],
|
|
198
|
+
params: first
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const last = args.at(-1);
|
|
202
|
+
if (last !== void 0 && !isPlatformUser(last)) {
|
|
203
|
+
return {
|
|
204
|
+
users: args.slice(0, -1),
|
|
205
|
+
params: last
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
users: args,
|
|
210
|
+
params: void 0
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
const base = {
|
|
214
|
+
async user(userID) {
|
|
215
|
+
const resolved = await def.user.resolve({
|
|
216
|
+
input: { userID },
|
|
217
|
+
client: runtime.client,
|
|
218
|
+
config: runtime.config
|
|
219
|
+
});
|
|
220
|
+
return {
|
|
221
|
+
...resolved,
|
|
222
|
+
__platform: def.name
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
async space(...args) {
|
|
226
|
+
const { users, params } = normalizeSpaceArgs(args);
|
|
227
|
+
let parsedParams = params;
|
|
228
|
+
if (params !== void 0 && def.space.params) {
|
|
229
|
+
parsedParams = def.space.params.parse(params);
|
|
230
|
+
}
|
|
231
|
+
const resolved = await def.space.resolve({
|
|
232
|
+
input: { users, params: parsedParams },
|
|
233
|
+
client: runtime.client,
|
|
234
|
+
config: runtime.config
|
|
235
|
+
});
|
|
236
|
+
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
237
|
+
const spaceRef = {
|
|
238
|
+
id: parsedSpace.id,
|
|
239
|
+
__platform: def.name
|
|
240
|
+
};
|
|
241
|
+
const typingCtx = {
|
|
242
|
+
space: spaceRef,
|
|
243
|
+
client: runtime.client,
|
|
244
|
+
config: runtime.config
|
|
245
|
+
};
|
|
246
|
+
return buildSpace({
|
|
247
|
+
spaceRef,
|
|
248
|
+
extras: parsedSpace,
|
|
249
|
+
typingCtx,
|
|
250
|
+
definition: def,
|
|
251
|
+
client: runtime.client,
|
|
252
|
+
config: runtime.config
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
const eventProperties = {};
|
|
257
|
+
for (const eventName of Object.keys(def.events)) {
|
|
258
|
+
if (eventName === "messages") {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const producer = def.events[eventName];
|
|
262
|
+
if (producer) {
|
|
263
|
+
eventProperties[eventName] = producer({
|
|
264
|
+
client: runtime.client,
|
|
265
|
+
config: runtime.config
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return Object.assign(base, eventProperties);
|
|
270
|
+
}
|
|
271
|
+
function definePlatform(name, def) {
|
|
272
|
+
const fullDef = { name, ...def };
|
|
273
|
+
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
274
|
+
const narrowSpectrum = (spectrum) => {
|
|
275
|
+
const cached = platformCache.get(spectrum);
|
|
276
|
+
if (cached) {
|
|
277
|
+
return cached;
|
|
278
|
+
}
|
|
279
|
+
const runtime = spectrum.__internal.platforms.get(name);
|
|
280
|
+
if (!runtime) {
|
|
281
|
+
throw new Error(`Platform "${name}" is not registered`);
|
|
282
|
+
}
|
|
283
|
+
const instance = createPlatformInstance(
|
|
284
|
+
fullDef,
|
|
285
|
+
runtime
|
|
286
|
+
);
|
|
287
|
+
platformCache.set(spectrum, instance);
|
|
288
|
+
return instance;
|
|
289
|
+
};
|
|
290
|
+
const narrowSpace = (input) => {
|
|
291
|
+
if (input.__platform !== name) {
|
|
292
|
+
throw new Error(
|
|
293
|
+
`Expected space from "${name}", got "${input.__platform}"`
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
return input;
|
|
297
|
+
};
|
|
298
|
+
const narrowMessage = (input) => {
|
|
299
|
+
if (input.platform !== name) {
|
|
300
|
+
throw new Error(
|
|
301
|
+
`Expected message from "${name}", got "${input.platform}"`
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
return input;
|
|
305
|
+
};
|
|
306
|
+
const narrower = ((input) => {
|
|
307
|
+
if ("__providers" in input && "__internal" in input) {
|
|
308
|
+
return narrowSpectrum(input);
|
|
309
|
+
}
|
|
310
|
+
if ("__platform" in input && "send" in input) {
|
|
311
|
+
return narrowSpace(input);
|
|
312
|
+
}
|
|
313
|
+
if ("platform" in input && "sender" in input && "space" in input) {
|
|
314
|
+
return narrowMessage(input);
|
|
315
|
+
}
|
|
316
|
+
throw new Error("Invalid input to platform narrowing function");
|
|
317
|
+
});
|
|
318
|
+
narrower.config = (config) => {
|
|
319
|
+
const resolvedConfig = config ?? {};
|
|
320
|
+
return {
|
|
321
|
+
__tag: "PlatformProviderConfig",
|
|
322
|
+
__def: void 0,
|
|
323
|
+
__name: name,
|
|
324
|
+
config: resolvedConfig,
|
|
325
|
+
__definition: fullDef
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
if (def.static) {
|
|
329
|
+
Object.assign(narrower, def.static);
|
|
330
|
+
}
|
|
331
|
+
return narrower;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export {
|
|
335
|
+
asText,
|
|
336
|
+
text,
|
|
337
|
+
resolveContents,
|
|
338
|
+
buildSpace,
|
|
339
|
+
buildMessage,
|
|
340
|
+
definePlatform
|
|
341
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ContentBuilder, U as User, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space,
|
|
2
|
-
export { A as AnyPlatformDef, E as EventProducer, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage } from './types-
|
|
1
|
+
import { C as ContentBuilder, U as User, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, I as InboundMessage, O as OutboundMessage } from './types-DZMHfgYQ.js';
|
|
2
|
+
export { A as AnyPlatformDef, E as EventProducer, M as Message, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage } from './types-DZMHfgYQ.js';
|
|
3
3
|
import vCard from 'vcf';
|
|
4
4
|
import z__default from 'zod';
|
|
5
5
|
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-DGy4geUK.js';
|
|
@@ -161,9 +161,11 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
|
|
|
161
161
|
}): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events>> & Readonly<_Static>;
|
|
162
162
|
|
|
163
163
|
type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
|
|
164
|
-
readonly messages: AsyncIterable<[Space,
|
|
164
|
+
readonly messages: AsyncIterable<[Space, InboundMessage]>;
|
|
165
165
|
stop(): Promise<void>;
|
|
166
|
-
send(space: Space,
|
|
166
|
+
send(space: Space, content: ContentInput): Promise<OutboundMessage>;
|
|
167
|
+
send(space: Space, ...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage[]>;
|
|
168
|
+
edit(message: OutboundMessage, newContent: ContentInput): Promise<void>;
|
|
167
169
|
responding<T>(space: Space, fn: () => T | Promise<T>): Promise<T>;
|
|
168
170
|
};
|
|
169
171
|
declare function Spectrum<const Providers extends PlatformProviderConfig[]>(options: {
|
|
@@ -216,4 +218,4 @@ declare const cloud: {
|
|
|
216
218
|
declare const fromVCard: (vcf: string) => ContactInput;
|
|
217
219
|
declare const toVCard: (contact: Contact) => Promise<string>;
|
|
218
220
|
|
|
219
|
-
export { type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type ImessageInfoData,
|
|
221
|
+
export { type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type ImessageInfoData, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, User, type Voice, attachment, cloud, contact, custom, definePlatform, fromVCard, resolveContents, text, toVCard, voice };
|
package/dist/index.js
CHANGED
|
@@ -15,10 +15,12 @@ import {
|
|
|
15
15
|
toVCard
|
|
16
16
|
} from "./chunk-UZWRB3FZ.js";
|
|
17
17
|
import {
|
|
18
|
+
buildMessage,
|
|
19
|
+
buildSpace,
|
|
18
20
|
definePlatform,
|
|
19
21
|
resolveContents,
|
|
20
22
|
text
|
|
21
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-XZTTLPHE.js";
|
|
22
24
|
|
|
23
25
|
// src/content/voice.ts
|
|
24
26
|
import { createReadStream } from "fs";
|
|
@@ -207,72 +209,27 @@ async function Spectrum(options) {
|
|
|
207
209
|
__platform: definition.name
|
|
208
210
|
};
|
|
209
211
|
const typingCtx = { space: spaceRef, client, config };
|
|
210
|
-
const space = {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
startTyping: async () => {
|
|
222
|
-
await definition.actions.startTyping?.(typingCtx);
|
|
223
|
-
},
|
|
224
|
-
stopTyping: async () => {
|
|
225
|
-
await definition.actions.stopTyping?.(typingCtx);
|
|
226
|
-
},
|
|
227
|
-
responding: async (fn) => {
|
|
228
|
-
await definition.actions.startTyping?.(typingCtx);
|
|
229
|
-
try {
|
|
230
|
-
return await fn();
|
|
231
|
-
} finally {
|
|
232
|
-
await definition.actions.stopTyping?.(typingCtx).catch(() => {
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
};
|
|
237
|
-
const normalizedMessage = {
|
|
238
|
-
...parsedExtra,
|
|
212
|
+
const space = buildSpace({
|
|
213
|
+
spaceRef,
|
|
214
|
+
extras: {},
|
|
215
|
+
typingCtx,
|
|
216
|
+
definition,
|
|
217
|
+
client,
|
|
218
|
+
config
|
|
219
|
+
});
|
|
220
|
+
const normalizedMessage = buildMessage({
|
|
239
221
|
id: msg.id,
|
|
240
222
|
content: msg.content,
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
await definition.actions.reactToMessage({
|
|
247
|
-
space: spaceRef,
|
|
248
|
-
messageId: msg.id,
|
|
249
|
-
reaction,
|
|
250
|
-
client,
|
|
251
|
-
config
|
|
252
|
-
});
|
|
253
|
-
},
|
|
254
|
-
reply: async (...content) => {
|
|
255
|
-
if (!definition.actions.replyToMessage) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
const resolved = await resolveContents(content);
|
|
259
|
-
for (const item of resolved) {
|
|
260
|
-
await definition.actions.replyToMessage({
|
|
261
|
-
space: spaceRef,
|
|
262
|
-
messageId: msg.id,
|
|
263
|
-
content: item,
|
|
264
|
-
client,
|
|
265
|
-
config
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
},
|
|
269
|
-
sender: {
|
|
270
|
-
...msg.sender,
|
|
271
|
-
__platform: definition.name
|
|
272
|
-
},
|
|
223
|
+
sender: msg.sender,
|
|
224
|
+
timestamp: msg.timestamp ?? /* @__PURE__ */ new Date(),
|
|
225
|
+
extras: parsedExtra,
|
|
226
|
+
spaceRef,
|
|
273
227
|
space,
|
|
274
|
-
|
|
275
|
-
|
|
228
|
+
definition,
|
|
229
|
+
client,
|
|
230
|
+
config,
|
|
231
|
+
direction: "inbound"
|
|
232
|
+
});
|
|
276
233
|
yield [space, normalizedMessage];
|
|
277
234
|
}
|
|
278
235
|
};
|
|
@@ -383,8 +340,13 @@ async function Spectrum(options) {
|
|
|
383
340
|
__internal: { platforms: platformStates },
|
|
384
341
|
messages,
|
|
385
342
|
stop: stopOnce,
|
|
386
|
-
send: async (space, ...content) => {
|
|
387
|
-
await space.send(
|
|
343
|
+
send: (async (space, ...content) => {
|
|
344
|
+
return content.length === 1 ? await space.send(content[0]) : await space.send(
|
|
345
|
+
...content
|
|
346
|
+
);
|
|
347
|
+
}),
|
|
348
|
+
edit: async (message, newContent) => {
|
|
349
|
+
await message.edit(newContent);
|
|
388
350
|
},
|
|
389
351
|
responding: async (space, fn) => {
|
|
390
352
|
return space.responding(fn);
|
|
@@ -3,7 +3,7 @@ import { AdvancedIMessage } from '@photon-ai/advanced-imessage';
|
|
|
3
3
|
import { IMessageSDK } from '@photon-ai/imessage-kit';
|
|
4
4
|
import * as z from 'zod';
|
|
5
5
|
import z__default from 'zod';
|
|
6
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
6
|
+
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
|
|
7
7
|
import * as zod_v4_core from 'zod/v4/core';
|
|
8
8
|
import 'hotscript';
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
asText,
|
|
15
15
|
definePlatform
|
|
16
|
-
} from "../../chunk-
|
|
16
|
+
} from "../../chunk-XZTTLPHE.js";
|
|
17
17
|
|
|
18
18
|
// src/providers/imessage/index.ts
|
|
19
19
|
import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
|
|
@@ -114,6 +114,14 @@ import { Readable } from "stream";
|
|
|
114
114
|
import {
|
|
115
115
|
readAttachmentBytes
|
|
116
116
|
} from "@photon-ai/imessage-kit";
|
|
117
|
+
var toSendResult = (result) => {
|
|
118
|
+
if (!result.message?.id) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
"iMessage local send did not return a message id \u2014 track upstream in @photon-ai/imessage-kit"
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return { id: result.message.id, timestamp: result.sentAt };
|
|
124
|
+
};
|
|
117
125
|
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
118
126
|
var VCARD_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
119
127
|
"text/vcard",
|
|
@@ -180,6 +188,9 @@ var messages = (client) => stream((emit, end) => {
|
|
|
180
188
|
let lastPromise = Promise.resolve();
|
|
181
189
|
client.startWatching({
|
|
182
190
|
onMessage: (message) => {
|
|
191
|
+
if (message.isFromMe) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
183
194
|
lastPromise = lastPromise.then(() => toMessages(message)).then((ms) => {
|
|
184
195
|
for (const m of ms) {
|
|
185
196
|
emit(m);
|
|
@@ -199,7 +210,7 @@ var sendTempFile = async (client, spaceId, name, data) => {
|
|
|
199
210
|
const tmp = join(dir, safeName);
|
|
200
211
|
await writeFile(tmp, data);
|
|
201
212
|
try {
|
|
202
|
-
await client.send(spaceId, { attachments: [tmp] });
|
|
213
|
+
return await client.send(spaceId, { attachments: [tmp] });
|
|
203
214
|
} finally {
|
|
204
215
|
await rm(dir, { recursive: true, force: true }).catch(() => {
|
|
205
216
|
});
|
|
@@ -208,23 +219,26 @@ var sendTempFile = async (client, spaceId, name, data) => {
|
|
|
208
219
|
var send = async (client, spaceId, content) => {
|
|
209
220
|
switch (content.type) {
|
|
210
221
|
case "text":
|
|
211
|
-
await client.send(spaceId, content.text);
|
|
212
|
-
break;
|
|
222
|
+
return toSendResult(await client.send(spaceId, content.text));
|
|
213
223
|
case "attachment":
|
|
214
|
-
|
|
215
|
-
|
|
224
|
+
return toSendResult(
|
|
225
|
+
await sendTempFile(client, spaceId, content.name, await content.read())
|
|
226
|
+
);
|
|
216
227
|
case "contact": {
|
|
217
228
|
const vcf = await toVCard(content);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
229
|
+
return toSendResult(
|
|
230
|
+
await sendTempFile(
|
|
231
|
+
client,
|
|
232
|
+
spaceId,
|
|
233
|
+
vcardFileName(content),
|
|
234
|
+
Buffer.from(vcf, "utf8")
|
|
235
|
+
)
|
|
223
236
|
);
|
|
224
|
-
break;
|
|
225
237
|
}
|
|
226
238
|
default:
|
|
227
|
-
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Unsupported iMessage local content type: ${content.type}`
|
|
241
|
+
);
|
|
228
242
|
}
|
|
229
243
|
};
|
|
230
244
|
|
|
@@ -359,6 +373,10 @@ var ensureM4a = async (buffer, mimeType) => {
|
|
|
359
373
|
};
|
|
360
374
|
|
|
361
375
|
// src/providers/imessage/remote.ts
|
|
376
|
+
var toSendResult2 = (receipt) => ({
|
|
377
|
+
id: receipt.guid,
|
|
378
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
379
|
+
});
|
|
362
380
|
var VCARD_MIME_TYPES2 = /* @__PURE__ */ new Set([
|
|
363
381
|
"text/vcard",
|
|
364
382
|
"text/x-vcard",
|
|
@@ -425,6 +443,9 @@ var clientStream = (client) => {
|
|
|
425
443
|
(async () => {
|
|
426
444
|
try {
|
|
427
445
|
for await (const event of sub) {
|
|
446
|
+
if (event.message.isFromMe) {
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
428
449
|
for (const message of await toMessages2(client, event)) {
|
|
429
450
|
emit(message);
|
|
430
451
|
}
|
|
@@ -469,27 +490,27 @@ var stopTyping = async (clients, spaceId) => {
|
|
|
469
490
|
var send2 = async (clients, spaceId, content) => {
|
|
470
491
|
const remote = clients[0];
|
|
471
492
|
if (!remote) {
|
|
472
|
-
|
|
493
|
+
throw new Error("No remote iMessage client available");
|
|
473
494
|
}
|
|
495
|
+
const chat = chatGuid(spaceId);
|
|
474
496
|
switch (content.type) {
|
|
475
497
|
case "text":
|
|
476
|
-
await remote.messages.send(
|
|
477
|
-
break;
|
|
498
|
+
return toSendResult2(await remote.messages.send(chat, content.text));
|
|
478
499
|
case "attachment": {
|
|
479
500
|
const attachment = await remote.attachments.upload({
|
|
480
501
|
data: await content.read(),
|
|
481
502
|
fileName: content.name,
|
|
482
503
|
mimeType: content.mimeType
|
|
483
504
|
});
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
505
|
+
return toSendResult2(
|
|
506
|
+
await remote.messages.send(chat, "", {
|
|
507
|
+
attachment: attachment.guid
|
|
508
|
+
})
|
|
509
|
+
);
|
|
488
510
|
}
|
|
489
511
|
case "contact": {
|
|
490
512
|
const attachment = await sendContactAttachment(remote, content);
|
|
491
|
-
await remote.messages.send(
|
|
492
|
-
break;
|
|
513
|
+
return toSendResult2(await remote.messages.send(chat, "", { attachment }));
|
|
493
514
|
}
|
|
494
515
|
case "voice": {
|
|
495
516
|
const { buffer } = await ensureM4a(
|
|
@@ -501,11 +522,12 @@ var send2 = async (clients, spaceId, content) => {
|
|
|
501
522
|
fileName: content.name ?? "voice.m4a",
|
|
502
523
|
mimeType: "audio/x-m4a"
|
|
503
524
|
});
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
525
|
+
return toSendResult2(
|
|
526
|
+
await remote.messages.send(chat, "", {
|
|
527
|
+
attachment: attachment.guid,
|
|
528
|
+
audioMessage: true
|
|
529
|
+
})
|
|
530
|
+
);
|
|
509
531
|
}
|
|
510
532
|
default:
|
|
511
533
|
throw new Error(`Unsupported iMessage content type: ${content.type}`);
|
|
@@ -514,30 +536,33 @@ var send2 = async (clients, spaceId, content) => {
|
|
|
514
536
|
var replyToMessage = async (clients, spaceId, msgId, content) => {
|
|
515
537
|
const remote = clients[0];
|
|
516
538
|
if (!remote) {
|
|
517
|
-
|
|
539
|
+
throw new Error("No remote iMessage client available");
|
|
518
540
|
}
|
|
519
541
|
const chat = chatGuid(spaceId);
|
|
520
542
|
const replyTo = messageGuid(msgId);
|
|
521
543
|
switch (content.type) {
|
|
522
544
|
case "text":
|
|
523
|
-
|
|
524
|
-
|
|
545
|
+
return toSendResult2(
|
|
546
|
+
await remote.messages.send(chat, content.text, { replyTo })
|
|
547
|
+
);
|
|
525
548
|
case "attachment": {
|
|
526
549
|
const attachment = await remote.attachments.upload({
|
|
527
550
|
data: await content.read(),
|
|
528
551
|
fileName: content.name,
|
|
529
552
|
mimeType: content.mimeType
|
|
530
553
|
});
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
554
|
+
return toSendResult2(
|
|
555
|
+
await remote.messages.send(chat, "", {
|
|
556
|
+
attachment: attachment.guid,
|
|
557
|
+
replyTo
|
|
558
|
+
})
|
|
559
|
+
);
|
|
536
560
|
}
|
|
537
561
|
case "contact": {
|
|
538
562
|
const attachment = await sendContactAttachment(remote, content);
|
|
539
|
-
|
|
540
|
-
|
|
563
|
+
return toSendResult2(
|
|
564
|
+
await remote.messages.send(chat, "", { attachment, replyTo })
|
|
565
|
+
);
|
|
541
566
|
}
|
|
542
567
|
case "voice": {
|
|
543
568
|
const { buffer } = await ensureM4a(
|
|
@@ -549,17 +574,32 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
|
|
|
549
574
|
fileName: content.name ?? "voice.m4a",
|
|
550
575
|
mimeType: "audio/x-m4a"
|
|
551
576
|
});
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
577
|
+
return toSendResult2(
|
|
578
|
+
await remote.messages.send(chat, "", {
|
|
579
|
+
attachment: attachment.guid,
|
|
580
|
+
audioMessage: true,
|
|
581
|
+
replyTo
|
|
582
|
+
})
|
|
583
|
+
);
|
|
558
584
|
}
|
|
559
585
|
default:
|
|
560
586
|
throw new Error(`Unsupported iMessage content type: ${content.type}`);
|
|
561
587
|
}
|
|
562
588
|
};
|
|
589
|
+
var editMessage = async (clients, spaceId, msgId, content) => {
|
|
590
|
+
if (content.type !== "text") {
|
|
591
|
+
throw new Error("iMessage only supports editing text content");
|
|
592
|
+
}
|
|
593
|
+
const remote = clients[0];
|
|
594
|
+
if (!remote) {
|
|
595
|
+
throw new Error("No remote iMessage client available");
|
|
596
|
+
}
|
|
597
|
+
await remote.messages.edit(
|
|
598
|
+
chatGuid(spaceId),
|
|
599
|
+
messageGuid(msgId),
|
|
600
|
+
content.text
|
|
601
|
+
);
|
|
602
|
+
};
|
|
563
603
|
var reactToMessage = async (clients, spaceId, msgId, reaction) => {
|
|
564
604
|
const remote = clients[0];
|
|
565
605
|
if (!remote) {
|
|
@@ -671,10 +711,9 @@ var imessage = definePlatform("iMessage", {
|
|
|
671
711
|
actions: {
|
|
672
712
|
send: async ({ space, content, client }) => {
|
|
673
713
|
if (isLocal(client)) {
|
|
674
|
-
await send(client, space.id, content);
|
|
675
|
-
} else {
|
|
676
|
-
await send2(client, space.id, content);
|
|
714
|
+
return await send(client, space.id, content);
|
|
677
715
|
}
|
|
716
|
+
return await send2(client, space.id, content);
|
|
678
717
|
},
|
|
679
718
|
startTyping: async ({ space, client }) => {
|
|
680
719
|
if (isLocal(client)) {
|
|
@@ -696,9 +735,19 @@ var imessage = definePlatform("iMessage", {
|
|
|
696
735
|
},
|
|
697
736
|
replyToMessage: async ({ space, messageId, content, client }) => {
|
|
698
737
|
if (isLocal(client)) {
|
|
699
|
-
|
|
738
|
+
throw new Error(
|
|
739
|
+
"iMessage local mode does not support replying to messages"
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
return await replyToMessage(client, space.id, messageId, content);
|
|
743
|
+
},
|
|
744
|
+
editMessage: async ({ space, messageId, content, client }) => {
|
|
745
|
+
if (isLocal(client)) {
|
|
746
|
+
throw new Error(
|
|
747
|
+
"iMessage local mode does not support editing messages"
|
|
748
|
+
);
|
|
700
749
|
}
|
|
701
|
-
await
|
|
750
|
+
await editMessage(client, space.id, messageId, content);
|
|
702
751
|
}
|
|
703
752
|
}
|
|
704
753
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
1
|
+
import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
|
|
2
2
|
import * as node_readline from 'node:readline';
|
|
3
3
|
import z__default from 'zod';
|
|
4
4
|
import 'hotscript';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
definePlatform
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-XZTTLPHE.js";
|
|
4
4
|
|
|
5
5
|
// src/providers/terminal/index.ts
|
|
6
6
|
import { createInterface } from "readline";
|
|
@@ -49,9 +49,13 @@ var terminal = definePlatform("terminal", {
|
|
|
49
49
|
},
|
|
50
50
|
actions: {
|
|
51
51
|
send: async ({ content }) => {
|
|
52
|
-
if (content.type
|
|
53
|
-
|
|
52
|
+
if (content.type !== "text") {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Terminal provider only supports text content, got "${content.type}"`
|
|
55
|
+
);
|
|
54
56
|
}
|
|
57
|
+
console.log(content.text);
|
|
58
|
+
return { id: crypto.randomUUID(), timestamp: /* @__PURE__ */ new Date() };
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { M as ManagedStream } from '../../stream-DGy4geUK.js';
|
|
2
2
|
import * as z from 'zod';
|
|
3
3
|
import z__default from 'zod';
|
|
4
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
4
|
+
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
|
|
5
5
|
import * as zod_v4_core from 'zod/v4/core';
|
|
6
6
|
import { WhatsAppClient } from '@photon-ai/whatsapp-business';
|
|
7
7
|
import 'hotscript';
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
asText,
|
|
9
9
|
definePlatform
|
|
10
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-XZTTLPHE.js";
|
|
11
11
|
|
|
12
12
|
// src/providers/whatsapp-business/index.ts
|
|
13
13
|
import {
|
|
@@ -16,6 +16,9 @@ import {
|
|
|
16
16
|
|
|
17
17
|
// src/providers/whatsapp-business/messages.ts
|
|
18
18
|
import { extension as mimeExtension } from "mime-types";
|
|
19
|
+
var toSendResult = (result) => ({
|
|
20
|
+
id: result.messageId
|
|
21
|
+
});
|
|
19
22
|
var mapWaPhoneType = (type) => {
|
|
20
23
|
if (!type) {
|
|
21
24
|
return void 0;
|
|
@@ -311,8 +314,9 @@ var messages = (client) => {
|
|
|
311
314
|
var send = async (client, spaceId, content) => {
|
|
312
315
|
switch (content.type) {
|
|
313
316
|
case "text":
|
|
314
|
-
|
|
315
|
-
|
|
317
|
+
return toSendResult(
|
|
318
|
+
await client.messages.send({ to: spaceId, text: content.text })
|
|
319
|
+
);
|
|
316
320
|
case "attachment": {
|
|
317
321
|
const { mediaId } = await client.media.upload({
|
|
318
322
|
file: await content.read(),
|
|
@@ -321,32 +325,35 @@ var send = async (client, spaceId, content) => {
|
|
|
321
325
|
});
|
|
322
326
|
const mediaType = mimeToMediaType(content.mimeType);
|
|
323
327
|
const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
328
|
+
return toSendResult(
|
|
329
|
+
await client.messages.send({
|
|
330
|
+
to: spaceId,
|
|
331
|
+
[mediaType]: mediaPayload
|
|
332
|
+
})
|
|
333
|
+
);
|
|
329
334
|
}
|
|
330
335
|
case "contact":
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
+
return toSendResult(
|
|
337
|
+
await client.messages.send({
|
|
338
|
+
to: spaceId,
|
|
339
|
+
contacts: [contactToWa(content)]
|
|
340
|
+
})
|
|
341
|
+
);
|
|
336
342
|
case "voice": {
|
|
337
343
|
const { mediaId } = await client.media.upload({
|
|
338
344
|
file: await content.read(),
|
|
339
345
|
mimeType: content.mimeType,
|
|
340
346
|
filename: voiceFilename(content)
|
|
341
347
|
});
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
348
|
+
return toSendResult(
|
|
349
|
+
await client.messages.send({
|
|
350
|
+
to: spaceId,
|
|
351
|
+
audio: { id: mediaId }
|
|
352
|
+
})
|
|
353
|
+
);
|
|
347
354
|
}
|
|
348
355
|
default:
|
|
349
|
-
|
|
356
|
+
throw new Error(`Unsupported WhatsApp content type: ${content.type}`);
|
|
350
357
|
}
|
|
351
358
|
};
|
|
352
359
|
var reactToMessage = async (client, spaceId, messageId, reaction) => {
|
|
@@ -358,12 +365,13 @@ var reactToMessage = async (client, spaceId, messageId, reaction) => {
|
|
|
358
365
|
var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
359
366
|
switch (content.type) {
|
|
360
367
|
case "text":
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
368
|
+
return toSendResult(
|
|
369
|
+
await client.messages.send({
|
|
370
|
+
to: spaceId,
|
|
371
|
+
replyTo: messageId,
|
|
372
|
+
text: content.text
|
|
373
|
+
})
|
|
374
|
+
);
|
|
367
375
|
case "attachment": {
|
|
368
376
|
const { mediaId } = await client.media.upload({
|
|
369
377
|
file: await content.read(),
|
|
@@ -372,35 +380,38 @@ var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
|
372
380
|
});
|
|
373
381
|
const mediaType = mimeToMediaType(content.mimeType);
|
|
374
382
|
const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
383
|
+
return toSendResult(
|
|
384
|
+
await client.messages.send({
|
|
385
|
+
to: spaceId,
|
|
386
|
+
replyTo: messageId,
|
|
387
|
+
[mediaType]: mediaPayload
|
|
388
|
+
})
|
|
389
|
+
);
|
|
381
390
|
}
|
|
382
391
|
case "contact":
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
392
|
+
return toSendResult(
|
|
393
|
+
await client.messages.send({
|
|
394
|
+
to: spaceId,
|
|
395
|
+
replyTo: messageId,
|
|
396
|
+
contacts: [contactToWa(content)]
|
|
397
|
+
})
|
|
398
|
+
);
|
|
389
399
|
case "voice": {
|
|
390
400
|
const { mediaId } = await client.media.upload({
|
|
391
401
|
file: await content.read(),
|
|
392
402
|
mimeType: content.mimeType,
|
|
393
403
|
filename: voiceFilename(content)
|
|
394
404
|
});
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
405
|
+
return toSendResult(
|
|
406
|
+
await client.messages.send({
|
|
407
|
+
to: spaceId,
|
|
408
|
+
replyTo: messageId,
|
|
409
|
+
audio: { id: mediaId }
|
|
410
|
+
})
|
|
411
|
+
);
|
|
401
412
|
}
|
|
402
413
|
default:
|
|
403
|
-
|
|
414
|
+
throw new Error(`Unsupported WhatsApp content type: ${content.type}`);
|
|
404
415
|
}
|
|
405
416
|
};
|
|
406
417
|
|
|
@@ -457,7 +468,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
|
|
|
457
468
|
},
|
|
458
469
|
actions: {
|
|
459
470
|
send: async ({ space, content, client }) => {
|
|
460
|
-
await send(client, space.id, content);
|
|
471
|
+
return await send(client, space.id, content);
|
|
461
472
|
},
|
|
462
473
|
reactToMessage: async ({ space, messageId, reaction, client }) => {
|
|
463
474
|
await reactToMessage(
|
|
@@ -468,7 +479,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
|
|
|
468
479
|
);
|
|
469
480
|
},
|
|
470
481
|
replyToMessage: async ({ space, messageId, content, client }) => {
|
|
471
|
-
await replyToMessage(
|
|
482
|
+
return await replyToMessage(
|
|
472
483
|
client,
|
|
473
484
|
space.id,
|
|
474
485
|
messageId,
|
|
@@ -92,23 +92,35 @@ interface User {
|
|
|
92
92
|
|
|
93
93
|
interface Space<_Def = unknown> {
|
|
94
94
|
readonly __platform: string;
|
|
95
|
+
edit(message: OutboundMessage, newContent: ContentInput): Promise<void>;
|
|
95
96
|
readonly id: string;
|
|
96
97
|
responding<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
97
|
-
send(
|
|
98
|
+
send(content: ContentInput): Promise<OutboundMessage>;
|
|
99
|
+
send(...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage[]>;
|
|
98
100
|
startTyping(): Promise<void>;
|
|
99
101
|
stopTyping(): Promise<void>;
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
interface
|
|
104
|
+
interface BaseMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
|
|
103
105
|
content: Content;
|
|
104
106
|
readonly id: string;
|
|
105
107
|
platform: TPlatform;
|
|
106
108
|
react(reaction: string): Promise<void>;
|
|
107
|
-
reply(
|
|
108
|
-
|
|
109
|
+
reply(content: ContentInput): Promise<OutboundMessage<TPlatform, TSender, TSpace>>;
|
|
110
|
+
reply(...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage<TPlatform, TSender, TSpace>[]>;
|
|
109
111
|
space: TSpace;
|
|
110
112
|
timestamp: Date;
|
|
111
113
|
}
|
|
114
|
+
interface InboundMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> extends BaseMessage<TPlatform, TSender, TSpace> {
|
|
115
|
+
direction: "inbound";
|
|
116
|
+
sender: TSender;
|
|
117
|
+
}
|
|
118
|
+
interface OutboundMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> extends BaseMessage<TPlatform, TSender, TSpace> {
|
|
119
|
+
direction: "outbound";
|
|
120
|
+
edit(newContent: ContentInput): Promise<void>;
|
|
121
|
+
sender: TSender | undefined;
|
|
122
|
+
}
|
|
123
|
+
type Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> = InboundMessage<TPlatform, TSender, TSpace> | OutboundMessage<TPlatform, TSender, TSpace>;
|
|
112
124
|
|
|
113
125
|
type ResolvedSpace = Pick<Space, "id">;
|
|
114
126
|
type SpaceRef = Pick<Space, "id" | "__platform">;
|
|
@@ -131,6 +143,11 @@ type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends
|
|
|
131
143
|
space: TSpace;
|
|
132
144
|
timestamp?: Date;
|
|
133
145
|
} & TExtra;
|
|
146
|
+
interface SendResult<TSender extends ResolvedUser = ResolvedUser> {
|
|
147
|
+
id: string;
|
|
148
|
+
sender?: TSender;
|
|
149
|
+
timestamp?: Date;
|
|
150
|
+
}
|
|
134
151
|
type MergeSchema<TSchema extends z__default.ZodType | undefined, TBase extends object> = TSchema extends z__default.ZodType ? string extends keyof z__default.infer<TSchema> ? TBase : Omit<z__default.infer<TSchema>, keyof TBase> & TBase : TBase;
|
|
135
152
|
type SchemaMessage<TUserSchema extends z__default.ZodType | undefined = undefined, TSpaceSchema extends z__default.ZodType | undefined = undefined> = ProviderMessage<MergeSchema<TUserSchema, ResolvedUser>, MergeSchema<TSpaceSchema, ResolvedSpace>>;
|
|
136
153
|
type InferEventPayload<T> = T extends (ctx: never) => AsyncIterable<infer P> ? P : never;
|
|
@@ -146,7 +163,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
146
163
|
content: Content;
|
|
147
164
|
client: _Client;
|
|
148
165
|
config: z__default.infer<_ConfigSchema>;
|
|
149
|
-
}) => Promise<
|
|
166
|
+
}) => Promise<SendResult<_ResolvedUser>>;
|
|
150
167
|
startTyping?: (_: {
|
|
151
168
|
space: _ResolvedSpace & SpaceRef;
|
|
152
169
|
client: _Client;
|
|
@@ -170,6 +187,13 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
170
187
|
content: Content;
|
|
171
188
|
client: _Client;
|
|
172
189
|
config: z__default.infer<_ConfigSchema>;
|
|
190
|
+
}) => Promise<SendResult<_ResolvedUser>>;
|
|
191
|
+
editMessage?: (_: {
|
|
192
|
+
space: _ResolvedSpace & SpaceRef;
|
|
193
|
+
messageId: string;
|
|
194
|
+
content: Content;
|
|
195
|
+
client: _Client;
|
|
196
|
+
config: z__default.infer<_ConfigSchema>;
|
|
173
197
|
}) => Promise<void>;
|
|
174
198
|
};
|
|
175
199
|
config: _ConfigSchema;
|
|
@@ -215,11 +239,12 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
215
239
|
}
|
|
216
240
|
interface AnyPlatformDef {
|
|
217
241
|
actions: {
|
|
218
|
-
send: (_: any) => Promise<
|
|
242
|
+
send: (_: any) => Promise<SendResult>;
|
|
219
243
|
startTyping?: (_: any) => Promise<void>;
|
|
220
244
|
stopTyping?: (_: any) => Promise<void>;
|
|
221
245
|
reactToMessage?: (_: any) => Promise<void>;
|
|
222
|
-
replyToMessage?: (_: any) => Promise<
|
|
246
|
+
replyToMessage?: (_: any) => Promise<SendResult>;
|
|
247
|
+
editMessage?: (_: any) => Promise<void>;
|
|
223
248
|
};
|
|
224
249
|
config: z__default.ZodType<object>;
|
|
225
250
|
events: {
|
|
@@ -318,4 +343,4 @@ interface Platform<Def extends AnyPlatformDef> {
|
|
|
318
343
|
(message: Message): PlatformMessage<Def>;
|
|
319
344
|
}
|
|
320
345
|
|
|
321
|
-
export type { AnyPlatformDef as A, ContentBuilder as C, EventProducer as E, Message as M, ProviderMessage as P, SpectrumLike as S, User as U, ContentInput as a, Content as b, PlatformDef as c, Platform as d, PlatformProviderConfig as e, CustomEventStreams as f, Space as g, PlatformInstance as h, PlatformMessage as i, PlatformSpace as j, PlatformUser as k, SchemaMessage as l };
|
|
346
|
+
export type { AnyPlatformDef as A, ContentBuilder as C, EventProducer as E, InboundMessage as I, Message as M, OutboundMessage as O, ProviderMessage as P, SpectrumLike as S, User as U, ContentInput as a, Content as b, PlatformDef as c, Platform as d, PlatformProviderConfig as e, CustomEventStreams as f, Space as g, PlatformInstance as h, PlatformMessage as i, PlatformSpace as j, PlatformUser as k, SchemaMessage as l };
|
package/package.json
CHANGED
package/dist/chunk-XEEDIGVK.js
DELETED
|
@@ -1,199 +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/platform/define.ts
|
|
20
|
-
function createPlatformInstance(def, runtime) {
|
|
21
|
-
const isPlatformUser = (value) => {
|
|
22
|
-
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
23
|
-
};
|
|
24
|
-
const normalizeSpaceArgs = (args) => {
|
|
25
|
-
if (args.length === 0) {
|
|
26
|
-
return { users: [], params: void 0 };
|
|
27
|
-
}
|
|
28
|
-
const [first, ...rest] = args;
|
|
29
|
-
if (Array.isArray(first)) {
|
|
30
|
-
return {
|
|
31
|
-
users: first,
|
|
32
|
-
params: rest[0]
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
if (!isPlatformUser(first)) {
|
|
36
|
-
return {
|
|
37
|
-
users: [],
|
|
38
|
-
params: first
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const last = args.at(-1);
|
|
42
|
-
if (last !== void 0 && !isPlatformUser(last)) {
|
|
43
|
-
return {
|
|
44
|
-
users: args.slice(0, -1),
|
|
45
|
-
params: last
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
users: args,
|
|
50
|
-
params: void 0
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
const base = {
|
|
54
|
-
async user(userID) {
|
|
55
|
-
const resolved = await def.user.resolve({
|
|
56
|
-
input: { userID },
|
|
57
|
-
client: runtime.client,
|
|
58
|
-
config: runtime.config
|
|
59
|
-
});
|
|
60
|
-
return {
|
|
61
|
-
...resolved,
|
|
62
|
-
__platform: def.name
|
|
63
|
-
};
|
|
64
|
-
},
|
|
65
|
-
async space(...args) {
|
|
66
|
-
const { users, params } = normalizeSpaceArgs(args);
|
|
67
|
-
let parsedParams = params;
|
|
68
|
-
if (params !== void 0 && def.space.params) {
|
|
69
|
-
parsedParams = def.space.params.parse(params);
|
|
70
|
-
}
|
|
71
|
-
const resolved = await def.space.resolve({
|
|
72
|
-
input: { users, params: parsedParams },
|
|
73
|
-
client: runtime.client,
|
|
74
|
-
config: runtime.config
|
|
75
|
-
});
|
|
76
|
-
const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
|
|
77
|
-
const spaceRef = {
|
|
78
|
-
id: parsedSpace.id,
|
|
79
|
-
__platform: def.name
|
|
80
|
-
};
|
|
81
|
-
const typingCtx = {
|
|
82
|
-
space: spaceRef,
|
|
83
|
-
client: runtime.client,
|
|
84
|
-
config: runtime.config
|
|
85
|
-
};
|
|
86
|
-
return {
|
|
87
|
-
...parsedSpace,
|
|
88
|
-
...spaceRef,
|
|
89
|
-
send: async (...content) => {
|
|
90
|
-
const built = await resolveContents(content);
|
|
91
|
-
for (const item of built) {
|
|
92
|
-
await def.actions.send({
|
|
93
|
-
...typingCtx,
|
|
94
|
-
content: item
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
startTyping: async () => {
|
|
99
|
-
await def.actions.startTyping?.(typingCtx);
|
|
100
|
-
},
|
|
101
|
-
stopTyping: async () => {
|
|
102
|
-
await def.actions.stopTyping?.(typingCtx);
|
|
103
|
-
},
|
|
104
|
-
responding: async (fn) => {
|
|
105
|
-
await def.actions.startTyping?.(typingCtx);
|
|
106
|
-
try {
|
|
107
|
-
return await fn();
|
|
108
|
-
} finally {
|
|
109
|
-
await def.actions.stopTyping?.(typingCtx).catch(() => {
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
const eventProperties = {};
|
|
117
|
-
for (const eventName of Object.keys(def.events)) {
|
|
118
|
-
if (eventName === "messages") {
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
const producer = def.events[eventName];
|
|
122
|
-
if (producer) {
|
|
123
|
-
eventProperties[eventName] = producer({
|
|
124
|
-
client: runtime.client,
|
|
125
|
-
config: runtime.config
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return Object.assign(base, eventProperties);
|
|
130
|
-
}
|
|
131
|
-
function definePlatform(name, def) {
|
|
132
|
-
const fullDef = { name, ...def };
|
|
133
|
-
const platformCache = /* @__PURE__ */ new WeakMap();
|
|
134
|
-
const narrowSpectrum = (spectrum) => {
|
|
135
|
-
const cached = platformCache.get(spectrum);
|
|
136
|
-
if (cached) {
|
|
137
|
-
return cached;
|
|
138
|
-
}
|
|
139
|
-
const runtime = spectrum.__internal.platforms.get(name);
|
|
140
|
-
if (!runtime) {
|
|
141
|
-
throw new Error(`Platform "${name}" is not registered`);
|
|
142
|
-
}
|
|
143
|
-
const instance = createPlatformInstance(
|
|
144
|
-
fullDef,
|
|
145
|
-
runtime
|
|
146
|
-
);
|
|
147
|
-
platformCache.set(spectrum, instance);
|
|
148
|
-
return instance;
|
|
149
|
-
};
|
|
150
|
-
const narrowSpace = (input) => {
|
|
151
|
-
if (input.__platform !== name) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
`Expected space from "${name}", got "${input.__platform}"`
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
return input;
|
|
157
|
-
};
|
|
158
|
-
const narrowMessage = (input) => {
|
|
159
|
-
if (input.platform !== name) {
|
|
160
|
-
throw new Error(
|
|
161
|
-
`Expected message from "${name}", got "${input.platform}"`
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
return input;
|
|
165
|
-
};
|
|
166
|
-
const narrower = ((input) => {
|
|
167
|
-
if ("__providers" in input && "__internal" in input) {
|
|
168
|
-
return narrowSpectrum(input);
|
|
169
|
-
}
|
|
170
|
-
if ("__platform" in input && "send" in input) {
|
|
171
|
-
return narrowSpace(input);
|
|
172
|
-
}
|
|
173
|
-
if ("platform" in input && "sender" in input && "space" in input) {
|
|
174
|
-
return narrowMessage(input);
|
|
175
|
-
}
|
|
176
|
-
throw new Error("Invalid input to platform narrowing function");
|
|
177
|
-
});
|
|
178
|
-
narrower.config = (config) => {
|
|
179
|
-
const resolvedConfig = config ?? {};
|
|
180
|
-
return {
|
|
181
|
-
__tag: "PlatformProviderConfig",
|
|
182
|
-
__def: void 0,
|
|
183
|
-
__name: name,
|
|
184
|
-
config: resolvedConfig,
|
|
185
|
-
__definition: fullDef
|
|
186
|
-
};
|
|
187
|
-
};
|
|
188
|
-
if (def.static) {
|
|
189
|
-
Object.assign(narrower, def.static);
|
|
190
|
-
}
|
|
191
|
-
return narrower;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export {
|
|
195
|
-
asText,
|
|
196
|
-
text,
|
|
197
|
-
resolveContents,
|
|
198
|
-
definePlatform
|
|
199
|
-
};
|