@spectrum-ts/imessage 7.0.0 → 8.0.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/index.js +8 -49
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { MessageEffect, NotFoundError, ValidationError, createClient } from "@ph
|
|
|
2
2
|
import { IMessageSDK } from "@photon-ai/imessage-kit";
|
|
3
3
|
import { sanitizePhone, withSpan } from "@photon-ai/otel";
|
|
4
4
|
import { UnsupportedError, appLayoutSchema, cloud, definePlatform, fromVCard, mergeStreams, read, stream, text, toVCard } from "@spectrum-ts/core";
|
|
5
|
-
import { asAttachment, asContact, asCustom, asGroup, asPoll, asPollOption,
|
|
5
|
+
import { asAttachment, asContact, asCustom, asGroup, asPoll, asPollOption, asText, buildPhotoAction, createLogger, ensureM4a, errorAttrs, groupSchema, messageEffectSchema, photoActionSchema, reactionSchema, resumableOrderedStream, sanitizeErrorMessage } from "@spectrum-ts/core/authoring";
|
|
6
6
|
import z from "zod";
|
|
7
7
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
8
8
|
import { createReadStream } from "node:fs";
|
|
@@ -798,8 +798,6 @@ const getRemoteAttachment = async (client, guid) => {
|
|
|
798
798
|
//#endregion
|
|
799
799
|
//#region src/remote/inbound.ts
|
|
800
800
|
const log$2 = createLogger("spectrum.imessage.inbound");
|
|
801
|
-
const URL_BALLOON_BUNDLE_ID = "com.apple.messages.URLBalloonProvider";
|
|
802
|
-
const getBalloonBundleId = (message) => message.content.balloonBundleId;
|
|
803
801
|
const messageAttachments = (message) => message.content.attachments;
|
|
804
802
|
const resolveChatGuid = (message, hint) => {
|
|
805
803
|
if (hint) return hint;
|
|
@@ -870,26 +868,6 @@ const buildAttachmentMessage = async (client, base, info, id, partIndex, parentI
|
|
|
870
868
|
if (parentId !== void 0) msg.parentId = parentId;
|
|
871
869
|
return msg;
|
|
872
870
|
};
|
|
873
|
-
const toRichlinkMessage = (message, base, id) => {
|
|
874
|
-
const url = message.content.text ?? "";
|
|
875
|
-
try {
|
|
876
|
-
return {
|
|
877
|
-
...base,
|
|
878
|
-
id,
|
|
879
|
-
content: asRichlink({ url })
|
|
880
|
-
};
|
|
881
|
-
} catch (err) {
|
|
882
|
-
log$2.warn("failed to convert message to rich link; falling back to text/custom content", {
|
|
883
|
-
"spectrum.imessage.message.id": id,
|
|
884
|
-
...errorAttrs(err)
|
|
885
|
-
}, err);
|
|
886
|
-
return {
|
|
887
|
-
...base,
|
|
888
|
-
id,
|
|
889
|
-
content: url ? asText(url) : asCustom(message)
|
|
890
|
-
};
|
|
891
|
-
}
|
|
892
|
-
};
|
|
893
871
|
const rebuildFromAppleMessage = async (client, message, phone, chatGuidHint) => {
|
|
894
872
|
const messageGuidStr = message.guid;
|
|
895
873
|
const base = buildMessageBase(message, chatGuidHint, message.dateCreated ?? /* @__PURE__ */ new Date(), phone);
|
|
@@ -912,7 +890,6 @@ const rebuildFromAppleMessage = async (client, message, phone, chatGuidHint) =>
|
|
|
912
890
|
content: asProviderGroup(items)
|
|
913
891
|
};
|
|
914
892
|
}
|
|
915
|
-
if (getBalloonBundleId(message) === URL_BALLOON_BUNDLE_ID) return toRichlinkMessage(message, base, messageGuidStr);
|
|
916
893
|
const text = message.content.text;
|
|
917
894
|
return {
|
|
918
895
|
...base,
|
|
@@ -929,11 +906,6 @@ const cacheMessage = (cache, message) => {
|
|
|
929
906
|
const toInboundMessages = async (client, cache, event, phone) => {
|
|
930
907
|
const base = buildMessageBase(event.message, event.chatGuid, event.occurredAt, phone);
|
|
931
908
|
const messageGuidStr = event.message.guid;
|
|
932
|
-
if (getBalloonBundleId(event.message) === URL_BALLOON_BUNDLE_ID) {
|
|
933
|
-
const msg = toRichlinkMessage(event.message, base, messageGuidStr);
|
|
934
|
-
cacheMessage(cache, msg);
|
|
935
|
-
return [msg];
|
|
936
|
-
}
|
|
937
909
|
const attachments = messageAttachments(event.message);
|
|
938
910
|
if (attachments.length === 1) {
|
|
939
911
|
const info = attachments[0];
|
|
@@ -1137,10 +1109,6 @@ const withStyle = (spans, style) => spans.map((span) => span.styles.includes(sty
|
|
|
1137
1109
|
...span,
|
|
1138
1110
|
styles: [...span.styles, style]
|
|
1139
1111
|
});
|
|
1140
|
-
const asLink = (spans) => spans.map((span) => ({
|
|
1141
|
-
...span,
|
|
1142
|
-
link: true
|
|
1143
|
-
}));
|
|
1144
1112
|
const spanText = (spans) => {
|
|
1145
1113
|
let out = "";
|
|
1146
1114
|
for (const span of spans) out += span.text;
|
|
@@ -1184,19 +1152,16 @@ const listMarker = (list, index) => {
|
|
|
1184
1152
|
const renderLink = (token) => {
|
|
1185
1153
|
if (token.text === token.href) return [{
|
|
1186
1154
|
text: token.href,
|
|
1187
|
-
styles: []
|
|
1188
|
-
link: true
|
|
1155
|
+
styles: []
|
|
1189
1156
|
}];
|
|
1190
|
-
return [...
|
|
1157
|
+
return [...renderInlineTokens(token.tokens), {
|
|
1191
1158
|
text: ` (${token.href})`,
|
|
1192
|
-
styles: []
|
|
1193
|
-
link: true
|
|
1159
|
+
styles: []
|
|
1194
1160
|
}];
|
|
1195
1161
|
};
|
|
1196
1162
|
const renderImage = (token) => [{
|
|
1197
1163
|
text: token.text ? `${token.text} (${token.href})` : token.href,
|
|
1198
|
-
styles: []
|
|
1199
|
-
link: true
|
|
1164
|
+
styles: []
|
|
1200
1165
|
}];
|
|
1201
1166
|
const renderInlineToken = (token) => {
|
|
1202
1167
|
switch (token.type) {
|
|
@@ -1309,7 +1274,6 @@ const trimSpans = (spans) => {
|
|
|
1309
1274
|
};
|
|
1310
1275
|
const finalize = (spans) => {
|
|
1311
1276
|
let text = "";
|
|
1312
|
-
let hasLinks = false;
|
|
1313
1277
|
const open = /* @__PURE__ */ new Map();
|
|
1314
1278
|
const ranges = [];
|
|
1315
1279
|
const close = (style, end) => {
|
|
@@ -1323,7 +1287,6 @@ const finalize = (spans) => {
|
|
|
1323
1287
|
};
|
|
1324
1288
|
for (const span of spans) {
|
|
1325
1289
|
if (!span.text) continue;
|
|
1326
|
-
hasLinks ||= span.link === true;
|
|
1327
1290
|
const offset = text.length;
|
|
1328
1291
|
for (const style of STYLE_ORDER) if (span.styles.includes(style)) {
|
|
1329
1292
|
if (!open.has(style)) open.set(style, offset);
|
|
@@ -1334,8 +1297,7 @@ const finalize = (spans) => {
|
|
|
1334
1297
|
ranges.sort((a, b) => a.start - b.start || STYLE_ORDER.indexOf(a.type) - STYLE_ORDER.indexOf(b.type));
|
|
1335
1298
|
return {
|
|
1336
1299
|
text,
|
|
1337
|
-
formatting: ranges
|
|
1338
|
-
hasLinks
|
|
1300
|
+
formatting: ranges
|
|
1339
1301
|
};
|
|
1340
1302
|
};
|
|
1341
1303
|
/**
|
|
@@ -1345,8 +1307,7 @@ const finalize = (spans) => {
|
|
|
1345
1307
|
* bullets, `label (url)` links); inline emphasis becomes native
|
|
1346
1308
|
* bold/italic/strikethrough ranges instead of being stripped, headings
|
|
1347
1309
|
* render as bold, and code maps to Unicode mathematical monospace
|
|
1348
|
-
* characters.
|
|
1349
|
-
* the text, so the sender can enable Apple's data-detector pass.
|
|
1310
|
+
* characters.
|
|
1350
1311
|
*/
|
|
1351
1312
|
const markdownToIMessageText = (markdown) => finalize(trimSpans(renderBlockTokens(markdownLexer.lexer(markdown))));
|
|
1352
1313
|
//#endregion
|
|
@@ -1380,7 +1341,6 @@ const withReply = (options, replyTo) => replyTo ? {
|
|
|
1380
1341
|
const replyOptions = (replyTo) => replyTo ? { replyTo } : void 0;
|
|
1381
1342
|
const effectOption = (effect) => effect ? { effect } : {};
|
|
1382
1343
|
const formattingOption = (formatting) => formatting.length > 0 ? { formatting } : {};
|
|
1383
|
-
const dataDetectionOption = (hasLinks) => hasLinks ? { enableDataDetection: true } : {};
|
|
1384
1344
|
const renderMarkdown = (markdown) => {
|
|
1385
1345
|
const rendered = markdownToIMessageText(markdown);
|
|
1386
1346
|
if (!rendered.text) throw unsupportedRemoteContent("markdown", "renders to empty text — nothing to send");
|
|
@@ -1436,8 +1396,7 @@ const sendContent = async (remote, spaceId, chat, content, replyTo, effect) => {
|
|
|
1436
1396
|
const rendered = renderMarkdown(content.markdown);
|
|
1437
1397
|
return outboundMessage(spaceId, await remote.messages.sendText(chat, rendered.text, withReply({
|
|
1438
1398
|
...effectOption(effect),
|
|
1439
|
-
...formattingOption(rendered.formatting)
|
|
1440
|
-
...dataDetectionOption(rendered.hasLinks)
|
|
1399
|
+
...formattingOption(rendered.formatting)
|
|
1441
1400
|
}, replyTo)), content);
|
|
1442
1401
|
}
|
|
1443
1402
|
case "richlink": return outboundMessage(spaceId, await remote.messages.sendText(chat, content.url, withReply({ enableLinkPreview: true }, replyTo)), content);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-ts/imessage",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "iMessage provider for spectrum-ts — local and remote (advanced) modes.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"zod": "^4.2.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@spectrum-ts/core": "^
|
|
42
|
+
"@spectrum-ts/core": "^8.0.0",
|
|
43
43
|
"typescript": "^5 || ^6.0.0"
|
|
44
44
|
},
|
|
45
45
|
"license": "MIT"
|