spectrum-ts 1.17.1 → 1.18.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.
|
@@ -60,21 +60,79 @@ function background(input, options) {
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// src/providers/imessage/content/customized-mini-app.ts
|
|
64
|
+
import z2 from "zod";
|
|
65
|
+
var layoutSchema = z2.object({
|
|
66
|
+
caption: z2.string().nonempty().optional(),
|
|
67
|
+
subcaption: z2.string().nonempty().optional(),
|
|
68
|
+
trailingCaption: z2.string().nonempty().optional(),
|
|
69
|
+
trailingSubcaption: z2.string().nonempty().optional(),
|
|
70
|
+
image: z2.instanceof(Uint8Array).optional(),
|
|
71
|
+
imageTitle: z2.string().nonempty().optional(),
|
|
72
|
+
imageSubtitle: z2.string().nonempty().optional(),
|
|
73
|
+
summary: z2.string().nonempty().optional()
|
|
74
|
+
}).refine(
|
|
75
|
+
(layout) => layout.caption !== void 0 || layout.subcaption !== void 0 || layout.trailingCaption !== void 0 || layout.trailingSubcaption !== void 0 || layout.image !== void 0,
|
|
76
|
+
{
|
|
77
|
+
message: "layout must set at least one of caption, subcaption, trailingCaption, trailingSubcaption, image"
|
|
78
|
+
}
|
|
79
|
+
).refine(
|
|
80
|
+
(layout) => layout.image === void 0 === (layout.imageTitle === void 0),
|
|
81
|
+
{
|
|
82
|
+
message: "layout.image and layout.imageTitle must be set together",
|
|
83
|
+
path: ["imageTitle"]
|
|
84
|
+
}
|
|
85
|
+
).refine(
|
|
86
|
+
(layout) => layout.imageSubtitle === void 0 || layout.image !== void 0,
|
|
87
|
+
{
|
|
88
|
+
message: "layout.imageSubtitle requires layout.image",
|
|
89
|
+
path: ["imageSubtitle"]
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
var customizedMiniAppSchema = z2.object({
|
|
93
|
+
type: z2.literal("customized-mini-app"),
|
|
94
|
+
__platform: z2.literal("iMessage"),
|
|
95
|
+
// Display name of the owning app, shown by Messages fallback UI.
|
|
96
|
+
appName: z2.string().nonempty(),
|
|
97
|
+
// Apple App Store numeric id of the owning app. Positive when set; omit to
|
|
98
|
+
// send a card whose extension is not published on the App Store.
|
|
99
|
+
appStoreId: z2.number().int().positive().optional(),
|
|
100
|
+
// Bundle identifier of the iMessage extension target.
|
|
101
|
+
extensionBundleId: z2.string().nonempty(),
|
|
102
|
+
// Visible card layout.
|
|
103
|
+
layout: layoutSchema,
|
|
104
|
+
// 10-character uppercase alphanumeric Apple Team ID.
|
|
105
|
+
teamId: z2.string(),
|
|
106
|
+
// Absolute URL delivered to the installed extension on tap.
|
|
107
|
+
url: z2.url()
|
|
108
|
+
});
|
|
109
|
+
var isCustomizedMiniApp = (v) => customizedMiniAppSchema.safeParse(v).success;
|
|
110
|
+
var asCustomizedMiniApp = (input) => customizedMiniAppSchema.parse({
|
|
111
|
+
type: "customized-mini-app",
|
|
112
|
+
__platform: "iMessage",
|
|
113
|
+
...input
|
|
114
|
+
});
|
|
115
|
+
function customizedMiniApp(input) {
|
|
116
|
+
return {
|
|
117
|
+
build: async () => asCustomizedMiniApp(input)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
63
121
|
// src/providers/imessage/content/effect.ts
|
|
64
122
|
import {
|
|
65
123
|
MessageEffect
|
|
66
124
|
} from "@photon-ai/advanced-imessage";
|
|
67
125
|
|
|
68
126
|
// src/content/effect.ts
|
|
69
|
-
import
|
|
70
|
-
var effectInnerSchema =
|
|
127
|
+
import z3 from "zod";
|
|
128
|
+
var effectInnerSchema = z3.discriminatedUnion("type", [
|
|
71
129
|
textSchema,
|
|
72
130
|
attachmentSchema
|
|
73
131
|
]);
|
|
74
|
-
var messageEffectSchema =
|
|
75
|
-
type:
|
|
132
|
+
var messageEffectSchema = z3.object({
|
|
133
|
+
type: z3.literal("effect"),
|
|
76
134
|
content: effectInnerSchema,
|
|
77
|
-
effect:
|
|
135
|
+
effect: z3.string().nonempty()
|
|
78
136
|
});
|
|
79
137
|
|
|
80
138
|
// src/providers/imessage/content/effect.ts
|
|
@@ -104,13 +162,13 @@ function effect(input, messageEffect) {
|
|
|
104
162
|
}
|
|
105
163
|
|
|
106
164
|
// src/providers/imessage/content/read.ts
|
|
107
|
-
import
|
|
165
|
+
import z4 from "zod";
|
|
108
166
|
var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
|
|
109
|
-
var readSchema =
|
|
110
|
-
type:
|
|
111
|
-
__platform:
|
|
112
|
-
__fireAndForget:
|
|
113
|
-
target:
|
|
167
|
+
var readSchema = z4.object({
|
|
168
|
+
type: z4.literal("read"),
|
|
169
|
+
__platform: z4.literal("iMessage"),
|
|
170
|
+
__fireAndForget: z4.literal(true),
|
|
171
|
+
target: z4.custom(isMessage, {
|
|
114
172
|
message: "read target must be a Message"
|
|
115
173
|
})
|
|
116
174
|
});
|
|
@@ -138,33 +196,33 @@ import { createClient } from "@photon-ai/advanced-imessage";
|
|
|
138
196
|
|
|
139
197
|
// src/providers/imessage/types.ts
|
|
140
198
|
import { IMessageSDK } from "@photon-ai/imessage-kit";
|
|
141
|
-
import
|
|
199
|
+
import z5 from "zod";
|
|
142
200
|
var SHARED_PHONE = "shared";
|
|
143
201
|
var isLocal = (client) => client instanceof IMessageSDK;
|
|
144
|
-
var clientEntry =
|
|
145
|
-
address:
|
|
146
|
-
token:
|
|
147
|
-
phone:
|
|
202
|
+
var clientEntry = z5.object({
|
|
203
|
+
address: z5.string(),
|
|
204
|
+
token: z5.string(),
|
|
205
|
+
phone: z5.string()
|
|
148
206
|
});
|
|
149
|
-
var configSchema =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
local:
|
|
153
|
-
clients: clientEntry.or(
|
|
207
|
+
var configSchema = z5.union([
|
|
208
|
+
z5.object({ local: z5.literal(true) }),
|
|
209
|
+
z5.object({
|
|
210
|
+
local: z5.literal(false).optional().default(false),
|
|
211
|
+
clients: clientEntry.or(z5.array(clientEntry)).optional()
|
|
154
212
|
})
|
|
155
213
|
]);
|
|
156
|
-
var userSchema =
|
|
157
|
-
var spaceSchema =
|
|
158
|
-
id:
|
|
159
|
-
type:
|
|
160
|
-
phone:
|
|
214
|
+
var userSchema = z5.object({});
|
|
215
|
+
var spaceSchema = z5.object({
|
|
216
|
+
id: z5.string(),
|
|
217
|
+
type: z5.enum(["dm", "group"]),
|
|
218
|
+
phone: z5.string()
|
|
161
219
|
});
|
|
162
|
-
var spaceParamsSchema =
|
|
163
|
-
phone:
|
|
220
|
+
var spaceParamsSchema = z5.object({
|
|
221
|
+
phone: z5.string().optional()
|
|
164
222
|
});
|
|
165
|
-
var messageSchema =
|
|
166
|
-
partIndex:
|
|
167
|
-
parentId:
|
|
223
|
+
var messageSchema = z5.object({
|
|
224
|
+
partIndex: z5.number().int().nonnegative().optional(),
|
|
225
|
+
parentId: z5.string().optional()
|
|
168
226
|
});
|
|
169
227
|
|
|
170
228
|
// src/providers/imessage/auth.ts
|
|
@@ -549,6 +607,18 @@ var setBackground = async (remote, spaceId, content) => {
|
|
|
549
607
|
);
|
|
550
608
|
};
|
|
551
609
|
|
|
610
|
+
// src/providers/imessage/remote/customized-mini-app.ts
|
|
611
|
+
var sendCustomizedMiniApp = async (remote, spaceId, content) => {
|
|
612
|
+
const chat = toChatGuid(spaceId);
|
|
613
|
+
const message = await remote.messages.sendCustomizedMiniApp(chat, content);
|
|
614
|
+
return {
|
|
615
|
+
id: message.guid,
|
|
616
|
+
content,
|
|
617
|
+
space: { id: spaceId },
|
|
618
|
+
timestamp: message.dateCreated
|
|
619
|
+
};
|
|
620
|
+
};
|
|
621
|
+
|
|
552
622
|
// src/providers/imessage/remote/inbound.ts
|
|
553
623
|
import {
|
|
554
624
|
NotFoundError as NotFoundError2
|
|
@@ -910,7 +980,6 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
|
|
|
910
980
|
if (childRef) {
|
|
911
981
|
try {
|
|
912
982
|
const fetched = await remote.messages.get(
|
|
913
|
-
toChatGuid(spaceId),
|
|
914
983
|
toMessageGuid(childRef.parentGuid)
|
|
915
984
|
);
|
|
916
985
|
const parent = await rebuildFromAppleMessage(
|
|
@@ -933,10 +1002,7 @@ var getMessage3 = async (remote, spaceId, msgId, phone) => {
|
|
|
933
1002
|
}
|
|
934
1003
|
}
|
|
935
1004
|
try {
|
|
936
|
-
const fetched = await remote.messages.get(
|
|
937
|
-
toChatGuid(spaceId),
|
|
938
|
-
toMessageGuid(msgId)
|
|
939
|
-
);
|
|
1005
|
+
const fetched = await remote.messages.get(toMessageGuid(msgId));
|
|
940
1006
|
const rebuilt = await rebuildFromAppleMessage(
|
|
941
1007
|
remote,
|
|
942
1008
|
fetched,
|
|
@@ -975,10 +1041,7 @@ var resolveReactionTarget = async (client, cache, chat, targetGuid, partIndex, p
|
|
|
975
1041
|
let candidate = cache.get(targetGuid);
|
|
976
1042
|
if (!candidate) {
|
|
977
1043
|
try {
|
|
978
|
-
const fetched = await client.messages.get(
|
|
979
|
-
toChatGuid(chat),
|
|
980
|
-
toMessageGuid(targetGuid)
|
|
981
|
-
);
|
|
1044
|
+
const fetched = await client.messages.get(toMessageGuid(targetGuid));
|
|
982
1045
|
candidate = await rebuildFromAppleMessage(client, fetched, phone, chat);
|
|
983
1046
|
cacheMessage(cache, candidate);
|
|
984
1047
|
} catch {
|
|
@@ -1987,6 +2050,7 @@ var stopTyping = async (remote, spaceId) => {
|
|
|
1987
2050
|
// src/providers/imessage/remote/api.ts
|
|
1988
2051
|
var messages4 = (clients, projectConfig) => messages3(clients, projectConfig);
|
|
1989
2052
|
var setBackground2 = async (remote, spaceId, content) => setBackground(remote, spaceId, content);
|
|
2053
|
+
var sendCustomizedMiniApp2 = async (remote, spaceId, content) => sendCustomizedMiniApp(remote, spaceId, content);
|
|
1990
2054
|
var setDisplayName2 = async (remote, spaceId, content) => setDisplayName(remote, spaceId, content);
|
|
1991
2055
|
var setIcon2 = async (remote, spaceId, content) => setIcon(remote, spaceId, content);
|
|
1992
2056
|
var markRead2 = async (remote, spaceId) => {
|
|
@@ -2067,6 +2131,17 @@ var handleBackground = async (client, space, content) => {
|
|
|
2067
2131
|
const remote = clientForPhone(client, space.phone);
|
|
2068
2132
|
await setBackground2(remote, space.id, content);
|
|
2069
2133
|
};
|
|
2134
|
+
var handleCustomizedMiniApp = async (client, space, content) => {
|
|
2135
|
+
if (isLocal(client)) {
|
|
2136
|
+
throw UnsupportedError.action(
|
|
2137
|
+
"customized-mini-app",
|
|
2138
|
+
"iMessage (local mode)",
|
|
2139
|
+
"mini app cards require remote iMessage"
|
|
2140
|
+
);
|
|
2141
|
+
}
|
|
2142
|
+
const remote = clientForPhone(client, space.phone);
|
|
2143
|
+
return await sendCustomizedMiniApp2(remote, space.id, content);
|
|
2144
|
+
};
|
|
2070
2145
|
var handleRead = async (client, space) => {
|
|
2071
2146
|
if (isLocal(client)) {
|
|
2072
2147
|
throw UnsupportedError.action(
|
|
@@ -2291,6 +2366,9 @@ var imessage = definePlatform("iMessage", {
|
|
|
2291
2366
|
await handleRead(client, space);
|
|
2292
2367
|
return;
|
|
2293
2368
|
}
|
|
2369
|
+
if (isCustomizedMiniApp(content)) {
|
|
2370
|
+
return await handleCustomizedMiniApp(client, space, content);
|
|
2371
|
+
}
|
|
2294
2372
|
if (isLocal(client)) {
|
|
2295
2373
|
return await send2(client, space.id, content);
|
|
2296
2374
|
}
|
|
@@ -2351,6 +2429,7 @@ var imessage = definePlatform("iMessage", {
|
|
|
2351
2429
|
|
|
2352
2430
|
export {
|
|
2353
2431
|
background,
|
|
2432
|
+
customizedMiniApp,
|
|
2354
2433
|
effect,
|
|
2355
2434
|
read,
|
|
2356
2435
|
imessage
|
package/dist/index.d.ts
CHANGED
|
@@ -373,8 +373,8 @@ declare function rename(displayName: string): ContentBuilder;
|
|
|
373
373
|
* `message.reply(content)` is sugar that delegates here. Providers see
|
|
374
374
|
* `reply` like any other content type and route to a threaded send.
|
|
375
375
|
*
|
|
376
|
-
* Reply cannot wrap `reply`, `edit`, `reaction`, `group`, `typing`,
|
|
377
|
-
* or `avatar` content.
|
|
376
|
+
* Reply cannot wrap `reply`, `edit`, `reaction`, `group`, `typing`,
|
|
377
|
+
* `rename`, or `avatar` content.
|
|
378
378
|
*/
|
|
379
379
|
declare const replySchema: z__default.ZodObject<{
|
|
380
380
|
type: z__default.ZodLiteral<"reply">;
|
|
@@ -39,6 +39,78 @@ declare function background(input: string | Buffer | URL, options?: {
|
|
|
39
39
|
mimeType?: string;
|
|
40
40
|
}): ContentBuilder;
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Visible layout of a mini-app card. Mirrors Apple's
|
|
44
|
+
* `MSMessageTemplateLayout`. At least one of `caption`, `subcaption`,
|
|
45
|
+
* `trailingCaption`, `trailingSubcaption`, or `image` must be set so the
|
|
46
|
+
* bubble is not empty — `summary` is the fallback text shown on surfaces
|
|
47
|
+
* that cannot render the card (notifications, lock screen) and is not a
|
|
48
|
+
* visible slot on its own. `image` and `imageTitle` must be set together;
|
|
49
|
+
* `imageSubtitle` requires `image`.
|
|
50
|
+
*/
|
|
51
|
+
declare const layoutSchema: z__default.ZodObject<{
|
|
52
|
+
caption: z__default.ZodOptional<z__default.ZodString>;
|
|
53
|
+
subcaption: z__default.ZodOptional<z__default.ZodString>;
|
|
54
|
+
trailingCaption: z__default.ZodOptional<z__default.ZodString>;
|
|
55
|
+
trailingSubcaption: z__default.ZodOptional<z__default.ZodString>;
|
|
56
|
+
image: z__default.ZodOptional<z__default.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
|
|
57
|
+
imageTitle: z__default.ZodOptional<z__default.ZodString>;
|
|
58
|
+
imageSubtitle: z__default.ZodOptional<z__default.ZodString>;
|
|
59
|
+
summary: z__default.ZodOptional<z__default.ZodString>;
|
|
60
|
+
}, z__default.core.$strip>;
|
|
61
|
+
/**
|
|
62
|
+
* iMessage-only mini-app card content. Lives entirely under the iMessage
|
|
63
|
+
* provider — never enters the universal `Content` discriminated union. The
|
|
64
|
+
* framework recognizes it via the generic content-level platform contract:
|
|
65
|
+
*
|
|
66
|
+
* - `__platform: "iMessage"` — `findUnsupportedPlatformContent` reads this tag
|
|
67
|
+
* and warns-and-skips when a different platform receives it.
|
|
68
|
+
*
|
|
69
|
+
* Unlike `background` / `read`, this content is **not** `__fireAndForget`: it
|
|
70
|
+
* produces a real outbound message, so the iMessage `send` handler narrows
|
|
71
|
+
* back to `CustomizedMiniApp` via the `isCustomizedMiniApp` guard and returns
|
|
72
|
+
* the resulting `ProviderMessageRecord` (rather than `void`).
|
|
73
|
+
*/
|
|
74
|
+
declare const customizedMiniAppSchema: z__default.ZodObject<{
|
|
75
|
+
type: z__default.ZodLiteral<"customized-mini-app">;
|
|
76
|
+
__platform: z__default.ZodLiteral<"iMessage">;
|
|
77
|
+
appName: z__default.ZodString;
|
|
78
|
+
appStoreId: z__default.ZodOptional<z__default.ZodNumber>;
|
|
79
|
+
extensionBundleId: z__default.ZodString;
|
|
80
|
+
layout: z__default.ZodObject<{
|
|
81
|
+
caption: z__default.ZodOptional<z__default.ZodString>;
|
|
82
|
+
subcaption: z__default.ZodOptional<z__default.ZodString>;
|
|
83
|
+
trailingCaption: z__default.ZodOptional<z__default.ZodString>;
|
|
84
|
+
trailingSubcaption: z__default.ZodOptional<z__default.ZodString>;
|
|
85
|
+
image: z__default.ZodOptional<z__default.ZodCustom<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
|
|
86
|
+
imageTitle: z__default.ZodOptional<z__default.ZodString>;
|
|
87
|
+
imageSubtitle: z__default.ZodOptional<z__default.ZodString>;
|
|
88
|
+
summary: z__default.ZodOptional<z__default.ZodString>;
|
|
89
|
+
}, z__default.core.$strip>;
|
|
90
|
+
teamId: z__default.ZodString;
|
|
91
|
+
url: z__default.ZodURL;
|
|
92
|
+
}, z__default.core.$strip>;
|
|
93
|
+
type CustomizedMiniApp = z__default.infer<typeof customizedMiniAppSchema>;
|
|
94
|
+
type CustomizedMiniAppLayout = z__default.infer<typeof layoutSchema>;
|
|
95
|
+
type CustomizedMiniAppInput = Omit<CustomizedMiniApp, "type" | "__platform">;
|
|
96
|
+
/**
|
|
97
|
+
* Construct a `customized-mini-app` content value. iMessage-only, remote-only.
|
|
98
|
+
*
|
|
99
|
+
* The layout is what recipients see in the bubble. `teamId` and
|
|
100
|
+
* `extensionBundleId` identify the iMessage extension that receives `url` when
|
|
101
|
+
* the recipient taps the card; the server constructs the matching
|
|
102
|
+
* `MSMessageExtensionBalloonPlugin` plugin id from these values. `appStoreId`
|
|
103
|
+
* is optional and only points recipients without the extension at its App
|
|
104
|
+
* Store entry.
|
|
105
|
+
*
|
|
106
|
+
* `space.send(customizedMiniApp(...))` is the canonical form.
|
|
107
|
+
*
|
|
108
|
+
* `CustomizedMiniApp` is intentionally not a member of the universal `Content`
|
|
109
|
+
* union — the `as unknown as Content` cast keeps the builder shape compatible
|
|
110
|
+
* with the framework's `ContentBuilder.build(): Promise<Content>` signature.
|
|
111
|
+
*/
|
|
112
|
+
declare function customizedMiniApp(input: CustomizedMiniAppInput): ContentBuilder;
|
|
113
|
+
|
|
42
114
|
type IMessageMessageEffect = MessageEffect;
|
|
43
115
|
declare function effect(input: ContentInput, messageEffect: IMessageMessageEffect): ContentBuilder;
|
|
44
116
|
|
|
@@ -176,4 +248,4 @@ declare const imessage: Platform<PlatformDef<"iMessage", z.ZodUnion<readonly [z.
|
|
|
176
248
|
};
|
|
177
249
|
}>;
|
|
178
250
|
|
|
179
|
-
export { type BackgroundInput, type IMessageMessageEffect, background, effect, imessage, read };
|
|
251
|
+
export { type BackgroundInput, type CustomizedMiniApp, type CustomizedMiniAppInput, type CustomizedMiniAppLayout, type IMessageMessageEffect, background, customizedMiniApp, effect, imessage, read };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
background,
|
|
4
|
+
customizedMiniApp,
|
|
4
5
|
effect,
|
|
5
6
|
imessage,
|
|
6
7
|
read
|
|
7
|
-
} from "../../chunk-
|
|
8
|
+
} from "../../chunk-YN6WOTBF.js";
|
|
8
9
|
import "../../chunk-JQN6CRSC.js";
|
|
9
10
|
import "../../chunk-2D27WW5B.js";
|
|
10
11
|
import "../../chunk-MC6ZKFSG.js";
|
|
@@ -13,6 +14,7 @@ import "../../chunk-IPOFBAIM.js";
|
|
|
13
14
|
import "../../chunk-2ILTJC35.js";
|
|
14
15
|
export {
|
|
15
16
|
background,
|
|
17
|
+
customizedMiniApp,
|
|
16
18
|
effect,
|
|
17
19
|
imessage,
|
|
18
20
|
read
|
package/dist/providers/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
imessage
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-YN6WOTBF.js";
|
|
5
5
|
import "../chunk-JQN6CRSC.js";
|
|
6
6
|
import {
|
|
7
7
|
slack
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spectrum-ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "Bring agents to any interface — unified messaging SDK for TypeScript.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"./manifest.json": "./dist/manifest.json"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@photon-ai/advanced-imessage": "^0.
|
|
41
|
+
"@photon-ai/advanced-imessage": "^0.11.0",
|
|
42
42
|
"@photon-ai/imessage-kit": "^3.0.0",
|
|
43
43
|
"@photon-ai/otel": "^0.1.1",
|
|
44
44
|
"@photon-ai/slack": "^0.2.0",
|