@spectrum-ts/imessage 11.1.0 → 11.2.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.
Files changed (2) hide show
  1. package/dist/index.js +34 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { NotFoundError, ValidationError, createClient } from "@photon-ai/advanced-imessage";
2
2
  import { sanitizePhone, withSpan } from "@photon-ai/otel";
3
3
  import { UnsupportedError, appLayoutSchema, cloud, definePlatform, fromVCard, mergeStreams, read, text, toVCard } from "@spectrum-ts/core";
4
- import { addMemberSchema, asAttachment, asContact, asCustom, asGroup, asPoll, asPollOption, asReply, asText, avatarSchema, buildPhotoAction, createLogger, ensureM4a, errorAttrs, groupSchema, leaveSpaceSchema, messageEffectSchema, photoActionSchema, reactionSchema, removeMemberSchema, renameSchema, resumableOrderedStream, sanitizeErrorMessage } from "@spectrum-ts/core/authoring";
4
+ import { addMemberSchema, asAttachment, asContact, asCustom, asGroup, asPoll, asPollOption, asReply, asText, asVoice, avatarSchema, buildPhotoAction, createLogger, ensureM4a, errorAttrs, groupSchema, leaveSpaceSchema, messageEffectSchema, photoActionSchema, reactionSchema, removeMemberSchema, renameSchema, resumableOrderedStream, sanitizeErrorMessage } from "@spectrum-ts/core/authoring";
5
5
  import z from "zod";
6
6
  import { Marked } from "marked";
7
7
  import { LRUCache } from "lru-cache";
