spectrum-ts 1.3.0 → 1.4.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.
@@ -78,6 +78,39 @@ function effect(input, messageEffect) {
78
78
 
79
79
  // src/providers/imessage/auth.ts
80
80
  import { createClient } from "@photon-ai/advanced-imessage";
81
+
82
+ // src/providers/imessage/types.ts
83
+ import { IMessageSDK } from "@photon-ai/imessage-kit";
84
+ import z2 from "zod";
85
+ var SHARED_PHONE = "shared";
86
+ var isLocal = (client) => client instanceof IMessageSDK;
87
+ var clientEntry = z2.object({
88
+ address: z2.string(),
89
+ token: z2.string(),
90
+ phone: z2.string()
91
+ });
92
+ var configSchema = z2.union([
93
+ z2.object({ local: z2.literal(true) }),
94
+ z2.object({
95
+ local: z2.literal(false).optional().default(false),
96
+ clients: clientEntry.or(z2.array(clientEntry)).optional()
97
+ })
98
+ ]);
99
+ var userSchema = z2.object({});
100
+ var spaceSchema = z2.object({
101
+ id: z2.string(),
102
+ type: z2.enum(["dm", "group"]),
103
+ phone: z2.string()
104
+ });
105
+ var spaceParamsSchema = z2.object({
106
+ phone: z2.string().optional()
107
+ });
108
+ var messageSchema = z2.object({
109
+ partIndex: z2.number().int().nonnegative().optional(),
110
+ parentId: z2.string().optional()
111
+ });
112
+
113
+ // src/providers/imessage/auth.ts
81
114
  var RENEWAL_RATIO = 0.8;
82
115
  var EXPIRY_BUFFER_MS = 3e4;
83
116
  var RETRY_DELAY_MS = 3e4;
@@ -94,13 +127,6 @@ async function createCloudClients(projectId, projectSecret) {
94
127
  let tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
95
128
  let disposed = false;
96
129
  let renewalTimer;
97
- if (tokenData.type === "shared") {
98
- throw UnsupportedError.action(
99
- "multi-phone",
100
- "iMessage shared mode",
101
- "use dedicated-token cloud mode"
102
- );
103
- }
104
130
  const records = [];
105
131
  const syncPhones = (data) => {
106
132
  for (const { entry, instanceId } of records) {
@@ -116,15 +142,10 @@ async function createCloudClients(projectId, projectSecret) {
116
142
  renewalTimer = setTimeout(async () => {
117
143
  try {
118
144
  tokenData = await cloud.issueImessageTokens(projectId, projectSecret);
119
- if (tokenData.type === "shared") {
120
- throw UnsupportedError.action(
121
- "multi-phone",
122
- "iMessage shared mode",
123
- "use dedicated-token cloud mode"
124
- );
125
- }
126
145
  tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
127
- syncPhones(tokenData);
146
+ if (tokenData.type === "dedicated") {
147
+ syncPhones(tokenData);
148
+ }
128
149
  scheduleRenewal();
129
150
  } catch {
130
151
  renewalTimer = setTimeout(() => scheduleRenewal(), RETRY_DELAY_MS);
@@ -139,17 +160,38 @@ async function createCloudClients(projectId, projectSecret) {
139
160
  return;
140
161
  }
141
162
  tokenData = await cloud.issueImessageTokens(projectId, projectSecret);
142
- if (tokenData.type === "shared") {
143
- throw UnsupportedError.action(
144
- "multi-phone",
145
- "iMessage shared mode",
146
- "use dedicated-token cloud mode"
147
- );
148
- }
149
163
  tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
150
- syncPhones(tokenData);
164
+ if (tokenData.type === "dedicated") {
165
+ syncPhones(tokenData);
166
+ }
151
167
  scheduleRenewal();
152
168
  };
169
+ if (tokenData.type === "shared") {
170
+ const address = process.env.SPECTRUM_IMESSAGE_ADDRESS ?? "imessage.spectrum.photon.codes:443";
171
+ const entries2 = [
172
+ {
173
+ phone: SHARED_PHONE,
174
+ client: createClient({
175
+ address,
176
+ tls: true,
177
+ token: async () => {
178
+ await refreshIfNeeded();
179
+ return tokenData.token;
180
+ }
181
+ })
182
+ }
183
+ ];
184
+ cloudAuthState.set(entries2, {
185
+ dispose: () => {
186
+ disposed = true;
187
+ if (renewalTimer !== void 0) {
188
+ clearTimeout(renewalTimer);
189
+ renewalTimer = void 0;
190
+ }
191
+ }
192
+ });
193
+ return entries2;
194
+ }
153
195
  const dedicated = tokenData;
154
196
  for (const [instanceId, token] of Object.entries(dedicated.auth)) {
155
197
  const entry = {
@@ -1865,8 +1907,16 @@ var reactToMessage2 = async (remote, spaceId, target, reaction) => {
1865
1907
  var getMessage4 = async (remote, spaceId, msgId, phone) => getMessage3(remote, spaceId, msgId, phone);
1866
1908
 
1867
1909
  // src/providers/imessage/remote/client.ts
1910
+ var isSharedMode = (clients) => clients.length === 1 && clients[0]?.phone === SHARED_PHONE;
1868
1911
  var availablePhones = (clients) => clients.map((c) => c.phone);
1869
1912
  var clientForPhone = (clients, phone) => {
1913
+ if (isSharedMode(clients)) {
1914
+ const entry2 = clients[0];
1915
+ if (!entry2) {
1916
+ throw new Error("No iMessage clients configured");
1917
+ }
1918
+ return entry2.client;
1919
+ }
1870
1920
  const entry = clients.find((c) => c.phone === phone);
1871
1921
  if (!entry) {
1872
1922
  const list = availablePhones(clients).join(", ") || "<none>";
@@ -1880,6 +1930,9 @@ var randomPhone = (clients) => {
1880
1930
  if (clients.length === 0) {
1881
1931
  throw new Error("No iMessage phones configured for this account");
1882
1932
  }
1933
+ if (isSharedMode(clients)) {
1934
+ return SHARED_PHONE;
1935
+ }
1883
1936
  const entry = clients[Math.floor(Math.random() * clients.length)];
1884
1937
  if (!entry) {
1885
1938
  throw new Error("No iMessage phones configured for this account");
@@ -1887,36 +1940,6 @@ var randomPhone = (clients) => {
1887
1940
  return entry.phone;
1888
1941
  };
1889
1942
 
1890
- // src/providers/imessage/types.ts
1891
- import { IMessageSDK } from "@photon-ai/imessage-kit";
1892
- import z2 from "zod";
1893
- var isLocal = (client) => client instanceof IMessageSDK;
1894
- var clientEntry = z2.object({
1895
- address: z2.string(),
1896
- token: z2.string(),
1897
- phone: z2.string()
1898
- });
1899
- var configSchema = z2.union([
1900
- z2.object({ local: z2.literal(true) }),
1901
- z2.object({
1902
- local: z2.literal(false).optional().default(false),
1903
- clients: clientEntry.or(z2.array(clientEntry)).optional()
1904
- })
1905
- ]);
1906
- var userSchema = z2.object({});
1907
- var spaceSchema = z2.object({
1908
- id: z2.string(),
1909
- type: z2.enum(["dm", "group"]),
1910
- phone: z2.string()
1911
- });
1912
- var spaceParamsSchema = z2.object({
1913
- phone: z2.string().optional()
1914
- });
1915
- var messageSchema = z2.object({
1916
- partIndex: z2.number().int().nonnegative().optional(),
1917
- parentId: z2.string().optional()
1918
- });
1919
-
1920
1943
  // src/providers/imessage/index.ts
1921
1944
  var isPollContent = (content) => content.type === "poll" || content.type === "poll_option";
1922
1945
  var imessage = definePlatform("iMessage", {
@@ -1982,7 +2005,7 @@ var imessage = definePlatform("iMessage", {
1982
2005
  if (client.length === 0) {
1983
2006
  throw new Error("No iMessage clients configured");
1984
2007
  }
1985
- const phone = input.params?.phone ?? randomPhone(client);
2008
+ const phone = isSharedMode(client) ? SHARED_PHONE : input.params?.phone ?? randomPhone(client);
1986
2009
  const remote = clientForPhone(client, phone);
1987
2010
  const addresses = input.users.map((u) => u.id);
1988
2011
  if (input.users.length === 1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",