spectrum-ts 0.7.0 → 0.8.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-6URE4AYH.js → chunk-4O6MQC5Z.js} +25 -1
- package/dist/chunk-H5XYVRHM.js +141 -0
- package/dist/{chunk-GX3JCGSD.js → chunk-ZNUORCLB.js} +7 -5
- package/dist/index.d.ts +18 -4
- package/dist/index.js +17 -10
- package/dist/providers/imessage/index.d.ts +2 -2
- package/dist/providers/imessage/index.js +45 -7
- package/dist/providers/terminal/index.d.ts +1 -1
- package/dist/providers/terminal/index.js +1 -1
- package/dist/providers/whatsapp-business/index.d.ts +2 -2
- package/dist/providers/whatsapp-business/index.js +12 -8
- package/dist/{stream-DGy4geUK.d.ts → stream-B55k7W8-.d.ts} +1 -1
- package/dist/{types-B5tTx5hc.d.ts → types-DLrsDzV-.d.ts} +13 -2
- package/package.json +2 -1
|
@@ -292,6 +292,29 @@ function createPlatformInstance(def, runtime) {
|
|
|
292
292
|
const isPlatformUser = (value) => {
|
|
293
293
|
return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
|
|
294
294
|
};
|
|
295
|
+
const resolveUserID = async (userID) => {
|
|
296
|
+
const resolved = await def.user.resolve({
|
|
297
|
+
input: { userID },
|
|
298
|
+
client: runtime.client,
|
|
299
|
+
config: runtime.config
|
|
300
|
+
});
|
|
301
|
+
return {
|
|
302
|
+
...resolved,
|
|
303
|
+
__platform: def.name
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
const resolveStringUsers = async (args) => {
|
|
307
|
+
const convertArg = async (arg) => {
|
|
308
|
+
if (typeof arg === "string") {
|
|
309
|
+
return await resolveUserID(arg);
|
|
310
|
+
}
|
|
311
|
+
if (Array.isArray(arg)) {
|
|
312
|
+
return await Promise.all(arg.map(convertArg));
|
|
313
|
+
}
|
|
314
|
+
return arg;
|
|
315
|
+
};
|
|
316
|
+
return await Promise.all(args.map(convertArg));
|
|
317
|
+
};
|
|
295
318
|
const normalizeSpaceArgs = (args) => {
|
|
296
319
|
if (args.length === 0) {
|
|
297
320
|
return { users: [], params: void 0 };
|
|
@@ -334,7 +357,8 @@ function createPlatformInstance(def, runtime) {
|
|
|
334
357
|
};
|
|
335
358
|
},
|
|
336
359
|
async space(...args) {
|
|
337
|
-
const
|
|
360
|
+
const convertedArgs = await resolveStringUsers(args);
|
|
361
|
+
const { users, params } = normalizeSpaceArgs(convertedArgs);
|
|
338
362
|
let parsedParams = params;
|
|
339
363
|
if (params !== void 0 && def.space.params) {
|
|
340
364
|
parsedParams = def.space.params.parse(params);
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bufferToStream,
|
|
3
|
+
readSchema,
|
|
4
|
+
streamSchema
|
|
5
|
+
} from "./chunk-ZNUORCLB.js";
|
|
6
|
+
|
|
7
|
+
// src/content/richlink.ts
|
|
8
|
+
import z from "zod";
|
|
9
|
+
|
|
10
|
+
// src/utils/link-metadata.ts
|
|
11
|
+
import ogs from "open-graph-scraper";
|
|
12
|
+
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
13
|
+
var USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15 spectrum-ts/richlink";
|
|
14
|
+
var normaliseImageUrl = (raw, base) => {
|
|
15
|
+
try {
|
|
16
|
+
return new URL(raw, base).toString();
|
|
17
|
+
} catch {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var cleanString = (v) => {
|
|
22
|
+
if (typeof v !== "string") {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const trimmed = v.trim();
|
|
26
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
27
|
+
};
|
|
28
|
+
var fetchLinkMetadata = async (url) => {
|
|
29
|
+
try {
|
|
30
|
+
const result = await ogs({
|
|
31
|
+
url,
|
|
32
|
+
timeout: DEFAULT_TIMEOUT_MS,
|
|
33
|
+
fetchOptions: { headers: { "User-Agent": USER_AGENT } }
|
|
34
|
+
});
|
|
35
|
+
if (result.error) {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
const {
|
|
39
|
+
ogTitle,
|
|
40
|
+
ogDescription,
|
|
41
|
+
ogImage,
|
|
42
|
+
twitterTitle,
|
|
43
|
+
twitterDescription,
|
|
44
|
+
twitterImage
|
|
45
|
+
} = result.result;
|
|
46
|
+
const title = cleanString(ogTitle) ?? cleanString(twitterTitle);
|
|
47
|
+
const summary = cleanString(ogDescription) ?? cleanString(twitterDescription);
|
|
48
|
+
const imageCandidate = ogImage?.[0] ?? twitterImage?.[0];
|
|
49
|
+
const resolved = imageCandidate ? normaliseImageUrl(imageCandidate.url, url) : void 0;
|
|
50
|
+
const image = imageCandidate && resolved ? {
|
|
51
|
+
url: resolved,
|
|
52
|
+
mimeType: "type" in imageCandidate && typeof imageCandidate.type === "string" ? imageCandidate.type : void 0
|
|
53
|
+
} : void 0;
|
|
54
|
+
return { title, summary, image };
|
|
55
|
+
} catch {
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var fetchImage = async (url) => {
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);
|
|
62
|
+
try {
|
|
63
|
+
const res = await fetch(url, {
|
|
64
|
+
signal: controller.signal,
|
|
65
|
+
headers: { "User-Agent": USER_AGENT }
|
|
66
|
+
});
|
|
67
|
+
if (!res.ok) {
|
|
68
|
+
throw new Error(`image fetch ${url} returned ${res.status}`);
|
|
69
|
+
}
|
|
70
|
+
const data = Buffer.from(await res.arrayBuffer());
|
|
71
|
+
const mimeType = res.headers.get("content-type") ?? void 0;
|
|
72
|
+
return { data, mimeType };
|
|
73
|
+
} finally {
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/content/richlink.ts
|
|
79
|
+
var richlinkCoverSchema = z.object({
|
|
80
|
+
mimeType: z.string().min(1).optional(),
|
|
81
|
+
read: readSchema,
|
|
82
|
+
stream: streamSchema
|
|
83
|
+
});
|
|
84
|
+
var optionalStringAccessor = z.function({
|
|
85
|
+
input: [],
|
|
86
|
+
output: z.promise(z.string().min(1).optional())
|
|
87
|
+
});
|
|
88
|
+
var coverAccessor = z.function({
|
|
89
|
+
input: [],
|
|
90
|
+
output: z.promise(richlinkCoverSchema.optional())
|
|
91
|
+
});
|
|
92
|
+
var richlinkSchema = z.object({
|
|
93
|
+
type: z.literal("richlink"),
|
|
94
|
+
url: z.url(),
|
|
95
|
+
title: optionalStringAccessor,
|
|
96
|
+
summary: optionalStringAccessor,
|
|
97
|
+
cover: coverAccessor
|
|
98
|
+
});
|
|
99
|
+
var memoize = (factory) => {
|
|
100
|
+
let cached;
|
|
101
|
+
return () => {
|
|
102
|
+
cached ??= factory();
|
|
103
|
+
return cached;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
var buildCover = (image) => {
|
|
107
|
+
const read = memoize(
|
|
108
|
+
() => fetchImage(image.url).then((r) => r.data).catch(() => Buffer.alloc(0))
|
|
109
|
+
);
|
|
110
|
+
return {
|
|
111
|
+
mimeType: image.mimeType,
|
|
112
|
+
read,
|
|
113
|
+
stream: async () => bufferToStream(await read())
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
var asRichlink = (input) => {
|
|
117
|
+
const getMetadata = memoize(() => fetchLinkMetadata(input.url));
|
|
118
|
+
const getCover = memoize(async () => {
|
|
119
|
+
const { image } = await getMetadata();
|
|
120
|
+
return image ? buildCover(image) : void 0;
|
|
121
|
+
});
|
|
122
|
+
const title = async () => (await getMetadata()).title;
|
|
123
|
+
const summary = async () => (await getMetadata()).summary;
|
|
124
|
+
return richlinkSchema.parse({
|
|
125
|
+
type: "richlink",
|
|
126
|
+
url: input.url,
|
|
127
|
+
title,
|
|
128
|
+
summary,
|
|
129
|
+
cover: getCover
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
function richlink(url) {
|
|
133
|
+
return {
|
|
134
|
+
build: async () => asRichlink({ url })
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
asRichlink,
|
|
140
|
+
richlink
|
|
141
|
+
};
|
|
@@ -557,11 +557,13 @@ function custom(raw) {
|
|
|
557
557
|
import { Repeater } from "@repeaterjs/repeater";
|
|
558
558
|
function stream(setup) {
|
|
559
559
|
const repeater = new Repeater(async (push, stop) => {
|
|
560
|
-
const emit = (value) => {
|
|
561
|
-
|
|
560
|
+
const emit = async (value) => {
|
|
561
|
+
try {
|
|
562
|
+
await push(value);
|
|
563
|
+
} catch (error) {
|
|
562
564
|
stop(error);
|
|
563
|
-
|
|
564
|
-
}
|
|
565
|
+
throw error;
|
|
566
|
+
}
|
|
565
567
|
};
|
|
566
568
|
const end = (error) => {
|
|
567
569
|
stop(error);
|
|
@@ -589,7 +591,7 @@ function mergeStreams(streams) {
|
|
|
589
591
|
const workers = streams.map(async (source) => {
|
|
590
592
|
try {
|
|
591
593
|
for await (const value of source) {
|
|
592
|
-
emit(value);
|
|
594
|
+
await emit(value);
|
|
593
595
|
}
|
|
594
596
|
} catch (error) {
|
|
595
597
|
end(error);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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-
|
|
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-
|
|
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-DLrsDzV-.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-DLrsDzV-.js';
|
|
3
3
|
import vCard from 'vcf';
|
|
4
4
|
import z__default from 'zod';
|
|
5
|
-
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-
|
|
5
|
+
export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-B55k7W8-.js';
|
|
6
6
|
import 'hotscript';
|
|
7
7
|
|
|
8
8
|
declare function attachment(input: string | Buffer, options?: {
|
|
@@ -124,6 +124,20 @@ declare function custom(raw: unknown): ContentBuilder;
|
|
|
124
124
|
|
|
125
125
|
declare const resolveContents: (items: readonly ContentInput[]) => Promise<Content[]>;
|
|
126
126
|
|
|
127
|
+
declare const richlinkSchema: z__default.ZodObject<{
|
|
128
|
+
type: z__default.ZodLiteral<"richlink">;
|
|
129
|
+
url: z__default.ZodURL;
|
|
130
|
+
title: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
|
|
131
|
+
summary: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
|
|
132
|
+
cover: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodObject<{
|
|
133
|
+
mimeType: z__default.ZodOptional<z__default.ZodString>;
|
|
134
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
135
|
+
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
136
|
+
}, z__default.core.$strip>>>>;
|
|
137
|
+
}, z__default.core.$strip>;
|
|
138
|
+
type Richlink = z__default.infer<typeof richlinkSchema>;
|
|
139
|
+
declare function richlink(url: string): ContentBuilder;
|
|
140
|
+
|
|
127
141
|
declare function text(text: string): ContentBuilder;
|
|
128
142
|
|
|
129
143
|
declare const voiceSchema: z__default.ZodObject<{
|
|
@@ -244,4 +258,4 @@ declare class UnsupportedError extends Error {
|
|
|
244
258
|
declare const fromVCard: (vcf: string) => ContactInput;
|
|
245
259
|
declare const toVCard: (contact: Contact) => Promise<string>;
|
|
246
260
|
|
|
247
|
-
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, UnsupportedError, type UnsupportedKind, User, type Voice, attachment, cloud, contact, custom, definePlatform, fromVCard, resolveContents, text, toVCard, voice };
|
|
261
|
+
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 Richlink, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, UnsupportedError, type UnsupportedKind, User, type Voice, attachment, cloud, contact, custom, definePlatform, fromVCard, resolveContents, richlink, text, toVCard, voice };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
richlink
|
|
3
|
+
} from "./chunk-H5XYVRHM.js";
|
|
1
4
|
import {
|
|
2
5
|
SpectrumCloudError,
|
|
3
6
|
attachment,
|
|
@@ -11,7 +14,7 @@ import {
|
|
|
11
14
|
stream,
|
|
12
15
|
streamSchema,
|
|
13
16
|
toVCard
|
|
14
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-ZNUORCLB.js";
|
|
15
18
|
import {
|
|
16
19
|
UnsupportedError,
|
|
17
20
|
buildMessage,
|
|
@@ -19,7 +22,7 @@ import {
|
|
|
19
22
|
definePlatform,
|
|
20
23
|
resolveContents,
|
|
21
24
|
text
|
|
22
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-4O6MQC5Z.js";
|
|
23
26
|
|
|
24
27
|
// src/content/voice.ts
|
|
25
28
|
import { createReadStream } from "fs";
|
|
@@ -173,11 +176,11 @@ async function Spectrum(options) {
|
|
|
173
176
|
const adaptIterable = (iterable) => {
|
|
174
177
|
return stream((emit, end) => {
|
|
175
178
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
176
|
-
(async () => {
|
|
179
|
+
const pump = (async () => {
|
|
177
180
|
try {
|
|
178
181
|
let result = await iterator.next();
|
|
179
182
|
while (!result.done) {
|
|
180
|
-
emit(result.value);
|
|
183
|
+
await emit(result.value);
|
|
181
184
|
result = await iterator.next();
|
|
182
185
|
}
|
|
183
186
|
end();
|
|
@@ -187,6 +190,7 @@ async function Spectrum(options) {
|
|
|
187
190
|
})();
|
|
188
191
|
return async () => {
|
|
189
192
|
await iterator.return?.();
|
|
193
|
+
await pump;
|
|
190
194
|
};
|
|
191
195
|
});
|
|
192
196
|
};
|
|
@@ -235,14 +239,14 @@ async function Spectrum(options) {
|
|
|
235
239
|
return adaptIterable(bindSend());
|
|
236
240
|
};
|
|
237
241
|
const createMessagesStream = () => {
|
|
238
|
-
return stream(
|
|
242
|
+
return stream((emit, end) => {
|
|
239
243
|
const merged = mergeStreams(
|
|
240
244
|
Array.from(platformStates.values(), createProviderMessagesStream)
|
|
241
245
|
);
|
|
242
|
-
(async () => {
|
|
246
|
+
const pump = (async () => {
|
|
243
247
|
try {
|
|
244
248
|
for await (const value of merged) {
|
|
245
|
-
emit(value);
|
|
249
|
+
await emit(value);
|
|
246
250
|
}
|
|
247
251
|
end();
|
|
248
252
|
} catch (error) {
|
|
@@ -251,11 +255,12 @@ async function Spectrum(options) {
|
|
|
251
255
|
})();
|
|
252
256
|
return async () => {
|
|
253
257
|
await merged.close();
|
|
258
|
+
await pump;
|
|
254
259
|
};
|
|
255
260
|
});
|
|
256
261
|
};
|
|
257
262
|
const createCustomEventStream = (eventName) => {
|
|
258
|
-
return stream(
|
|
263
|
+
return stream((emit, end) => {
|
|
259
264
|
const providerStreams = Array.from(platformStates.values(), (state) => {
|
|
260
265
|
const { client, config, definition } = state;
|
|
261
266
|
const producer = definition.events[eventName];
|
|
@@ -273,10 +278,10 @@ async function Spectrum(options) {
|
|
|
273
278
|
(value) => value !== void 0
|
|
274
279
|
);
|
|
275
280
|
const merged = mergeStreams(providerStreams);
|
|
276
|
-
(async () => {
|
|
281
|
+
const pump = (async () => {
|
|
277
282
|
try {
|
|
278
283
|
for await (const value of merged) {
|
|
279
|
-
emit(value);
|
|
284
|
+
await emit(value);
|
|
280
285
|
}
|
|
281
286
|
end();
|
|
282
287
|
} catch (error) {
|
|
@@ -285,6 +290,7 @@ async function Spectrum(options) {
|
|
|
285
290
|
})();
|
|
286
291
|
return async () => {
|
|
287
292
|
await merged.close();
|
|
293
|
+
await pump;
|
|
288
294
|
};
|
|
289
295
|
});
|
|
290
296
|
};
|
|
@@ -375,6 +381,7 @@ export {
|
|
|
375
381
|
fromVCard,
|
|
376
382
|
mergeStreams,
|
|
377
383
|
resolveContents,
|
|
384
|
+
richlink,
|
|
378
385
|
stream,
|
|
379
386
|
text,
|
|
380
387
|
toVCard,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { M as ManagedStream } from '../../stream-
|
|
1
|
+
import { M as ManagedStream } from '../../stream-B55k7W8-.js';
|
|
2
2
|
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-DLrsDzV-.js';
|
|
7
7
|
import * as zod_v4_core from 'zod/v4/core';
|
|
8
8
|
import 'hotscript';
|
|
9
9
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
asRichlink
|
|
3
|
+
} from "../../chunk-H5XYVRHM.js";
|
|
1
4
|
import {
|
|
2
5
|
asAttachment,
|
|
3
6
|
asContact,
|
|
@@ -7,12 +10,12 @@ import {
|
|
|
7
10
|
mergeStreams,
|
|
8
11
|
stream,
|
|
9
12
|
toVCard
|
|
10
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-ZNUORCLB.js";
|
|
11
14
|
import {
|
|
12
15
|
UnsupportedError,
|
|
13
16
|
asText,
|
|
14
17
|
definePlatform
|
|
15
|
-
} from "../../chunk-
|
|
18
|
+
} from "../../chunk-4O6MQC5Z.js";
|
|
16
19
|
|
|
17
20
|
// src/providers/imessage/index.ts
|
|
18
21
|
import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
|
|
@@ -191,9 +194,9 @@ var messages = (client) => stream((emit, end) => {
|
|
|
191
194
|
let lastPromise = Promise.resolve();
|
|
192
195
|
const startPromise = client.startWatching({
|
|
193
196
|
onIncomingMessage: (message) => {
|
|
194
|
-
lastPromise = lastPromise.then(() => toMessages(message)).then((ms) => {
|
|
197
|
+
lastPromise = lastPromise.then(() => toMessages(message)).then(async (ms) => {
|
|
195
198
|
for (const m of ms) {
|
|
196
|
-
emit(m);
|
|
199
|
+
await emit(m);
|
|
197
200
|
}
|
|
198
201
|
}).catch(end);
|
|
199
202
|
},
|
|
@@ -378,6 +381,7 @@ var ensureM4a = async (buffer, mimeType) => {
|
|
|
378
381
|
|
|
379
382
|
// src/providers/imessage/remote.ts
|
|
380
383
|
var PLATFORM = "iMessage";
|
|
384
|
+
var URL_BALLOON_BUNDLE_ID = "com.apple.messages.URLBalloonProvider";
|
|
381
385
|
var unsupportedContent = (type) => UnsupportedError.content(type, PLATFORM);
|
|
382
386
|
var toSendResult = (receipt) => ({
|
|
383
387
|
id: receipt.guid,
|
|
@@ -422,9 +426,29 @@ var toVCardContent2 = async (client, info) => {
|
|
|
422
426
|
return toAttachmentContent2(client, info);
|
|
423
427
|
}
|
|
424
428
|
};
|
|
429
|
+
var getBalloonBundleId = (message) => {
|
|
430
|
+
const raw = message._raw;
|
|
431
|
+
const id = raw?.balloonBundleId;
|
|
432
|
+
return typeof id === "string" ? id : void 0;
|
|
433
|
+
};
|
|
434
|
+
var toRichlinkMessage = (event, base, id) => {
|
|
435
|
+
const url = event.message.text ?? "";
|
|
436
|
+
try {
|
|
437
|
+
return { ...base, id, content: asRichlink({ url }) };
|
|
438
|
+
} catch {
|
|
439
|
+
return {
|
|
440
|
+
...base,
|
|
441
|
+
id,
|
|
442
|
+
content: url ? asText(url) : asCustom(event.message)
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
};
|
|
425
446
|
var toMessages2 = async (client, event) => {
|
|
426
447
|
const base = baseMessage(event);
|
|
427
448
|
const messageGuidStr = event.message.guid;
|
|
449
|
+
if (getBalloonBundleId(event.message) === URL_BALLOON_BUNDLE_ID) {
|
|
450
|
+
return [toRichlinkMessage(event, base, messageGuidStr)];
|
|
451
|
+
}
|
|
428
452
|
if (event.message.attachments.length > 0) {
|
|
429
453
|
return Promise.all(
|
|
430
454
|
event.message.attachments.map(async (info) => ({
|
|
@@ -446,14 +470,14 @@ var toMessages2 = async (client, event) => {
|
|
|
446
470
|
var clientStream = (client) => {
|
|
447
471
|
const sub = client.messages.subscribe("message.received");
|
|
448
472
|
return stream((emit, end) => {
|
|
449
|
-
(async () => {
|
|
473
|
+
const pump = (async () => {
|
|
450
474
|
try {
|
|
451
475
|
for await (const event of sub) {
|
|
452
476
|
if (event.message.isFromMe) {
|
|
453
477
|
continue;
|
|
454
478
|
}
|
|
455
479
|
for (const message of await toMessages2(client, event)) {
|
|
456
|
-
emit(message);
|
|
480
|
+
await emit(message);
|
|
457
481
|
}
|
|
458
482
|
}
|
|
459
483
|
end();
|
|
@@ -461,7 +485,10 @@ var clientStream = (client) => {
|
|
|
461
485
|
end(e);
|
|
462
486
|
}
|
|
463
487
|
})();
|
|
464
|
-
return () =>
|
|
488
|
+
return async () => {
|
|
489
|
+
sub.close();
|
|
490
|
+
await pump;
|
|
491
|
+
};
|
|
465
492
|
});
|
|
466
493
|
};
|
|
467
494
|
var sendVCardAttachment = (remote, name, vcf) => remote.attachments.upload({
|
|
@@ -502,6 +529,10 @@ var send2 = async (clients, spaceId, content) => {
|
|
|
502
529
|
switch (content.type) {
|
|
503
530
|
case "text":
|
|
504
531
|
return toSendResult(await remote.messages.send(chat, content.text));
|
|
532
|
+
case "richlink":
|
|
533
|
+
return toSendResult(
|
|
534
|
+
await remote.messages.send(chat, content.url, { richLink: true })
|
|
535
|
+
);
|
|
505
536
|
case "attachment": {
|
|
506
537
|
const attachment = await remote.attachments.upload({
|
|
507
538
|
data: await content.read(),
|
|
@@ -551,6 +582,13 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
|
|
|
551
582
|
return toSendResult(
|
|
552
583
|
await remote.messages.send(chat, content.text, { replyTo })
|
|
553
584
|
);
|
|
585
|
+
case "richlink":
|
|
586
|
+
return toSendResult(
|
|
587
|
+
await remote.messages.send(chat, content.url, {
|
|
588
|
+
richLink: true,
|
|
589
|
+
replyTo
|
|
590
|
+
})
|
|
591
|
+
);
|
|
554
592
|
case "attachment": {
|
|
555
593
|
const attachment = await remote.attachments.upload({
|
|
556
594
|
data: await content.read(),
|
|
@@ -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-DLrsDzV-.js';
|
|
2
2
|
import * as node_readline from 'node:readline';
|
|
3
3
|
import z__default from 'zod';
|
|
4
4
|
import 'hotscript';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { M as ManagedStream } from '../../stream-
|
|
1
|
+
import { M as ManagedStream } from '../../stream-B55k7W8-.js';
|
|
2
2
|
import { WhatsAppClient } from '@photon-ai/whatsapp-business';
|
|
3
3
|
import * as z from 'zod';
|
|
4
4
|
import z__default from 'zod';
|
|
5
|
-
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-
|
|
5
|
+
import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DLrsDzV-.js';
|
|
6
6
|
import * as zod_v4_core from 'zod/v4/core';
|
|
7
7
|
import 'hotscript';
|
|
8
8
|
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
cloud,
|
|
6
6
|
mergeStreams,
|
|
7
7
|
stream
|
|
8
|
-
} from "../../chunk-
|
|
8
|
+
} from "../../chunk-ZNUORCLB.js";
|
|
9
9
|
import {
|
|
10
10
|
UnsupportedError,
|
|
11
11
|
asText,
|
|
12
12
|
definePlatform
|
|
13
|
-
} from "../../chunk-
|
|
13
|
+
} from "../../chunk-4O6MQC5Z.js";
|
|
14
14
|
|
|
15
15
|
// src/providers/whatsapp-business/index.ts
|
|
16
16
|
import { createClient as createClient2 } from "@photon-ai/whatsapp-business";
|
|
@@ -174,7 +174,7 @@ var pumpOnce = async (ctx) => {
|
|
|
174
174
|
ctx.setActive(sub);
|
|
175
175
|
try {
|
|
176
176
|
for await (const event of sub) {
|
|
177
|
-
ctx.emit(event);
|
|
177
|
+
await ctx.emit(event);
|
|
178
178
|
}
|
|
179
179
|
return true;
|
|
180
180
|
} catch {
|
|
@@ -195,7 +195,7 @@ var resubscribableStream = (state, options) => {
|
|
|
195
195
|
active = s;
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
|
-
(async () => {
|
|
198
|
+
const pump = (async () => {
|
|
199
199
|
while (!closed) {
|
|
200
200
|
await pumpOnce(ctx);
|
|
201
201
|
if (!closed) {
|
|
@@ -204,11 +204,12 @@ var resubscribableStream = (state, options) => {
|
|
|
204
204
|
}
|
|
205
205
|
end();
|
|
206
206
|
})();
|
|
207
|
-
return () => {
|
|
207
|
+
return async () => {
|
|
208
208
|
closed = true;
|
|
209
209
|
active?.close().catch(() => void 0);
|
|
210
210
|
active = void 0;
|
|
211
211
|
state.subscriptions.delete(subscription);
|
|
212
|
+
await pump;
|
|
212
213
|
};
|
|
213
214
|
});
|
|
214
215
|
const subscription = {
|
|
@@ -518,11 +519,11 @@ var clientStream = (client) => {
|
|
|
518
519
|
(e) => e.type === "message"
|
|
519
520
|
);
|
|
520
521
|
return stream((emit, end) => {
|
|
521
|
-
(async () => {
|
|
522
|
+
const pump = (async () => {
|
|
522
523
|
try {
|
|
523
524
|
for await (const event of eventStream) {
|
|
524
525
|
for (const m of toMessages(client, event.message)) {
|
|
525
|
-
emit(m);
|
|
526
|
+
await emit(m);
|
|
526
527
|
}
|
|
527
528
|
}
|
|
528
529
|
end();
|
|
@@ -530,7 +531,10 @@ var clientStream = (client) => {
|
|
|
530
531
|
end(e);
|
|
531
532
|
}
|
|
532
533
|
})();
|
|
533
|
-
return () =>
|
|
534
|
+
return async () => {
|
|
535
|
+
await eventStream.close();
|
|
536
|
+
await pump;
|
|
537
|
+
};
|
|
534
538
|
});
|
|
535
539
|
};
|
|
536
540
|
var messages = (clients) => mergeStreams(clients.map(clientStream));
|
|
@@ -2,7 +2,7 @@ interface ManagedStream<T> extends AsyncIterable<T> {
|
|
|
2
2
|
close(): Promise<void>;
|
|
3
3
|
}
|
|
4
4
|
type StreamCleanup = void | (() => void | Promise<void>);
|
|
5
|
-
declare function stream<T>(setup: (emit: (value: T) => void
|
|
5
|
+
declare function stream<T>(setup: (emit: (value: T) => Promise<void>, end: (error?: unknown) => void) => StreamCleanup | Promise<StreamCleanup>): ManagedStream<T>;
|
|
6
6
|
declare function mergeStreams<T>(streams: readonly ManagedStream<T>[]): ManagedStream<T>;
|
|
7
7
|
|
|
8
8
|
export { type ManagedStream as M, mergeStreams as m, stream as s };
|
|
@@ -78,6 +78,16 @@ declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObj
|
|
|
78
78
|
size: z__default.ZodOptional<z__default.ZodNumber>;
|
|
79
79
|
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
80
80
|
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
81
|
+
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
82
|
+
type: z__default.ZodLiteral<"richlink">;
|
|
83
|
+
url: z__default.ZodURL;
|
|
84
|
+
title: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
|
|
85
|
+
summary: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodString>>>;
|
|
86
|
+
cover: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodOptional<z__default.ZodObject<{
|
|
87
|
+
mimeType: z__default.ZodOptional<z__default.ZodString>;
|
|
88
|
+
read: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>>>;
|
|
89
|
+
stream: z__default.ZodFunction<z__default.ZodTuple<readonly [], null>, z__default.ZodPromise<z__default.ZodCustom<ReadableStream<unknown>, ReadableStream<unknown>>>>;
|
|
90
|
+
}, z__default.core.$strip>>>>;
|
|
81
91
|
}, z__default.core.$strip>], "type">;
|
|
82
92
|
type Content = z__default.infer<typeof contentSchema>;
|
|
83
93
|
interface ContentBuilder {
|
|
@@ -310,12 +320,13 @@ type SpaceShapeOf<Def extends AnyPlatformDef> = [SchemaSpaceOf<Def>] extends [
|
|
|
310
320
|
never
|
|
311
321
|
] ? ResolvedSpaceOf<Def> : SchemaSpaceOf<Def>;
|
|
312
322
|
type SpaceParamsInputOf<Def extends AnyPlatformDef> = InputSchema<Def["space"]["params"]>;
|
|
323
|
+
type SpaceUserLike<Def extends AnyPlatformDef> = PlatformUser<Def> | string;
|
|
313
324
|
type SpaceArrayArgs<Def extends AnyPlatformDef> = [
|
|
314
325
|
SpaceParamsInputOf<Def>
|
|
315
|
-
] extends [never] ? [users:
|
|
326
|
+
] extends [never] ? [users: SpaceUserLike<Def>[]] : [users: SpaceUserLike<Def>[]] | [users: SpaceUserLike<Def>[], params: SpaceParamsInputOf<Def>] | [params: SpaceParamsInputOf<Def>];
|
|
316
327
|
type SpaceVarargArgs<Def extends AnyPlatformDef> = [
|
|
317
328
|
SpaceParamsInputOf<Def>
|
|
318
|
-
] extends [never] ?
|
|
329
|
+
] extends [never] ? SpaceUserLike<Def>[] : SpaceUserLike<Def>[] | [...SpaceUserLike<Def>[], SpaceParamsInputOf<Def>];
|
|
319
330
|
type SpaceArgs<Def extends AnyPlatformDef> = SpaceArrayArgs<Def> | SpaceVarargArgs<Def>;
|
|
320
331
|
type PlatformSpace<Def extends AnyPlatformDef> = Omit<SpaceShapeOf<Def>, keyof Space> & Space;
|
|
321
332
|
type PlatformMessage<Def extends AnyPlatformDef> = Omit<SchemaInfer<Def["message"]>, keyof Message> & Message<Def["name"], PlatformUser<Def>, PlatformSpace<Def>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@repeaterjs/repeater": "^3.0.6",
|
|
26
26
|
"better-grpc": "^0.3.2",
|
|
27
27
|
"mime-types": "^3.0.1",
|
|
28
|
+
"open-graph-scraper": "^6.11.0",
|
|
28
29
|
"type-fest": "^5.4.1",
|
|
29
30
|
"vcf": "^2.1.2",
|
|
30
31
|
"zod": "^4.2.1"
|