@@ -576,6 +576,18 @@ const sendCustomizedMiniApp$1 = async (remote, spaceId, content) => {
576
576
  const updateCustomizedMiniApp$1 = async (remote, spaceId, session, content) => {
577
577
  return toProviderRecord(await remote.messages.updateCustomizedMiniApp(session, content), content, spaceId);
578
578
  };
579
+ //#endregion
580
+ //#region src/shared/audio.ts
581
+ const AUDIO_MIME_PATTERN = /^audio\//i;
582
+ const CAF_MIME_TYPE = "audio/x-caf";
583
+ const CAF_UTI = "com.apple.coreaudio-format";
584
+ const GENERIC_BINARY_MIME_TYPE = "application/octet-stream";
585
+ const isCafAttachment = (attachment) => attachment.uti?.toLowerCase() === CAF_UTI || attachment.fileName?.toLowerCase().endsWith(".caf") === true;
586
+ const normalizeAppleAttachmentMimeType = (attachment) => attachment.mimeType.toLowerCase() === GENERIC_BINARY_MIME_TYPE && isCafAttachment(attachment) ? CAF_MIME_TYPE : attachment.mimeType;
587
+ const appleAudioMimeType = (attachment) => {
588
+ const mimeType = normalizeAppleAttachmentMimeType(attachment);
589
+ return AUDIO_MIME_PATTERN.test(mimeType) ? mimeType : void 0;
590
+ };
579
591
  const addTextPart = (parts, text) => {
580
592
  const trimmed = text?.trim();
581
593
  if (trimmed) parts.push({
@@ -707,7 +719,7 @@ const getRemoteAttachment = async (client, guid) => {
707
719
  return asAttachment({
708
720
  id: info.guid,
709
721
  name: info.fileName,
710
- mimeType: info.mimeType,
722
+ mimeType: normalizeAppleAttachmentMimeType(info),
711
723
  size: info.totalBytes,
712
724
  read: () => downloadPrimaryAttachment(client, info.guid),
713
725
  stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
@@ -762,7 +774,15 @@ const buildMessageBase = (message, chatGuidHint, timestamp, phone) => {
762
774
  const toAttachmentContent = (client, info) => asAttachment({
763
775
  id: info.guid,
764
776
  name: info.fileName,
765
- mimeType: info.mimeType,
777
+ mimeType: normalizeAppleAttachmentMimeType(info),
778
+ size: info.totalBytes,
779
+ read: async () => await downloadPrimaryAttachment(client, info.guid),
780
+ stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
781
+ });
782
+ const toVoiceContent = (client, info, mimeType) => asVoice({
783
+ id: info.guid,
784
+ name: info.fileName,
785
+ mimeType,
766
786
  size: info.totalBytes,
767
787
  read: async () => await downloadPrimaryAttachment(client, info.guid),
768
788
  stream: async () => downloadPrimaryAttachmentStream(client, info.guid)
@@ -778,9 +798,13 @@ const toVCardContent = async (client, info) => {
778
798
  return toAttachmentContent(client, info);
779
799
  }
780
800
  };
781
- const attachmentContent = async (client, info) => isVCardAttachment(info.mimeType, info.fileName) ? await toVCardContent(client, info) : toAttachmentContent(client, info);
782
- const buildAttachmentMessage = async (client, base, info, id, partIndex, parentId) => {
783
- const content = await attachmentContent(client, info);
801
+ const attachmentContent = async (client, info, isVoice) => {
802
+ if (isVCardAttachment(info.mimeType, info.fileName)) return await toVCardContent(client, info);
803
+ const audioMimeType = isVoice ? appleAudioMimeType(info) : void 0;
804
+ return audioMimeType ? toVoiceContent(client, info, audioMimeType) : toAttachmentContent(client, info);
805
+ };
806
+ const buildAttachmentMessage = async (client, base, info, id, partIndex, parentId, isVoice = false) => {
807
+ const content = await attachmentContent(client, info, isVoice);
784
808
  const msg = {
785
809
  ...base,
786
810
  id,
@@ -800,9 +824,10 @@ const buildTextMessage = (base, text, id, partIndex, parentId) => {
800
824
  if (parentId !== void 0) msg.parentId = parentId;
801
825
  return msg;
802
826
  };
803
- const buildOrderedPartMessage = async (client, base, part, id, partIndex, parentId) => part.type === "text" ? buildTextMessage(base, part.text, id, partIndex, parentId) : await buildAttachmentMessage(client, base, part.attachment, id, partIndex, parentId);
827
+ const buildOrderedPartMessage = async (client, base, part, id, partIndex, parentId, voiceAttachmentGuid) => part.type === "text" ? buildTextMessage(base, part.text, id, partIndex, parentId) : await buildAttachmentMessage(client, base, part.attachment, id, partIndex, parentId, part.attachment.guid === voiceAttachmentGuid);
804
828
  const buildUnwrappedContentMessage = async (client, base, message, messageGuidStr) => {
805
829
  const attachments = messageAttachments(message);
830
+ const voiceAttachmentGuid = message.isAudioMessage ? attachments.find((attachment) => appleAudioMimeType(attachment))?.guid : void 0;
806
831
  if (attachments.length === 0) {
807
832
  const text = message.content.text;
808
833
  return {
@@ -820,13 +845,13 @@ const buildUnwrappedContentMessage = async (client, base, message, messageGuidSt
820
845
  if (parts.length === 1) {
821
846
  const part = parts[0];
822
847
  if (!part) throw new Error("Unreachable: parts.length === 1 but no element");
823
- return buildOrderedPartMessage(client, base, part, messageGuidStr, 0);
848
+ return buildOrderedPartMessage(client, base, part, messageGuidStr, 0, void 0, voiceAttachmentGuid);
824
849
  }
825
850
  const items = [];
826
851
  for (let i = 0; i < parts.length; i++) {
827
852
  const part = parts[i];
828
853
  if (!part) continue;
829
- items.push(await buildOrderedPartMessage(client, base, part, formatChildId(i, messageGuidStr), i, messageGuidStr));
854
+ items.push(await buildOrderedPartMessage(client, base, part, formatChildId(i, messageGuidStr), i, messageGuidStr, voiceAttachmentGuid));
830
855
  }
831
856
  return {
832
857
  ...base,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-ts/imessage",
3
- "version": "11.1.0",
3
+ "version": "11.2.0",
4
4
  "description": "iMessage provider for spectrum-ts.",
5
5
  "repository": {
6
6
  "type": "git",