spectrum-ts 0.3.0 → 0.4.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-5XW4CAWS.js +165 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -4
- package/dist/providers/imessage/index.d.ts +1 -1
- package/dist/providers/imessage/index.js +87 -25
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.d.ts +1 -1
- package/dist/providers/whatsapp-business/index.js +32 -39
- package/dist/{types-DuE2hXuJ.d.ts → types-BdWMydUJ.d.ts} +4 -2
- package/package.json +3 -3
- package/dist/chunk-V2PK557T.js +0 -73
- package/dist/chunk-ZRSCHSLZ.js +0 -44
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// src/content/attachment.ts
|
|
2
|
+
import { createReadStream } from "fs";
|
|
3
|
+
import { readFile, stat } from "fs/promises";
|
|
4
|
+
import { basename } from "path";
|
|
5
|
+
import { Readable } from "stream";
|
|
6
|
+
import { lookup as lookupMimeType } from "mime-types";
|
|
7
|
+
import z from "zod";
|
|
8
|
+
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
9
|
+
var readSchema = z.function({
|
|
10
|
+
input: [],
|
|
11
|
+
output: z.promise(z.instanceof(Buffer))
|
|
12
|
+
});
|
|
13
|
+
var streamSchema = z.function({
|
|
14
|
+
input: [],
|
|
15
|
+
output: z.promise(z.instanceof(ReadableStream))
|
|
16
|
+
});
|
|
17
|
+
var attachmentSchema = z.object({
|
|
18
|
+
type: z.literal("attachment"),
|
|
19
|
+
name: z.string().nonempty(),
|
|
20
|
+
mimeType: z.string().nonempty(),
|
|
21
|
+
size: z.number().int().nonnegative().optional(),
|
|
22
|
+
read: readSchema,
|
|
23
|
+
stream: streamSchema
|
|
24
|
+
});
|
|
25
|
+
var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
|
|
26
|
+
var resolveAttachmentMimeType = (name, mimeType) => {
|
|
27
|
+
if (mimeType) {
|
|
28
|
+
return mimeType;
|
|
29
|
+
}
|
|
30
|
+
const resolvedMimeType = lookupMimeType(name);
|
|
31
|
+
if (!resolvedMimeType) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return resolvedMimeType;
|
|
37
|
+
};
|
|
38
|
+
var bufferToStream = (buf) => new ReadableStream({
|
|
39
|
+
start(controller) {
|
|
40
|
+
controller.enqueue(buf);
|
|
41
|
+
controller.close();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
var asAttachment = (input) => {
|
|
45
|
+
let cached;
|
|
46
|
+
const read = () => {
|
|
47
|
+
cached ??= input.read().catch((err) => {
|
|
48
|
+
cached = void 0;
|
|
49
|
+
throw err;
|
|
50
|
+
});
|
|
51
|
+
return cached;
|
|
52
|
+
};
|
|
53
|
+
const stream2 = input.stream ?? (async () => bufferToStream(await read()));
|
|
54
|
+
return attachmentSchema.parse({
|
|
55
|
+
type: "attachment",
|
|
56
|
+
name: input.name,
|
|
57
|
+
mimeType: input.mimeType,
|
|
58
|
+
size: input.size,
|
|
59
|
+
read,
|
|
60
|
+
stream: stream2
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
function attachment(input, options) {
|
|
64
|
+
return {
|
|
65
|
+
build: async () => {
|
|
66
|
+
const name = resolveAttachmentName(input, options?.name);
|
|
67
|
+
const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
|
|
68
|
+
if (typeof input === "string") {
|
|
69
|
+
const stats = await stat(input);
|
|
70
|
+
return asAttachment({
|
|
71
|
+
name,
|
|
72
|
+
mimeType,
|
|
73
|
+
size: stats.size,
|
|
74
|
+
read: () => readFile(input),
|
|
75
|
+
stream: async () => Readable.toWeb(
|
|
76
|
+
createReadStream(input)
|
|
77
|
+
)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return asAttachment({
|
|
81
|
+
name,
|
|
82
|
+
mimeType,
|
|
83
|
+
size: input.byteLength,
|
|
84
|
+
read: async () => input,
|
|
85
|
+
stream: async () => bufferToStream(input)
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/content/custom.ts
|
|
92
|
+
import z2 from "zod";
|
|
93
|
+
var customSchema = z2.object({
|
|
94
|
+
type: z2.literal("custom"),
|
|
95
|
+
raw: z2.unknown()
|
|
96
|
+
});
|
|
97
|
+
var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
|
|
98
|
+
function custom(raw) {
|
|
99
|
+
return {
|
|
100
|
+
build: async () => asCustom(raw)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/utils/stream.ts
|
|
105
|
+
import { Repeater } from "@repeaterjs/repeater";
|
|
106
|
+
function stream(setup) {
|
|
107
|
+
const repeater = new Repeater(async (push, stop) => {
|
|
108
|
+
const emit = (value) => {
|
|
109
|
+
Promise.resolve(push(value)).catch((error) => {
|
|
110
|
+
stop(error);
|
|
111
|
+
return void 0;
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
const end = (error) => {
|
|
115
|
+
stop(error);
|
|
116
|
+
};
|
|
117
|
+
const cleanup = await setup(emit, end);
|
|
118
|
+
try {
|
|
119
|
+
await stop;
|
|
120
|
+
} finally {
|
|
121
|
+
await cleanup?.();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return Object.assign(repeater, {
|
|
125
|
+
close: async () => {
|
|
126
|
+
await repeater.return(void 0);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function mergeStreams(streams) {
|
|
131
|
+
return stream((emit, end) => {
|
|
132
|
+
if (streams.length === 0) {
|
|
133
|
+
end();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
let openStreams = streams.length;
|
|
137
|
+
const workers = streams.map(async (source) => {
|
|
138
|
+
try {
|
|
139
|
+
for await (const value of source) {
|
|
140
|
+
emit(value);
|
|
141
|
+
}
|
|
142
|
+
} catch (error) {
|
|
143
|
+
end(error);
|
|
144
|
+
} finally {
|
|
145
|
+
openStreams -= 1;
|
|
146
|
+
if (openStreams === 0) {
|
|
147
|
+
end();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
return async () => {
|
|
152
|
+
await Promise.allSettled(streams.map((source) => source.close()));
|
|
153
|
+
await Promise.allSettled(workers);
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export {
|
|
159
|
+
asAttachment,
|
|
160
|
+
attachment,
|
|
161
|
+
asCustom,
|
|
162
|
+
custom,
|
|
163
|
+
stream,
|
|
164
|
+
mergeStreams
|
|
165
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ContentBuilder, 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, M as Message } from './types-
|
|
2
|
-
export { A as AnyPlatformDef, E as EventProducer, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage, U as User } from './types-
|
|
1
|
+
import { C as ContentBuilder, 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, M as Message } from './types-BdWMydUJ.js';
|
|
2
|
+
export { A as AnyPlatformDef, E as EventProducer, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage, U as User } from './types-BdWMydUJ.js';
|
|
3
3
|
import z__default from 'zod';
|
|
4
4
|
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-DGy4geUK.js';
|
|
5
5
|
import 'hotscript';
|
package/dist/index.js
CHANGED
|
@@ -3,13 +3,11 @@ import {
|
|
|
3
3
|
cloud
|
|
4
4
|
} from "./chunk-HXM64ENV.js";
|
|
5
5
|
import {
|
|
6
|
-
attachment
|
|
7
|
-
} from "./chunk-ZRSCHSLZ.js";
|
|
8
|
-
import {
|
|
6
|
+
attachment,
|
|
9
7
|
custom,
|
|
10
8
|
mergeStreams,
|
|
11
9
|
stream
|
|
12
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5XW4CAWS.js";
|
|
13
11
|
import {
|
|
14
12
|
definePlatform,
|
|
15
13
|
resolveContents,
|
|
@@ -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-BdWMydUJ.js';
|
|
7
7
|
import * as zod_v4_core from 'zod/v4/core';
|
|
8
8
|
import 'hotscript';
|
|
9
9
|
|
|
@@ -2,10 +2,11 @@ import {
|
|
|
2
2
|
cloud
|
|
3
3
|
} from "../../chunk-HXM64ENV.js";
|
|
4
4
|
import {
|
|
5
|
+
asAttachment,
|
|
5
6
|
asCustom,
|
|
6
7
|
mergeStreams,
|
|
7
8
|
stream
|
|
8
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-5XW4CAWS.js";
|
|
9
10
|
import {
|
|
10
11
|
asText,
|
|
11
12
|
definePlatform
|
|
@@ -102,23 +103,62 @@ async function disposeCloudAuth(clients) {
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
// src/providers/imessage/local.ts
|
|
106
|
+
import { createReadStream } from "fs";
|
|
105
107
|
import { unlink, writeFile } from "fs/promises";
|
|
106
108
|
import { tmpdir } from "os";
|
|
107
109
|
import { join } from "path";
|
|
110
|
+
import { Readable } from "stream";
|
|
111
|
+
import {
|
|
112
|
+
readAttachmentBytes
|
|
113
|
+
} from "@photon-ai/imessage-kit";
|
|
114
|
+
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
108
115
|
var toSpace = (message) => ({
|
|
109
116
|
id: message.chatId,
|
|
110
117
|
type: message.chatKind === "group" ? "group" : "dm"
|
|
111
118
|
});
|
|
112
|
-
var
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
var toMessages = (message) => {
|
|
120
|
+
const base = {
|
|
121
|
+
sender: { id: message.participant ?? "" },
|
|
122
|
+
space: toSpace(message),
|
|
123
|
+
timestamp: message.createdAt
|
|
124
|
+
};
|
|
125
|
+
if (message.attachments.length > 0) {
|
|
126
|
+
return message.attachments.map((att) => {
|
|
127
|
+
const { localPath } = att;
|
|
128
|
+
return {
|
|
129
|
+
...base,
|
|
130
|
+
id: `${message.id}:${att.id}`,
|
|
131
|
+
content: asAttachment({
|
|
132
|
+
name: att.fileName ?? DEFAULT_ATTACHMENT_NAME,
|
|
133
|
+
mimeType: att.mimeType,
|
|
134
|
+
size: att.sizeBytes,
|
|
135
|
+
read: () => readAttachmentBytes(att),
|
|
136
|
+
stream: localPath ? async () => Readable.toWeb(
|
|
137
|
+
createReadStream(localPath)
|
|
138
|
+
) : void 0
|
|
139
|
+
})
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return [
|
|
144
|
+
{
|
|
145
|
+
...base,
|
|
146
|
+
id: message.id,
|
|
147
|
+
content: { type: "text", text: message.text ?? "" }
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
};
|
|
151
|
+
var messages = (client) => stream((emit, end) => {
|
|
120
152
|
client.startWatching({
|
|
121
|
-
onMessage: (message) =>
|
|
153
|
+
onMessage: (message) => {
|
|
154
|
+
try {
|
|
155
|
+
for (const m of toMessages(message)) {
|
|
156
|
+
emit(m);
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
end(error);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
122
162
|
});
|
|
123
163
|
return () => client.stopWatching();
|
|
124
164
|
});
|
|
@@ -129,7 +169,7 @@ var send = async (client, spaceId, content) => {
|
|
|
129
169
|
break;
|
|
130
170
|
case "attachment": {
|
|
131
171
|
const tmp = join(tmpdir(), `spectrum-${Date.now()}-${content.name}`);
|
|
132
|
-
await writeFile(tmp, content.
|
|
172
|
+
await writeFile(tmp, await content.read());
|
|
133
173
|
try {
|
|
134
174
|
await client.send(spaceId, { attachments: [tmp] });
|
|
135
175
|
} finally {
|
|
@@ -152,18 +192,38 @@ import {
|
|
|
152
192
|
var TAPBACK_NAMES = new Set(
|
|
153
193
|
Object.values(Reaction).filter((r) => r !== "emoji" && r !== "sticker")
|
|
154
194
|
);
|
|
155
|
-
var
|
|
195
|
+
var baseMessage = (event) => ({
|
|
196
|
+
sender: { id: event.message.sender?.address ?? "" },
|
|
197
|
+
space: {
|
|
198
|
+
id: event.chatGuid,
|
|
199
|
+
type: event.chatGuid.includes(";+;") ? "group" : "dm"
|
|
200
|
+
},
|
|
201
|
+
timestamp: event.timestamp
|
|
202
|
+
});
|
|
203
|
+
var toMessages2 = (client, event) => {
|
|
204
|
+
const base = baseMessage(event);
|
|
205
|
+
const messageGuidStr = event.message.guid;
|
|
206
|
+
if (event.message.attachments.length > 0) {
|
|
207
|
+
return event.message.attachments.map((info) => ({
|
|
208
|
+
...base,
|
|
209
|
+
id: `${messageGuidStr}:${info.guid}`,
|
|
210
|
+
content: asAttachment({
|
|
211
|
+
name: info.fileName,
|
|
212
|
+
mimeType: info.mimeType,
|
|
213
|
+
size: info.totalBytes,
|
|
214
|
+
read: async () => Buffer.from(await client.attachments.downloadBuffer(info.guid)),
|
|
215
|
+
stream: async () => client.attachments.download(info.guid).stream
|
|
216
|
+
})
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
156
219
|
const text = event.message.text;
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
},
|
|
165
|
-
timestamp: event.timestamp
|
|
166
|
-
};
|
|
220
|
+
return [
|
|
221
|
+
{
|
|
222
|
+
...base,
|
|
223
|
+
id: messageGuidStr,
|
|
224
|
+
content: text ? asText(text) : asCustom(event.message)
|
|
225
|
+
}
|
|
226
|
+
];
|
|
167
227
|
};
|
|
168
228
|
var clientStream = (client) => {
|
|
169
229
|
const sub = client.messages.subscribe("message.received");
|
|
@@ -171,7 +231,9 @@ var clientStream = (client) => {
|
|
|
171
231
|
(async () => {
|
|
172
232
|
try {
|
|
173
233
|
for await (const event of sub) {
|
|
174
|
-
|
|
234
|
+
for (const message of toMessages2(client, event)) {
|
|
235
|
+
emit(message);
|
|
236
|
+
}
|
|
175
237
|
}
|
|
176
238
|
end();
|
|
177
239
|
} catch (e) {
|
|
@@ -207,7 +269,7 @@ var send2 = async (clients, spaceId, content) => {
|
|
|
207
269
|
break;
|
|
208
270
|
case "attachment": {
|
|
209
271
|
const attachment = await remote.attachments.upload({
|
|
210
|
-
data: content.
|
|
272
|
+
data: await content.read(),
|
|
211
273
|
fileName: content.name,
|
|
212
274
|
mimeType: content.mimeType
|
|
213
275
|
});
|
|
@@ -233,7 +295,7 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
|
|
|
233
295
|
break;
|
|
234
296
|
case "attachment": {
|
|
235
297
|
const attachment = await remote.attachments.upload({
|
|
236
|
-
data: content.
|
|
298
|
+
data: await content.read(),
|
|
237
299
|
fileName: content.name,
|
|
238
300
|
mimeType: content.mimeType
|
|
239
301
|
});
|
|
@@ -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-BdWMydUJ.js';
|
|
2
2
|
import * as node_readline from 'node:readline';
|
|
3
3
|
import z__default from 'zod';
|
|
4
4
|
import 'hotscript';
|
|
@@ -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-BdWMydUJ.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';
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
asAttachment
|
|
3
|
-
} from "../../chunk-ZRSCHSLZ.js";
|
|
4
|
-
import {
|
|
2
|
+
asAttachment,
|
|
5
3
|
asCustom,
|
|
6
4
|
stream
|
|
7
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-5XW4CAWS.js";
|
|
8
6
|
import {
|
|
9
7
|
asText,
|
|
10
8
|
definePlatform
|
|
@@ -16,17 +14,14 @@ import {
|
|
|
16
14
|
} from "@photon-ai/whatsapp-business";
|
|
17
15
|
|
|
18
16
|
// src/providers/whatsapp-business/messages.ts
|
|
19
|
-
var toMessage =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
var mapContent = async (client, content) => {
|
|
17
|
+
var toMessage = (client, msg) => ({
|
|
18
|
+
id: msg.id,
|
|
19
|
+
content: mapContent(client, msg.content),
|
|
20
|
+
sender: { id: msg.from },
|
|
21
|
+
space: { id: msg.from },
|
|
22
|
+
timestamp: msg.timestamp
|
|
23
|
+
});
|
|
24
|
+
var mapContent = (client, content) => {
|
|
30
25
|
switch (content.type) {
|
|
31
26
|
case "text":
|
|
32
27
|
return asText(content.body);
|
|
@@ -34,7 +29,7 @@ var mapContent = async (client, content) => {
|
|
|
34
29
|
case "video":
|
|
35
30
|
case "audio":
|
|
36
31
|
case "document":
|
|
37
|
-
return
|
|
32
|
+
return lazyMedia(client, content.media);
|
|
38
33
|
case "sticker":
|
|
39
34
|
return asCustom({ whatsapp_type: "sticker", ...content.sticker });
|
|
40
35
|
case "location":
|
|
@@ -58,27 +53,26 @@ var mapContent = async (client, content) => {
|
|
|
58
53
|
return asCustom({ whatsapp_type: "unknown" });
|
|
59
54
|
}
|
|
60
55
|
};
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
throw new Error(`Media download failed: ${response.status}`);
|
|
67
|
-
}
|
|
68
|
-
const data = Buffer.from(await response.arrayBuffer());
|
|
69
|
-
return asAttachment({
|
|
70
|
-
data,
|
|
71
|
-
mimeType: media.mimeType,
|
|
72
|
-
name: media.filename ?? `media-${media.id}`
|
|
73
|
-
});
|
|
74
|
-
} catch {
|
|
75
|
-
return asCustom({
|
|
76
|
-
whatsapp_type: "media_error",
|
|
77
|
-
mediaId: media.id,
|
|
78
|
-
mimeType: media.mimeType
|
|
79
|
-
});
|
|
56
|
+
var fetchMedia = async (client, mediaId) => {
|
|
57
|
+
const { url } = await client.media.getUrl(mediaId);
|
|
58
|
+
const response = await fetch(url);
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
throw new Error(`Media download failed: ${response.status}`);
|
|
80
61
|
}
|
|
62
|
+
return response;
|
|
81
63
|
};
|
|
64
|
+
var lazyMedia = (client, media) => asAttachment({
|
|
65
|
+
name: media.filename ?? `media-${media.id}`,
|
|
66
|
+
mimeType: media.mimeType,
|
|
67
|
+
read: async () => Buffer.from(await (await fetchMedia(client, media.id)).arrayBuffer()),
|
|
68
|
+
stream: async () => {
|
|
69
|
+
const response = await fetchMedia(client, media.id);
|
|
70
|
+
if (!response.body) {
|
|
71
|
+
throw new Error("Media response missing body");
|
|
72
|
+
}
|
|
73
|
+
return response.body;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
82
76
|
var mimeToMediaType = (mimeType) => {
|
|
83
77
|
if (mimeType.startsWith("image/")) {
|
|
84
78
|
return "image";
|
|
@@ -99,8 +93,7 @@ var messages = (client) => {
|
|
|
99
93
|
(async () => {
|
|
100
94
|
try {
|
|
101
95
|
for await (const event of eventStream) {
|
|
102
|
-
|
|
103
|
-
emit(msg);
|
|
96
|
+
emit(toMessage(client, event.message));
|
|
104
97
|
}
|
|
105
98
|
end();
|
|
106
99
|
} catch (e) {
|
|
@@ -117,7 +110,7 @@ var send = async (client, spaceId, content) => {
|
|
|
117
110
|
break;
|
|
118
111
|
case "attachment": {
|
|
119
112
|
const { mediaId } = await client.media.upload({
|
|
120
|
-
file: content.
|
|
113
|
+
file: await content.read(),
|
|
121
114
|
mimeType: content.mimeType,
|
|
122
115
|
filename: content.name
|
|
123
116
|
});
|
|
@@ -150,7 +143,7 @@ var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
|
150
143
|
break;
|
|
151
144
|
case "attachment": {
|
|
152
145
|
const { mediaId } = await client.media.upload({
|
|
153
|
-
file: content.
|
|
146
|
+
file: await content.read(),
|
|
154
147
|
mimeType: content.mimeType,
|
|
155
148
|
filename: content.name
|
|
156
149
|
});
|
|
@@ -9,9 +9,11 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
|
|
|
9
9
|
raw: z__default.ZodUnknown;
|
|
10
10
|
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
11
11
|
type: z__default.ZodLiteral<"attachment">;
|
|
12
|
-
data: z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
|
|
13
|
-
mimeType: z__default.ZodString;
|
|
14
12
|
name: z__default.ZodString;
|
|
13
|
+
mimeType: z__default.ZodString;
|
|
14
|
+
size: z__default.ZodOptional<z__default.ZodNumber>;
|
|
15
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
16
|
+
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
15
17
|
}, z__default.core.$strip>], "type">;
|
|
16
18
|
type Content = z__default.infer<typeof contentSchema>;
|
|
17
19
|
interface ContentBuilder {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@photon-ai/advanced-imessage": "^0.4.
|
|
22
|
+
"@photon-ai/advanced-imessage": "^0.4.3",
|
|
23
23
|
"@photon-ai/whatsapp-business": "^0.1.1",
|
|
24
|
-
"@photon-ai/imessage-kit": "^3.0.0-rc.
|
|
24
|
+
"@photon-ai/imessage-kit": "^3.0.0-rc.2",
|
|
25
25
|
"@repeaterjs/repeater": "^3.0.6",
|
|
26
26
|
"better-grpc": "^0.3.2",
|
|
27
27
|
"mime-types": "^3.0.1",
|
package/dist/chunk-V2PK557T.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/content/custom.ts
|
|
2
|
-
import z from "zod";
|
|
3
|
-
var customSchema = z.object({
|
|
4
|
-
type: z.literal("custom"),
|
|
5
|
-
raw: z.unknown()
|
|
6
|
-
});
|
|
7
|
-
var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
|
|
8
|
-
function custom(raw) {
|
|
9
|
-
return {
|
|
10
|
-
build: async () => asCustom(raw)
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// src/utils/stream.ts
|
|
15
|
-
import { Repeater } from "@repeaterjs/repeater";
|
|
16
|
-
function stream(setup) {
|
|
17
|
-
const repeater = new Repeater(async (push, stop) => {
|
|
18
|
-
const emit = (value) => {
|
|
19
|
-
Promise.resolve(push(value)).catch((error) => {
|
|
20
|
-
stop(error);
|
|
21
|
-
return void 0;
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
const end = (error) => {
|
|
25
|
-
stop(error);
|
|
26
|
-
};
|
|
27
|
-
const cleanup = await setup(emit, end);
|
|
28
|
-
try {
|
|
29
|
-
await stop;
|
|
30
|
-
} finally {
|
|
31
|
-
await cleanup?.();
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
return Object.assign(repeater, {
|
|
35
|
-
close: async () => {
|
|
36
|
-
await repeater.return(void 0);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function mergeStreams(streams) {
|
|
41
|
-
return stream((emit, end) => {
|
|
42
|
-
if (streams.length === 0) {
|
|
43
|
-
end();
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
let openStreams = streams.length;
|
|
47
|
-
const workers = streams.map(async (source) => {
|
|
48
|
-
try {
|
|
49
|
-
for await (const value of source) {
|
|
50
|
-
emit(value);
|
|
51
|
-
}
|
|
52
|
-
} catch (error) {
|
|
53
|
-
end(error);
|
|
54
|
-
} finally {
|
|
55
|
-
openStreams -= 1;
|
|
56
|
-
if (openStreams === 0) {
|
|
57
|
-
end();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
return async () => {
|
|
62
|
-
await Promise.allSettled(streams.map((source) => source.close()));
|
|
63
|
-
await Promise.allSettled(workers);
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export {
|
|
69
|
-
asCustom,
|
|
70
|
-
custom,
|
|
71
|
-
stream,
|
|
72
|
-
mergeStreams
|
|
73
|
-
};
|
package/dist/chunk-ZRSCHSLZ.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
// src/content/attachment.ts
|
|
2
|
-
import { readFile } from "fs/promises";
|
|
3
|
-
import { basename } from "path";
|
|
4
|
-
import { lookup as lookupMimeType } from "mime-types";
|
|
5
|
-
import z from "zod";
|
|
6
|
-
var DEFAULT_ATTACHMENT_NAME = "attachment";
|
|
7
|
-
var attachmentSchema = z.object({
|
|
8
|
-
type: z.literal("attachment"),
|
|
9
|
-
data: z.instanceof(Buffer),
|
|
10
|
-
mimeType: z.string().nonempty(),
|
|
11
|
-
name: z.string().nonempty()
|
|
12
|
-
});
|
|
13
|
-
var resolveAttachmentName = (input, name) => name || (typeof input === "string" ? basename(input) : DEFAULT_ATTACHMENT_NAME);
|
|
14
|
-
var resolveAttachmentMimeType = (name, mimeType) => {
|
|
15
|
-
if (mimeType) {
|
|
16
|
-
return mimeType;
|
|
17
|
-
}
|
|
18
|
-
const resolvedMimeType = lookupMimeType(name);
|
|
19
|
-
if (!resolvedMimeType) {
|
|
20
|
-
throw new Error(
|
|
21
|
-
`Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
return resolvedMimeType;
|
|
25
|
-
};
|
|
26
|
-
var asAttachment = (input) => attachmentSchema.parse({ type: "attachment", ...input });
|
|
27
|
-
function attachment(input, options) {
|
|
28
|
-
return {
|
|
29
|
-
build: async () => {
|
|
30
|
-
const data = typeof input === "string" ? await readFile(input) : input;
|
|
31
|
-
const name = resolveAttachmentName(input, options?.name);
|
|
32
|
-
return asAttachment({
|
|
33
|
-
data,
|
|
34
|
-
mimeType: resolveAttachmentMimeType(name, options?.mimeType),
|
|
35
|
-
name
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export {
|
|
42
|
-
asAttachment,
|
|
43
|
-
attachment
|
|
44
|
-
};
|