spectrum-ts 0.2.1 → 0.3.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-3TBRO2J7.js → chunk-V2PK557T.js} +15 -0
- package/dist/{chunk-LIRM7SBA.js → chunk-XEEDIGVK.js} +28 -5
- package/dist/chunk-ZRSCHSLZ.js +44 -0
- package/dist/index.d.ts +15 -5
- package/dist/index.js +27 -76
- package/dist/providers/imessage/index.d.ts +1 -2
- package/dist/providers/imessage/index.js +34 -33
- package/dist/providers/terminal/index.d.ts +3 -4
- package/dist/providers/terminal/index.js +4 -5
- package/dist/providers/whatsapp-business/index.d.ts +1 -2
- package/dist/providers/whatsapp-business/index.js +37 -71
- package/dist/{types-DQE0dQT4.d.ts → types-DuE2hXuJ.d.ts} +10 -16
- package/package.json +6 -29
- package/src/index.ts +0 -38
- package/src/platform/define.ts +0 -308
- package/src/platform/types.ts +0 -442
- package/src/providers/imessage/auth.ts +0 -115
- package/src/providers/imessage/index.ts +0 -153
- package/src/providers/imessage/local.ts +0 -55
- package/src/providers/imessage/remote.ts +0 -157
- package/src/providers/imessage/types.ts +0 -31
- package/src/providers/terminal/index.ts +0 -66
- package/src/providers/whatsapp-business/index.ts +0 -77
- package/src/providers/whatsapp-business/messages.ts +0 -240
- package/src/providers/whatsapp-business/types.ts +0 -19
- package/src/spectrum.ts +0 -390
- package/src/types/content.ts +0 -85
- package/src/types/message.ts +0 -18
- package/src/types/space.ts +0 -10
- package/src/types/user.ts +0 -4
- package/src/utils/cloud.ts +0 -147
- package/src/utils/stream.ts +0 -71
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
asAttachment
|
|
3
|
+
} from "../../chunk-ZRSCHSLZ.js";
|
|
4
|
+
import {
|
|
5
|
+
asCustom,
|
|
2
6
|
stream
|
|
3
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-V2PK557T.js";
|
|
4
8
|
import {
|
|
9
|
+
asText,
|
|
5
10
|
definePlatform
|
|
6
|
-
} from "../../chunk-
|
|
11
|
+
} from "../../chunk-XEEDIGVK.js";
|
|
7
12
|
|
|
8
13
|
// src/providers/whatsapp-business/index.ts
|
|
9
14
|
import {
|
|
@@ -24,67 +29,33 @@ var toMessage = async (client, msg) => {
|
|
|
24
29
|
var mapContent = async (client, content) => {
|
|
25
30
|
switch (content.type) {
|
|
26
31
|
case "text":
|
|
27
|
-
return
|
|
32
|
+
return asText(content.body);
|
|
28
33
|
case "image":
|
|
29
34
|
case "video":
|
|
30
35
|
case "audio":
|
|
31
36
|
case "document":
|
|
32
|
-
return
|
|
37
|
+
return downloadMedia(client, content.media);
|
|
33
38
|
case "sticker":
|
|
34
|
-
return
|
|
35
|
-
{
|
|
36
|
-
type: "custom",
|
|
37
|
-
raw: { whatsapp_type: "sticker", ...content.sticker }
|
|
38
|
-
}
|
|
39
|
-
];
|
|
39
|
+
return asCustom({ whatsapp_type: "sticker", ...content.sticker });
|
|
40
40
|
case "location":
|
|
41
|
-
return
|
|
42
|
-
{
|
|
43
|
-
type: "custom",
|
|
44
|
-
raw: { whatsapp_type: "location", ...content.location }
|
|
45
|
-
}
|
|
46
|
-
];
|
|
41
|
+
return asCustom({ whatsapp_type: "location", ...content.location });
|
|
47
42
|
case "contacts":
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
];
|
|
43
|
+
return asCustom({
|
|
44
|
+
whatsapp_type: "contacts",
|
|
45
|
+
contacts: content.contacts
|
|
46
|
+
});
|
|
54
47
|
case "reaction":
|
|
55
|
-
return
|
|
56
|
-
{
|
|
57
|
-
type: "custom",
|
|
58
|
-
raw: { whatsapp_type: "reaction", ...content.reaction }
|
|
59
|
-
}
|
|
60
|
-
];
|
|
48
|
+
return asCustom({ whatsapp_type: "reaction", ...content.reaction });
|
|
61
49
|
case "interactive":
|
|
62
|
-
return
|
|
63
|
-
{
|
|
64
|
-
type: "custom",
|
|
65
|
-
raw: { whatsapp_type: "interactive", ...content.interactive }
|
|
66
|
-
}
|
|
67
|
-
];
|
|
50
|
+
return asCustom({ whatsapp_type: "interactive", ...content.interactive });
|
|
68
51
|
case "button":
|
|
69
|
-
return
|
|
70
|
-
{
|
|
71
|
-
type: "custom",
|
|
72
|
-
raw: { whatsapp_type: "button", ...content.button }
|
|
73
|
-
}
|
|
74
|
-
];
|
|
52
|
+
return asCustom({ whatsapp_type: "button", ...content.button });
|
|
75
53
|
case "order":
|
|
76
|
-
return
|
|
77
|
-
{ type: "custom", raw: { whatsapp_type: "order", ...content.order } }
|
|
78
|
-
];
|
|
54
|
+
return asCustom({ whatsapp_type: "order", ...content.order });
|
|
79
55
|
case "system":
|
|
80
|
-
return
|
|
81
|
-
{
|
|
82
|
-
type: "custom",
|
|
83
|
-
raw: { whatsapp_type: "system", ...content.system }
|
|
84
|
-
}
|
|
85
|
-
];
|
|
56
|
+
return asCustom({ whatsapp_type: "system", ...content.system });
|
|
86
57
|
default:
|
|
87
|
-
return
|
|
58
|
+
return asCustom({ whatsapp_type: "unknown" });
|
|
88
59
|
}
|
|
89
60
|
};
|
|
90
61
|
var downloadMedia = async (client, media) => {
|
|
@@ -95,21 +66,17 @@ var downloadMedia = async (client, media) => {
|
|
|
95
66
|
throw new Error(`Media download failed: ${response.status}`);
|
|
96
67
|
}
|
|
97
68
|
const data = Buffer.from(await response.arrayBuffer());
|
|
98
|
-
return {
|
|
99
|
-
type: "attachment",
|
|
69
|
+
return asAttachment({
|
|
100
70
|
data,
|
|
101
71
|
mimeType: media.mimeType,
|
|
102
72
|
name: media.filename ?? `media-${media.id}`
|
|
103
|
-
};
|
|
73
|
+
});
|
|
104
74
|
} catch {
|
|
105
|
-
return {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
mimeType: media.mimeType
|
|
111
|
-
}
|
|
112
|
-
};
|
|
75
|
+
return asCustom({
|
|
76
|
+
whatsapp_type: "media_error",
|
|
77
|
+
mediaId: media.id,
|
|
78
|
+
mimeType: media.mimeType
|
|
79
|
+
});
|
|
113
80
|
}
|
|
114
81
|
};
|
|
115
82
|
var mimeToMediaType = (mimeType) => {
|
|
@@ -145,7 +112,7 @@ var messages = (client) => {
|
|
|
145
112
|
};
|
|
146
113
|
var send = async (client, spaceId, content) => {
|
|
147
114
|
switch (content.type) {
|
|
148
|
-
case "
|
|
115
|
+
case "text":
|
|
149
116
|
await client.messages.send({ to: spaceId, text: content.text });
|
|
150
117
|
break;
|
|
151
118
|
case "attachment": {
|
|
@@ -174,7 +141,7 @@ var reactToMessage = async (client, spaceId, messageId, reaction) => {
|
|
|
174
141
|
};
|
|
175
142
|
var replyToMessage = async (client, spaceId, messageId, content) => {
|
|
176
143
|
switch (content.type) {
|
|
177
|
-
case "
|
|
144
|
+
case "text":
|
|
178
145
|
await client.messages.send({
|
|
179
146
|
to: spaceId,
|
|
180
147
|
replyTo: messageId,
|
|
@@ -254,10 +221,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
|
|
|
254
221
|
},
|
|
255
222
|
actions: {
|
|
256
223
|
send: async ({ space, content, client }) => {
|
|
257
|
-
|
|
258
|
-
for (const item of content) {
|
|
259
|
-
await send(wa, space.id, item);
|
|
260
|
-
}
|
|
224
|
+
await send(client, space.id, content);
|
|
261
225
|
},
|
|
262
226
|
reactToMessage: async ({ space, messageId, reaction, client }) => {
|
|
263
227
|
await reactToMessage(
|
|
@@ -268,10 +232,12 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
|
|
|
268
232
|
);
|
|
269
233
|
},
|
|
270
234
|
replyToMessage: async ({ space, messageId, content, client }) => {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
235
|
+
await replyToMessage(
|
|
236
|
+
client,
|
|
237
|
+
space.id,
|
|
238
|
+
messageId,
|
|
239
|
+
content
|
|
240
|
+
);
|
|
275
241
|
}
|
|
276
242
|
}
|
|
277
243
|
});
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { Pipe, Tuples, Fn } from 'hotscript';
|
|
2
2
|
import z__default from 'zod';
|
|
3
|
-
import { NonEmptyString } from 'type-fest';
|
|
4
3
|
|
|
5
4
|
declare const contentSchema: z__default.ZodDiscriminatedUnion<[z__default.ZodObject<{
|
|
6
|
-
type: z__default.ZodLiteral<"
|
|
5
|
+
type: z__default.ZodLiteral<"text">;
|
|
7
6
|
text: z__default.ZodString;
|
|
8
7
|
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
9
8
|
type: z__default.ZodLiteral<"custom">;
|
|
10
|
-
raw: z__default.
|
|
9
|
+
raw: z__default.ZodUnknown;
|
|
11
10
|
}, z__default.core.$strip>, z__default.ZodObject<{
|
|
12
11
|
type: z__default.ZodLiteral<"attachment">;
|
|
13
12
|
data: z__default.ZodCustom<Buffer<ArrayBufferLike>, Buffer<ArrayBufferLike>>;
|
|
@@ -18,18 +17,13 @@ type Content = z__default.infer<typeof contentSchema>;
|
|
|
18
17
|
interface ContentBuilder {
|
|
19
18
|
build(): Promise<Content>;
|
|
20
19
|
}
|
|
21
|
-
|
|
22
|
-
declare function custom(raw: z__default.infer<ReturnType<typeof z__default.json>>): ContentBuilder;
|
|
23
|
-
declare function attachment(input: string | Buffer, options?: {
|
|
24
|
-
mimeType?: string;
|
|
25
|
-
name?: string;
|
|
26
|
-
}): ContentBuilder;
|
|
20
|
+
type ContentInput = string | ContentBuilder;
|
|
27
21
|
|
|
28
22
|
interface Space<_Def = unknown> {
|
|
29
23
|
readonly __platform: string;
|
|
30
24
|
readonly id: string;
|
|
31
25
|
responding<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
32
|
-
send(...content: [
|
|
26
|
+
send(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
|
|
33
27
|
startTyping(): Promise<void>;
|
|
34
28
|
stopTyping(): Promise<void>;
|
|
35
29
|
}
|
|
@@ -40,11 +34,11 @@ interface User {
|
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
interface Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
|
|
43
|
-
content: Content
|
|
37
|
+
content: Content;
|
|
44
38
|
readonly id: string;
|
|
45
39
|
platform: TPlatform;
|
|
46
40
|
react(reaction: string): Promise<void>;
|
|
47
|
-
reply(...content: [
|
|
41
|
+
reply(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
|
|
48
42
|
sender: TSender;
|
|
49
43
|
space: TSpace;
|
|
50
44
|
timestamp: Date;
|
|
@@ -66,7 +60,7 @@ type EventProducer<TPayload = unknown, TClient = unknown, TConfig = unknown> = (
|
|
|
66
60
|
}) => AsyncIterable<TPayload>;
|
|
67
61
|
type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends ResolvedSpace = ResolvedSpace, TExtra extends object = Record<never, never>> = {
|
|
68
62
|
id: string;
|
|
69
|
-
content: Content
|
|
63
|
+
content: Content;
|
|
70
64
|
sender: TSender;
|
|
71
65
|
space: TSpace;
|
|
72
66
|
timestamp?: Date;
|
|
@@ -83,7 +77,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
83
77
|
actions: {
|
|
84
78
|
send: (_: {
|
|
85
79
|
space: _ResolvedSpace & SpaceRef;
|
|
86
|
-
content: Content
|
|
80
|
+
content: Content;
|
|
87
81
|
client: _Client;
|
|
88
82
|
config: z__default.infer<_ConfigSchema>;
|
|
89
83
|
}) => Promise<void>;
|
|
@@ -107,7 +101,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
|
|
|
107
101
|
replyToMessage?: (_: {
|
|
108
102
|
space: _ResolvedSpace & SpaceRef;
|
|
109
103
|
messageId: string;
|
|
110
|
-
content: Content
|
|
104
|
+
content: Content;
|
|
111
105
|
client: _Client;
|
|
112
106
|
config: z__default.infer<_ConfigSchema>;
|
|
113
107
|
}) => Promise<void>;
|
|
@@ -258,4 +252,4 @@ interface Platform<Def extends AnyPlatformDef> {
|
|
|
258
252
|
(message: Message): PlatformMessage<Def>;
|
|
259
253
|
}
|
|
260
254
|
|
|
261
|
-
export {
|
|
255
|
+
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 };
|
package/package.json
CHANGED
|
@@ -1,56 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
|
-
"dist"
|
|
10
|
-
"src"
|
|
9
|
+
"dist"
|
|
11
10
|
],
|
|
12
11
|
"exports": {
|
|
13
12
|
".": {
|
|
14
13
|
"types": "./dist/index.d.ts",
|
|
15
|
-
"bun": "./src/index.ts",
|
|
16
14
|
"default": "./dist/index.js"
|
|
17
15
|
},
|
|
18
|
-
"./providers
|
|
19
|
-
"types": "./dist/providers
|
|
20
|
-
"
|
|
21
|
-
"default": "./dist/providers/imessage/index.js"
|
|
22
|
-
},
|
|
23
|
-
"./providers/terminal": {
|
|
24
|
-
"types": "./dist/providers/terminal/index.d.ts",
|
|
25
|
-
"bun": "./src/providers/terminal/index.ts",
|
|
26
|
-
"default": "./dist/providers/terminal/index.js"
|
|
27
|
-
},
|
|
28
|
-
"./providers/whatsapp-business": {
|
|
29
|
-
"types": "./dist/providers/whatsapp-business/index.d.ts",
|
|
30
|
-
"bun": "./src/providers/whatsapp-business/index.ts",
|
|
31
|
-
"default": "./dist/providers/whatsapp-business/index.js"
|
|
16
|
+
"./providers/*": {
|
|
17
|
+
"types": "./dist/providers/*/index.d.ts",
|
|
18
|
+
"default": "./dist/providers/*/index.js"
|
|
32
19
|
}
|
|
33
20
|
},
|
|
34
|
-
"scripts": {
|
|
35
|
-
"build": "tsup",
|
|
36
|
-
"dev": "tsup --watch"
|
|
37
|
-
},
|
|
38
21
|
"dependencies": {
|
|
39
22
|
"@photon-ai/advanced-imessage": "^0.4.2",
|
|
40
23
|
"@photon-ai/whatsapp-business": "^0.1.1",
|
|
41
|
-
"@photon-ai/imessage-kit": "^
|
|
24
|
+
"@photon-ai/imessage-kit": "^3.0.0-rc.1",
|
|
42
25
|
"@repeaterjs/repeater": "^3.0.6",
|
|
43
26
|
"better-grpc": "^0.3.2",
|
|
44
27
|
"mime-types": "^3.0.1",
|
|
45
28
|
"type-fest": "^5.4.1",
|
|
46
29
|
"zod": "^4.2.1"
|
|
47
30
|
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@types/bun": "latest",
|
|
50
|
-
"@types/mime-types": "^3.0.1",
|
|
51
|
-
"hotscript": "^1.0.13",
|
|
52
|
-
"tsup": "^8.4.0"
|
|
53
|
-
},
|
|
54
31
|
"peerDependencies": {
|
|
55
32
|
"typescript": "^5"
|
|
56
33
|
},
|
package/src/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// biome-ignore lint/performance/noBarrelFile: library entry point
|
|
2
|
-
export { definePlatform } from "./platform/define";
|
|
3
|
-
export type {
|
|
4
|
-
AnyPlatformDef,
|
|
5
|
-
EventProducer,
|
|
6
|
-
Platform,
|
|
7
|
-
PlatformDef,
|
|
8
|
-
PlatformInstance,
|
|
9
|
-
PlatformMessage,
|
|
10
|
-
PlatformProviderConfig,
|
|
11
|
-
PlatformSpace,
|
|
12
|
-
PlatformUser,
|
|
13
|
-
SchemaMessage,
|
|
14
|
-
} from "./platform/types";
|
|
15
|
-
export { Spectrum, type SpectrumInstance } from "./spectrum";
|
|
16
|
-
export {
|
|
17
|
-
attachment,
|
|
18
|
-
type Content,
|
|
19
|
-
type ContentBuilder,
|
|
20
|
-
custom,
|
|
21
|
-
text,
|
|
22
|
-
} from "./types/content";
|
|
23
|
-
export type { Message } from "./types/message";
|
|
24
|
-
export type { Space } from "./types/space";
|
|
25
|
-
export type { User } from "./types/user";
|
|
26
|
-
export type {
|
|
27
|
-
CloudPlatform,
|
|
28
|
-
DedicatedTokenData,
|
|
29
|
-
ImessageInfoData,
|
|
30
|
-
PlatformStatus,
|
|
31
|
-
PlatformsData,
|
|
32
|
-
SharedTokenData,
|
|
33
|
-
SubscriptionData,
|
|
34
|
-
SubscriptionStatus,
|
|
35
|
-
TokenData,
|
|
36
|
-
} from "./utils/cloud";
|
|
37
|
-
export { cloud, SpectrumCloudError } from "./utils/cloud";
|
|
38
|
-
export { type ManagedStream, mergeStreams, stream } from "./utils/stream";
|
package/src/platform/define.ts
DELETED
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import type z from "zod";
|
|
2
|
-
import type { ContentBuilder } from "../types/content";
|
|
3
|
-
import type { Message } from "../types/message";
|
|
4
|
-
import type { Space } from "../types/space";
|
|
5
|
-
import type {
|
|
6
|
-
AnyPlatformDef,
|
|
7
|
-
Platform,
|
|
8
|
-
PlatformDef,
|
|
9
|
-
PlatformInstance,
|
|
10
|
-
PlatformMessage,
|
|
11
|
-
PlatformProviderConfig,
|
|
12
|
-
PlatformSpace,
|
|
13
|
-
PlatformUser,
|
|
14
|
-
ProviderMessage,
|
|
15
|
-
SpectrumLike,
|
|
16
|
-
} from "./types";
|
|
17
|
-
|
|
18
|
-
function createPlatformInstance<
|
|
19
|
-
Def extends AnyPlatformDef,
|
|
20
|
-
_Client,
|
|
21
|
-
_ConfigSchema extends z.ZodType<object>,
|
|
22
|
-
>(
|
|
23
|
-
def: Def,
|
|
24
|
-
runtime: { client: unknown; config: unknown }
|
|
25
|
-
): PlatformInstance<Def> {
|
|
26
|
-
const isPlatformUser = (value: unknown): value is PlatformUser<Def> => {
|
|
27
|
-
return (
|
|
28
|
-
typeof value === "object" &&
|
|
29
|
-
value !== null &&
|
|
30
|
-
"__platform" in value &&
|
|
31
|
-
(value as { __platform?: unknown }).__platform === def.name
|
|
32
|
-
);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const normalizeSpaceArgs = (
|
|
36
|
-
args: unknown[]
|
|
37
|
-
): { users: PlatformUser<Def>[]; params: unknown } => {
|
|
38
|
-
if (args.length === 0) {
|
|
39
|
-
return { users: [], params: undefined };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const [first, ...rest] = args;
|
|
43
|
-
if (Array.isArray(first)) {
|
|
44
|
-
return {
|
|
45
|
-
users: first as PlatformUser<Def>[],
|
|
46
|
-
params: rest[0],
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!isPlatformUser(first)) {
|
|
51
|
-
return {
|
|
52
|
-
users: [],
|
|
53
|
-
params: first,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const last = args.at(-1);
|
|
58
|
-
if (last !== undefined && !isPlatformUser(last)) {
|
|
59
|
-
return {
|
|
60
|
-
users: args.slice(0, -1) as PlatformUser<Def>[],
|
|
61
|
-
params: last,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
users: args as PlatformUser<Def>[],
|
|
67
|
-
params: undefined,
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const base = {
|
|
72
|
-
async user(userID: string) {
|
|
73
|
-
const resolved = await def.user.resolve({
|
|
74
|
-
input: { userID },
|
|
75
|
-
client: runtime.client as _Client,
|
|
76
|
-
config: runtime.config as z.infer<_ConfigSchema>,
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
...resolved,
|
|
80
|
-
__platform: def.name,
|
|
81
|
-
} as PlatformUser<Def>;
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
async space(...args: unknown[]) {
|
|
85
|
-
const { users, params } = normalizeSpaceArgs(args);
|
|
86
|
-
let parsedParams = params;
|
|
87
|
-
if (params !== undefined && def.space.params) {
|
|
88
|
-
parsedParams = def.space.params.parse(params);
|
|
89
|
-
}
|
|
90
|
-
const resolved = await def.space.resolve({
|
|
91
|
-
input: { users, params: parsedParams },
|
|
92
|
-
client: runtime.client as _Client,
|
|
93
|
-
config: runtime.config as z.infer<_ConfigSchema>,
|
|
94
|
-
});
|
|
95
|
-
const parsedSpace = def.space.schema
|
|
96
|
-
? def.space.schema.parse(resolved)
|
|
97
|
-
: resolved;
|
|
98
|
-
const spaceRef = {
|
|
99
|
-
id: parsedSpace.id,
|
|
100
|
-
__platform: def.name,
|
|
101
|
-
};
|
|
102
|
-
const typingCtx = {
|
|
103
|
-
space: spaceRef,
|
|
104
|
-
client: runtime.client as _Client,
|
|
105
|
-
config: runtime.config as z.infer<_ConfigSchema>,
|
|
106
|
-
};
|
|
107
|
-
return {
|
|
108
|
-
...parsedSpace,
|
|
109
|
-
...spaceRef,
|
|
110
|
-
send: async (...content: [ContentBuilder, ...ContentBuilder[]]) => {
|
|
111
|
-
const built = await Promise.all(content.map((c) => c.build()));
|
|
112
|
-
await def.actions.send({
|
|
113
|
-
...typingCtx,
|
|
114
|
-
content: built,
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
startTyping: async () => {
|
|
118
|
-
await def.actions.startTyping?.(typingCtx);
|
|
119
|
-
},
|
|
120
|
-
stopTyping: async () => {
|
|
121
|
-
await def.actions.stopTyping?.(typingCtx);
|
|
122
|
-
},
|
|
123
|
-
responding: async <T>(fn: () => T | Promise<T>): Promise<T> => {
|
|
124
|
-
await def.actions.startTyping?.(typingCtx);
|
|
125
|
-
try {
|
|
126
|
-
return await fn();
|
|
127
|
-
} finally {
|
|
128
|
-
await def.actions.stopTyping?.(typingCtx).catch(() => {});
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
} as PlatformSpace<Def>;
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// Add flat event properties for custom events (non-messages)
|
|
136
|
-
const eventProperties: Record<string, AsyncIterable<unknown>> = {};
|
|
137
|
-
for (const eventName of Object.keys(def.events)) {
|
|
138
|
-
if (eventName === "messages") {
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
const producer = def.events[eventName] as
|
|
142
|
-
| ((ctx: { client: unknown; config: unknown }) => AsyncIterable<unknown>)
|
|
143
|
-
| undefined;
|
|
144
|
-
if (producer) {
|
|
145
|
-
eventProperties[eventName] = producer({
|
|
146
|
-
client: runtime.client,
|
|
147
|
-
config: runtime.config,
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return Object.assign(base, eventProperties) as PlatformInstance<Def>;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
export function definePlatform<
|
|
156
|
-
_Name extends string,
|
|
157
|
-
_ConfigSchema extends z.ZodType<object>,
|
|
158
|
-
_UserSchema extends z.ZodType<object> | undefined,
|
|
159
|
-
_SpaceSchema extends z.ZodType<object> | undefined,
|
|
160
|
-
_SpaceParamsSchema extends z.ZodType<object> | undefined,
|
|
161
|
-
_Client,
|
|
162
|
-
_ResolvedUser extends { id: string },
|
|
163
|
-
_ResolvedSpace extends { id: string },
|
|
164
|
-
_MessageSchema extends z.ZodType<object> | undefined = undefined,
|
|
165
|
-
_MessageType extends ProviderMessage<
|
|
166
|
-
_ResolvedUser,
|
|
167
|
-
_ResolvedSpace,
|
|
168
|
-
_MessageSchema extends z.ZodType<object>
|
|
169
|
-
? z.infer<_MessageSchema>
|
|
170
|
-
: Record<never, never>
|
|
171
|
-
> = ProviderMessage<
|
|
172
|
-
_ResolvedUser,
|
|
173
|
-
_ResolvedSpace,
|
|
174
|
-
_MessageSchema extends z.ZodType<object>
|
|
175
|
-
? z.infer<_MessageSchema>
|
|
176
|
-
: Record<never, never>
|
|
177
|
-
>,
|
|
178
|
-
_Events extends {
|
|
179
|
-
messages: (ctx: {
|
|
180
|
-
client: _Client;
|
|
181
|
-
config: z.infer<_ConfigSchema>;
|
|
182
|
-
}) => AsyncIterable<_MessageType>;
|
|
183
|
-
} = {
|
|
184
|
-
messages: (ctx: {
|
|
185
|
-
client: _Client;
|
|
186
|
-
config: z.infer<_ConfigSchema>;
|
|
187
|
-
}) => AsyncIterable<_MessageType>;
|
|
188
|
-
},
|
|
189
|
-
_Static extends Record<string, unknown> = Record<never, never>,
|
|
190
|
-
>(
|
|
191
|
-
name: _Name,
|
|
192
|
-
def: Omit<
|
|
193
|
-
PlatformDef<
|
|
194
|
-
_Name,
|
|
195
|
-
_ConfigSchema,
|
|
196
|
-
_UserSchema,
|
|
197
|
-
_SpaceSchema,
|
|
198
|
-
_SpaceParamsSchema,
|
|
199
|
-
_Client,
|
|
200
|
-
_ResolvedUser,
|
|
201
|
-
_ResolvedSpace,
|
|
202
|
-
_MessageSchema,
|
|
203
|
-
_MessageType,
|
|
204
|
-
_Events
|
|
205
|
-
>,
|
|
206
|
-
"name"
|
|
207
|
-
> & { static?: _Static }
|
|
208
|
-
): Platform<
|
|
209
|
-
PlatformDef<
|
|
210
|
-
_Name,
|
|
211
|
-
_ConfigSchema,
|
|
212
|
-
_UserSchema,
|
|
213
|
-
_SpaceSchema,
|
|
214
|
-
_SpaceParamsSchema,
|
|
215
|
-
_Client,
|
|
216
|
-
_ResolvedUser,
|
|
217
|
-
_ResolvedSpace,
|
|
218
|
-
_MessageSchema,
|
|
219
|
-
_MessageType,
|
|
220
|
-
_Events
|
|
221
|
-
>
|
|
222
|
-
> &
|
|
223
|
-
Readonly<_Static> {
|
|
224
|
-
type Def = PlatformDef<
|
|
225
|
-
_Name,
|
|
226
|
-
_ConfigSchema,
|
|
227
|
-
_UserSchema,
|
|
228
|
-
_SpaceSchema,
|
|
229
|
-
_SpaceParamsSchema,
|
|
230
|
-
_Client,
|
|
231
|
-
_ResolvedUser,
|
|
232
|
-
_ResolvedSpace,
|
|
233
|
-
_MessageSchema,
|
|
234
|
-
_MessageType,
|
|
235
|
-
_Events
|
|
236
|
-
>;
|
|
237
|
-
|
|
238
|
-
const fullDef = { name, ...def };
|
|
239
|
-
|
|
240
|
-
const platformCache = new WeakMap<SpectrumLike, PlatformInstance<Def>>();
|
|
241
|
-
|
|
242
|
-
const narrowSpectrum = (spectrum: SpectrumLike) => {
|
|
243
|
-
const cached = platformCache.get(spectrum);
|
|
244
|
-
if (cached) {
|
|
245
|
-
return cached;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const runtime = spectrum.__internal.platforms.get(name);
|
|
249
|
-
if (!runtime) {
|
|
250
|
-
throw new Error(`Platform "${name}" is not registered`);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const instance = createPlatformInstance<Def, _Client, _ConfigSchema>(
|
|
254
|
-
fullDef as Def & AnyPlatformDef,
|
|
255
|
-
runtime
|
|
256
|
-
);
|
|
257
|
-
platformCache.set(spectrum, instance);
|
|
258
|
-
return instance;
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
const narrowSpace = (input: Space) => {
|
|
262
|
-
if (input.__platform !== name) {
|
|
263
|
-
throw new Error(
|
|
264
|
-
`Expected space from "${name}", got "${input.__platform}"`
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
return input as PlatformSpace<Def>;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
const narrowMessage = (input: Message) => {
|
|
271
|
-
if (input.platform !== name) {
|
|
272
|
-
throw new Error(
|
|
273
|
-
`Expected message from "${name}", got "${input.platform}"`
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
return input as PlatformMessage<Def>;
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const narrower = ((input: SpectrumLike | Space | Message) => {
|
|
280
|
-
if ("__providers" in input && "__internal" in input) {
|
|
281
|
-
return narrowSpectrum(input as SpectrumLike);
|
|
282
|
-
}
|
|
283
|
-
if ("__platform" in input && "send" in input) {
|
|
284
|
-
return narrowSpace(input as Space);
|
|
285
|
-
}
|
|
286
|
-
if ("platform" in input && "sender" in input && "space" in input) {
|
|
287
|
-
return narrowMessage(input as Message);
|
|
288
|
-
}
|
|
289
|
-
throw new Error("Invalid input to platform narrowing function");
|
|
290
|
-
}) as Platform<Def>;
|
|
291
|
-
|
|
292
|
-
narrower.config = (config?: z.input<_ConfigSchema>) => {
|
|
293
|
-
const resolvedConfig = config ?? {};
|
|
294
|
-
return {
|
|
295
|
-
__tag: "PlatformProviderConfig" as const,
|
|
296
|
-
__def: undefined as unknown as Def,
|
|
297
|
-
__name: name,
|
|
298
|
-
config: resolvedConfig,
|
|
299
|
-
__definition: fullDef as AnyPlatformDef,
|
|
300
|
-
} satisfies PlatformProviderConfig<Def> as PlatformProviderConfig<Def>;
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
if (def.static) {
|
|
304
|
-
Object.assign(narrower, def.static);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return narrower as Platform<Def> & Readonly<_Static>;
|
|
308
|
-
}
|