spectrum-ts 0.5.0 → 0.6.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.
@@ -0,0 +1,341 @@
1
+ // src/content/text.ts
2
+ import z from "zod";
3
+ var textSchema = z.object({
4
+ type: z.literal("text"),
5
+ text: z.string().nonempty()
6
+ });
7
+ var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
8
+ function text(text2) {
9
+ return {
10
+ build: async () => asText(text2)
11
+ };
12
+ }
13
+
14
+ // src/content/resolve.ts
15
+ var resolveContents = (items) => Promise.all(
16
+ items.map((c) => typeof c === "string" ? text(c).build() : c.build())
17
+ );
18
+
19
+ // src/platform/build.ts
20
+ function buildSpace(params) {
21
+ const { spaceRef, extras, typingCtx, definition, client, config } = params;
22
+ let space;
23
+ async function sendImpl(...content) {
24
+ const resolved = await resolveContents(content);
25
+ const results = [];
26
+ for (const item of resolved) {
27
+ const sendResult = await definition.actions.send({
28
+ ...typingCtx,
29
+ content: item
30
+ });
31
+ if (!sendResult?.id) {
32
+ throw new Error(
33
+ `Platform "${definition.name}" send did not return a message id`
34
+ );
35
+ }
36
+ results.push(
37
+ buildMessage({
38
+ id: sendResult.id,
39
+ content: item,
40
+ sender: sendResult.sender,
41
+ timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
42
+ extras: {},
43
+ spaceRef,
44
+ space,
45
+ definition,
46
+ client,
47
+ config,
48
+ direction: "outbound"
49
+ })
50
+ );
51
+ }
52
+ return content.length === 1 && results[0] ? results[0] : results;
53
+ }
54
+ space = {
55
+ ...extras,
56
+ ...spaceRef,
57
+ send: sendImpl,
58
+ edit: async (message, newContent) => {
59
+ await message.edit(newContent);
60
+ },
61
+ startTyping: async () => {
62
+ await definition.actions.startTyping?.(typingCtx);
63
+ },
64
+ stopTyping: async () => {
65
+ await definition.actions.stopTyping?.(typingCtx);
66
+ },
67
+ responding: async (fn) => {
68
+ await definition.actions.startTyping?.(typingCtx);
69
+ try {
70
+ return await fn();
71
+ } finally {
72
+ await definition.actions.stopTyping?.(typingCtx).catch(() => {
73
+ });
74
+ }
75
+ }
76
+ };
77
+ return space;
78
+ }
79
+ function buildMessage(params) {
80
+ const { definition, client, config, spaceRef, space } = params;
81
+ const react = async (reaction) => {
82
+ if (!definition.actions.reactToMessage) {
83
+ return;
84
+ }
85
+ await definition.actions.reactToMessage({
86
+ space: spaceRef,
87
+ messageId: params.id,
88
+ reaction,
89
+ client,
90
+ config
91
+ });
92
+ };
93
+ async function reply(...content) {
94
+ if (!definition.actions.replyToMessage) {
95
+ throw new Error(
96
+ `Platform "${definition.name}" does not support replying to messages`
97
+ );
98
+ }
99
+ const resolved = await resolveContents(content);
100
+ const results = [];
101
+ for (const item of resolved) {
102
+ const sendResult = await definition.actions.replyToMessage({
103
+ space: spaceRef,
104
+ messageId: params.id,
105
+ content: item,
106
+ client,
107
+ config
108
+ });
109
+ if (!sendResult?.id) {
110
+ throw new Error(
111
+ `Platform "${definition.name}" reply did not return a message id`
112
+ );
113
+ }
114
+ results.push(
115
+ buildMessage({
116
+ id: sendResult.id,
117
+ content: item,
118
+ sender: sendResult.sender,
119
+ timestamp: sendResult.timestamp ?? /* @__PURE__ */ new Date(),
120
+ extras: {},
121
+ spaceRef,
122
+ space,
123
+ definition,
124
+ client,
125
+ config,
126
+ direction: "outbound"
127
+ })
128
+ );
129
+ }
130
+ return content.length === 1 && results[0] ? results[0] : results;
131
+ }
132
+ const senderWithPlatform = params.sender === void 0 ? void 0 : { ...params.sender, __platform: definition.name };
133
+ if (params.direction === "outbound") {
134
+ return {
135
+ ...params.extras,
136
+ id: params.id,
137
+ content: params.content,
138
+ direction: "outbound",
139
+ platform: definition.name,
140
+ react,
141
+ reply,
142
+ edit: async (newContent) => {
143
+ if (!definition.actions.editMessage) {
144
+ throw new Error(
145
+ `Platform "${definition.name}" does not support editing messages`
146
+ );
147
+ }
148
+ const [resolved] = await resolveContents([newContent]);
149
+ if (!resolved) {
150
+ return;
151
+ }
152
+ await definition.actions.editMessage({
153
+ space: spaceRef,
154
+ messageId: params.id,
155
+ content: resolved,
156
+ client,
157
+ config
158
+ });
159
+ },
160
+ sender: senderWithPlatform,
161
+ space,
162
+ timestamp: params.timestamp
163
+ };
164
+ }
165
+ return {
166
+ ...params.extras,
167
+ id: params.id,
168
+ content: params.content,
169
+ direction: "inbound",
170
+ platform: definition.name,
171
+ react,
172
+ reply,
173
+ sender: senderWithPlatform,
174
+ space,
175
+ timestamp: params.timestamp
176
+ };
177
+ }
178
+
179
+ // src/platform/define.ts
180
+ function createPlatformInstance(def, runtime) {
181
+ const isPlatformUser = (value) => {
182
+ return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
183
+ };
184
+ const normalizeSpaceArgs = (args) => {
185
+ if (args.length === 0) {
186
+ return { users: [], params: void 0 };
187
+ }
188
+ const [first, ...rest] = args;
189
+ if (Array.isArray(first)) {
190
+ return {
191
+ users: first,
192
+ params: rest[0]
193
+ };
194
+ }
195
+ if (!isPlatformUser(first)) {
196
+ return {
197
+ users: [],
198
+ params: first
199
+ };
200
+ }
201
+ const last = args.at(-1);
202
+ if (last !== void 0 && !isPlatformUser(last)) {
203
+ return {
204
+ users: args.slice(0, -1),
205
+ params: last
206
+ };
207
+ }
208
+ return {
209
+ users: args,
210
+ params: void 0
211
+ };
212
+ };
213
+ const base = {
214
+ async user(userID) {
215
+ const resolved = await def.user.resolve({
216
+ input: { userID },
217
+ client: runtime.client,
218
+ config: runtime.config
219
+ });
220
+ return {
221
+ ...resolved,
222
+ __platform: def.name
223
+ };
224
+ },
225
+ async space(...args) {
226
+ const { users, params } = normalizeSpaceArgs(args);
227
+ let parsedParams = params;
228
+ if (params !== void 0 && def.space.params) {
229
+ parsedParams = def.space.params.parse(params);
230
+ }
231
+ const resolved = await def.space.resolve({
232
+ input: { users, params: parsedParams },
233
+ client: runtime.client,
234
+ config: runtime.config
235
+ });
236
+ const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
237
+ const spaceRef = {
238
+ id: parsedSpace.id,
239
+ __platform: def.name
240
+ };
241
+ const typingCtx = {
242
+ space: spaceRef,
243
+ client: runtime.client,
244
+ config: runtime.config
245
+ };
246
+ return buildSpace({
247
+ spaceRef,
248
+ extras: parsedSpace,
249
+ typingCtx,
250
+ definition: def,
251
+ client: runtime.client,
252
+ config: runtime.config
253
+ });
254
+ }
255
+ };
256
+ const eventProperties = {};
257
+ for (const eventName of Object.keys(def.events)) {
258
+ if (eventName === "messages") {
259
+ continue;
260
+ }
261
+ const producer = def.events[eventName];
262
+ if (producer) {
263
+ eventProperties[eventName] = producer({
264
+ client: runtime.client,
265
+ config: runtime.config
266
+ });
267
+ }
268
+ }
269
+ return Object.assign(base, eventProperties);
270
+ }
271
+ function definePlatform(name, def) {
272
+ const fullDef = { name, ...def };
273
+ const platformCache = /* @__PURE__ */ new WeakMap();
274
+ const narrowSpectrum = (spectrum) => {
275
+ const cached = platformCache.get(spectrum);
276
+ if (cached) {
277
+ return cached;
278
+ }
279
+ const runtime = spectrum.__internal.platforms.get(name);
280
+ if (!runtime) {
281
+ throw new Error(`Platform "${name}" is not registered`);
282
+ }
283
+ const instance = createPlatformInstance(
284
+ fullDef,
285
+ runtime
286
+ );
287
+ platformCache.set(spectrum, instance);
288
+ return instance;
289
+ };
290
+ const narrowSpace = (input) => {
291
+ if (input.__platform !== name) {
292
+ throw new Error(
293
+ `Expected space from "${name}", got "${input.__platform}"`
294
+ );
295
+ }
296
+ return input;
297
+ };
298
+ const narrowMessage = (input) => {
299
+ if (input.platform !== name) {
300
+ throw new Error(
301
+ `Expected message from "${name}", got "${input.platform}"`
302
+ );
303
+ }
304
+ return input;
305
+ };
306
+ const narrower = ((input) => {
307
+ if ("__providers" in input && "__internal" in input) {
308
+ return narrowSpectrum(input);
309
+ }
310
+ if ("__platform" in input && "send" in input) {
311
+ return narrowSpace(input);
312
+ }
313
+ if ("platform" in input && "sender" in input && "space" in input) {
314
+ return narrowMessage(input);
315
+ }
316
+ throw new Error("Invalid input to platform narrowing function");
317
+ });
318
+ narrower.config = (config) => {
319
+ const resolvedConfig = config ?? {};
320
+ return {
321
+ __tag: "PlatformProviderConfig",
322
+ __def: void 0,
323
+ __name: name,
324
+ config: resolvedConfig,
325
+ __definition: fullDef
326
+ };
327
+ };
328
+ if (def.static) {
329
+ Object.assign(narrower, def.static);
330
+ }
331
+ return narrower;
332
+ }
333
+
334
+ export {
335
+ asText,
336
+ text,
337
+ resolveContents,
338
+ buildSpace,
339
+ buildMessage,
340
+ definePlatform
341
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ContentBuilder, U as User, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, M as Message } from './types-CfiD_00g.js';
2
- export { A as AnyPlatformDef, E as EventProducer, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage } from './types-CfiD_00g.js';
1
+ import { C as ContentBuilder, U as User, a as ContentInput, b as Content, P as ProviderMessage, c as PlatformDef, d as Platform, e as PlatformProviderConfig, S as SpectrumLike, f as CustomEventStreams, g as Space, I as InboundMessage, O as OutboundMessage } from './types-DZMHfgYQ.js';
2
+ export { A as AnyPlatformDef, E as EventProducer, M as Message, h as PlatformInstance, i as PlatformMessage, j as PlatformSpace, k as PlatformUser, l as SchemaMessage } from './types-DZMHfgYQ.js';
3
3
  import vCard from 'vcf';
4
4
  import z__default from 'zod';
5
5
  export { M as ManagedStream, m as mergeStreams, s as stream } from './stream-DGy4geUK.js';
@@ -161,9 +161,11 @@ declare function definePlatform<_Name extends string, _ConfigSchema extends z__d
161
161
  }): Platform<PlatformDef<_Name, _ConfigSchema, _UserSchema, _SpaceSchema, _SpaceParamsSchema, _Client, _ResolvedUser, _ResolvedSpace, _MessageSchema, _MessageType, _Events>> & Readonly<_Static>;
162
162
 
163
163
  type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProviderConfig[]> = SpectrumLike<Providers> & CustomEventStreams<Providers> & {
164
- readonly messages: AsyncIterable<[Space, Message]>;
164
+ readonly messages: AsyncIterable<[Space, InboundMessage]>;
165
165
  stop(): Promise<void>;
166
- send(space: Space, ...content: [ContentInput, ...ContentInput[]]): Promise<void>;
166
+ send(space: Space, content: ContentInput): Promise<OutboundMessage>;
167
+ send(space: Space, ...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage[]>;
168
+ edit(message: OutboundMessage, newContent: ContentInput): Promise<void>;
167
169
  responding<T>(space: Space, fn: () => T | Promise<T>): Promise<T>;
168
170
  };
169
171
  declare function Spectrum<const Providers extends PlatformProviderConfig[]>(options: {
@@ -216,4 +218,4 @@ declare const cloud: {
216
218
  declare const fromVCard: (vcf: string) => ContactInput;
217
219
  declare const toVCard: (contact: Contact) => Promise<string>;
218
220
 
219
- export { type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type ImessageInfoData, Message, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, User, type Voice, attachment, cloud, contact, custom, definePlatform, fromVCard, resolveContents, text, toVCard, voice };
221
+ export { type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, Content, ContentBuilder, ContentInput, type DedicatedTokenData, type ImessageInfoData, Platform, PlatformDef, PlatformProviderConfig, type PlatformStatus, type PlatformsData, type SharedTokenData, Space, Spectrum, SpectrumCloudError, type SpectrumInstance, type SubscriptionData, type SubscriptionStatus, type TokenData, User, type Voice, attachment, cloud, contact, custom, definePlatform, fromVCard, resolveContents, text, toVCard, voice };
package/dist/index.js CHANGED
@@ -15,10 +15,12 @@ import {
15
15
  toVCard
16
16
  } from "./chunk-UZWRB3FZ.js";
17
17
  import {
18
+ buildMessage,
19
+ buildSpace,
18
20
  definePlatform,
19
21
  resolveContents,
20
22
  text
21
- } from "./chunk-XEEDIGVK.js";
23
+ } from "./chunk-XZTTLPHE.js";
22
24
 
23
25
  // src/content/voice.ts
24
26
  import { createReadStream } from "fs";
@@ -207,72 +209,27 @@ async function Spectrum(options) {
207
209
  __platform: definition.name
208
210
  };
209
211
  const typingCtx = { space: spaceRef, client, config };
210
- const space = {
211
- ...spaceRef,
212
- send: async (...content) => {
213
- const resolved = await resolveContents(content);
214
- for (const item of resolved) {
215
- await definition.actions.send({
216
- ...typingCtx,
217
- content: item
218
- });
219
- }
220
- },
221
- startTyping: async () => {
222
- await definition.actions.startTyping?.(typingCtx);
223
- },
224
- stopTyping: async () => {
225
- await definition.actions.stopTyping?.(typingCtx);
226
- },
227
- responding: async (fn) => {
228
- await definition.actions.startTyping?.(typingCtx);
229
- try {
230
- return await fn();
231
- } finally {
232
- await definition.actions.stopTyping?.(typingCtx).catch(() => {
233
- });
234
- }
235
- }
236
- };
237
- const normalizedMessage = {
238
- ...parsedExtra,
212
+ const space = buildSpace({
213
+ spaceRef,
214
+ extras: {},
215
+ typingCtx,
216
+ definition,
217
+ client,
218
+ config
219
+ });
220
+ const normalizedMessage = buildMessage({
239
221
  id: msg.id,
240
222
  content: msg.content,
241
- platform: definition.name,
242
- react: async (reaction) => {
243
- if (!definition.actions.reactToMessage) {
244
- return;
245
- }
246
- await definition.actions.reactToMessage({
247
- space: spaceRef,
248
- messageId: msg.id,
249
- reaction,
250
- client,
251
- config
252
- });
253
- },
254
- reply: async (...content) => {
255
- if (!definition.actions.replyToMessage) {
256
- return;
257
- }
258
- const resolved = await resolveContents(content);
259
- for (const item of resolved) {
260
- await definition.actions.replyToMessage({
261
- space: spaceRef,
262
- messageId: msg.id,
263
- content: item,
264
- client,
265
- config
266
- });
267
- }
268
- },
269
- sender: {
270
- ...msg.sender,
271
- __platform: definition.name
272
- },
223
+ sender: msg.sender,
224
+ timestamp: msg.timestamp ?? /* @__PURE__ */ new Date(),
225
+ extras: parsedExtra,
226
+ spaceRef,
273
227
  space,
274
- timestamp: msg.timestamp ?? /* @__PURE__ */ new Date()
275
- };
228
+ definition,
229
+ client,
230
+ config,
231
+ direction: "inbound"
232
+ });
276
233
  yield [space, normalizedMessage];
277
234
  }
278
235
  };
@@ -383,8 +340,13 @@ async function Spectrum(options) {
383
340
  __internal: { platforms: platformStates },
384
341
  messages,
385
342
  stop: stopOnce,
386
- send: async (space, ...content) => {
387
- await space.send(...content);
343
+ send: (async (space, ...content) => {
344
+ return content.length === 1 ? await space.send(content[0]) : await space.send(
345
+ ...content
346
+ );
347
+ }),
348
+ edit: async (message, newContent) => {
349
+ await message.edit(newContent);
388
350
  },
389
351
  responding: async (space, fn) => {
390
352
  return space.responding(fn);
@@ -3,7 +3,7 @@ import { AdvancedIMessage } from '@photon-ai/advanced-imessage';
3
3
  import { IMessageSDK } from '@photon-ai/imessage-kit';
4
4
  import * as z from 'zod';
5
5
  import z__default from 'zod';
6
- import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-CfiD_00g.js';
6
+ import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
7
7
  import * as zod_v4_core from 'zod/v4/core';
8
8
  import 'hotscript';
9
9
 
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  asText,
15
15
  definePlatform
16
- } from "../../chunk-XEEDIGVK.js";
16
+ } from "../../chunk-XZTTLPHE.js";
17
17
 
18
18
  // src/providers/imessage/index.ts
19
19
  import { createClient as createClient2, directChat } from "@photon-ai/advanced-imessage";
@@ -114,6 +114,14 @@ import { Readable } from "stream";
114
114
  import {
115
115
  readAttachmentBytes
116
116
  } from "@photon-ai/imessage-kit";
117
+ var toSendResult = (result) => {
118
+ if (!result.message?.id) {
119
+ throw new Error(
120
+ "iMessage local send did not return a message id \u2014 track upstream in @photon-ai/imessage-kit"
121
+ );
122
+ }
123
+ return { id: result.message.id, timestamp: result.sentAt };
124
+ };
117
125
  var DEFAULT_ATTACHMENT_NAME = "attachment";
118
126
  var VCARD_MIME_TYPES = /* @__PURE__ */ new Set([
119
127
  "text/vcard",
@@ -180,6 +188,9 @@ var messages = (client) => stream((emit, end) => {
180
188
  let lastPromise = Promise.resolve();
181
189
  client.startWatching({
182
190
  onMessage: (message) => {
191
+ if (message.isFromMe) {
192
+ return;
193
+ }
183
194
  lastPromise = lastPromise.then(() => toMessages(message)).then((ms) => {
184
195
  for (const m of ms) {
185
196
  emit(m);
@@ -199,7 +210,7 @@ var sendTempFile = async (client, spaceId, name, data) => {
199
210
  const tmp = join(dir, safeName);
200
211
  await writeFile(tmp, data);
201
212
  try {
202
- await client.send(spaceId, { attachments: [tmp] });
213
+ return await client.send(spaceId, { attachments: [tmp] });
203
214
  } finally {
204
215
  await rm(dir, { recursive: true, force: true }).catch(() => {
205
216
  });
@@ -208,23 +219,26 @@ var sendTempFile = async (client, spaceId, name, data) => {
208
219
  var send = async (client, spaceId, content) => {
209
220
  switch (content.type) {
210
221
  case "text":
211
- await client.send(spaceId, content.text);
212
- break;
222
+ return toSendResult(await client.send(spaceId, content.text));
213
223
  case "attachment":
214
- await sendTempFile(client, spaceId, content.name, await content.read());
215
- break;
224
+ return toSendResult(
225
+ await sendTempFile(client, spaceId, content.name, await content.read())
226
+ );
216
227
  case "contact": {
217
228
  const vcf = await toVCard(content);
218
- await sendTempFile(
219
- client,
220
- spaceId,
221
- vcardFileName(content),
222
- Buffer.from(vcf, "utf8")
229
+ return toSendResult(
230
+ await sendTempFile(
231
+ client,
232
+ spaceId,
233
+ vcardFileName(content),
234
+ Buffer.from(vcf, "utf8")
235
+ )
223
236
  );
224
- break;
225
237
  }
226
238
  default:
227
- break;
239
+ throw new Error(
240
+ `Unsupported iMessage local content type: ${content.type}`
241
+ );
228
242
  }
229
243
  };
230
244
 
@@ -359,6 +373,10 @@ var ensureM4a = async (buffer, mimeType) => {
359
373
  };
360
374
 
361
375
  // src/providers/imessage/remote.ts
376
+ var toSendResult2 = (receipt) => ({
377
+ id: receipt.guid,
378
+ timestamp: /* @__PURE__ */ new Date()
379
+ });
362
380
  var VCARD_MIME_TYPES2 = /* @__PURE__ */ new Set([
363
381
  "text/vcard",
364
382
  "text/x-vcard",
@@ -425,6 +443,9 @@ var clientStream = (client) => {
425
443
  (async () => {
426
444
  try {
427
445
  for await (const event of sub) {
446
+ if (event.message.isFromMe) {
447
+ continue;
448
+ }
428
449
  for (const message of await toMessages2(client, event)) {
429
450
  emit(message);
430
451
  }
@@ -469,27 +490,27 @@ var stopTyping = async (clients, spaceId) => {
469
490
  var send2 = async (clients, spaceId, content) => {
470
491
  const remote = clients[0];
471
492
  if (!remote) {
472
- return;
493
+ throw new Error("No remote iMessage client available");
473
494
  }
495
+ const chat = chatGuid(spaceId);
474
496
  switch (content.type) {
475
497
  case "text":
476
- await remote.messages.send(chatGuid(spaceId), content.text);
477
- break;
498
+ return toSendResult2(await remote.messages.send(chat, content.text));
478
499
  case "attachment": {
479
500
  const attachment = await remote.attachments.upload({
480
501
  data: await content.read(),
481
502
  fileName: content.name,
482
503
  mimeType: content.mimeType
483
504
  });
484
- await remote.messages.send(chatGuid(spaceId), "", {
485
- attachment: attachment.guid
486
- });
487
- break;
505
+ return toSendResult2(
506
+ await remote.messages.send(chat, "", {
507
+ attachment: attachment.guid
508
+ })
509
+ );
488
510
  }
489
511
  case "contact": {
490
512
  const attachment = await sendContactAttachment(remote, content);
491
- await remote.messages.send(chatGuid(spaceId), "", { attachment });
492
- break;
513
+ return toSendResult2(await remote.messages.send(chat, "", { attachment }));
493
514
  }
494
515
  case "voice": {
495
516
  const { buffer } = await ensureM4a(
@@ -501,11 +522,12 @@ var send2 = async (clients, spaceId, content) => {
501
522
  fileName: content.name ?? "voice.m4a",
502
523
  mimeType: "audio/x-m4a"
503
524
  });
504
- await remote.messages.send(chatGuid(spaceId), "", {
505
- attachment: attachment.guid,
506
- audioMessage: true
507
- });
508
- break;
525
+ return toSendResult2(
526
+ await remote.messages.send(chat, "", {
527
+ attachment: attachment.guid,
528
+ audioMessage: true
529
+ })
530
+ );
509
531
  }
510
532
  default:
511
533
  throw new Error(`Unsupported iMessage content type: ${content.type}`);
@@ -514,30 +536,33 @@ var send2 = async (clients, spaceId, content) => {
514
536
  var replyToMessage = async (clients, spaceId, msgId, content) => {
515
537
  const remote = clients[0];
516
538
  if (!remote) {
517
- return;
539
+ throw new Error("No remote iMessage client available");
518
540
  }
519
541
  const chat = chatGuid(spaceId);
520
542
  const replyTo = messageGuid(msgId);
521
543
  switch (content.type) {
522
544
  case "text":
523
- await remote.messages.send(chat, content.text, { replyTo });
524
- break;
545
+ return toSendResult2(
546
+ await remote.messages.send(chat, content.text, { replyTo })
547
+ );
525
548
  case "attachment": {
526
549
  const attachment = await remote.attachments.upload({
527
550
  data: await content.read(),
528
551
  fileName: content.name,
529
552
  mimeType: content.mimeType
530
553
  });
531
- await remote.messages.send(chat, "", {
532
- attachment: attachment.guid,
533
- replyTo
534
- });
535
- break;
554
+ return toSendResult2(
555
+ await remote.messages.send(chat, "", {
556
+ attachment: attachment.guid,
557
+ replyTo
558
+ })
559
+ );
536
560
  }
537
561
  case "contact": {
538
562
  const attachment = await sendContactAttachment(remote, content);
539
- await remote.messages.send(chat, "", { attachment, replyTo });
540
- break;
563
+ return toSendResult2(
564
+ await remote.messages.send(chat, "", { attachment, replyTo })
565
+ );
541
566
  }
542
567
  case "voice": {
543
568
  const { buffer } = await ensureM4a(
@@ -549,17 +574,32 @@ var replyToMessage = async (clients, spaceId, msgId, content) => {
549
574
  fileName: content.name ?? "voice.m4a",
550
575
  mimeType: "audio/x-m4a"
551
576
  });
552
- await remote.messages.send(chat, "", {
553
- attachment: attachment.guid,
554
- audioMessage: true,
555
- replyTo
556
- });
557
- break;
577
+ return toSendResult2(
578
+ await remote.messages.send(chat, "", {
579
+ attachment: attachment.guid,
580
+ audioMessage: true,
581
+ replyTo
582
+ })
583
+ );
558
584
  }
559
585
  default:
560
586
  throw new Error(`Unsupported iMessage content type: ${content.type}`);
561
587
  }
562
588
  };
589
+ var editMessage = async (clients, spaceId, msgId, content) => {
590
+ if (content.type !== "text") {
591
+ throw new Error("iMessage only supports editing text content");
592
+ }
593
+ const remote = clients[0];
594
+ if (!remote) {
595
+ throw new Error("No remote iMessage client available");
596
+ }
597
+ await remote.messages.edit(
598
+ chatGuid(spaceId),
599
+ messageGuid(msgId),
600
+ content.text
601
+ );
602
+ };
563
603
  var reactToMessage = async (clients, spaceId, msgId, reaction) => {
564
604
  const remote = clients[0];
565
605
  if (!remote) {
@@ -671,10 +711,9 @@ var imessage = definePlatform("iMessage", {
671
711
  actions: {
672
712
  send: async ({ space, content, client }) => {
673
713
  if (isLocal(client)) {
674
- await send(client, space.id, content);
675
- } else {
676
- await send2(client, space.id, content);
714
+ return await send(client, space.id, content);
677
715
  }
716
+ return await send2(client, space.id, content);
678
717
  },
679
718
  startTyping: async ({ space, client }) => {
680
719
  if (isLocal(client)) {
@@ -696,9 +735,19 @@ var imessage = definePlatform("iMessage", {
696
735
  },
697
736
  replyToMessage: async ({ space, messageId, content, client }) => {
698
737
  if (isLocal(client)) {
699
- return;
738
+ throw new Error(
739
+ "iMessage local mode does not support replying to messages"
740
+ );
741
+ }
742
+ return await replyToMessage(client, space.id, messageId, content);
743
+ },
744
+ editMessage: async ({ space, messageId, content, client }) => {
745
+ if (isLocal(client)) {
746
+ throw new Error(
747
+ "iMessage local mode does not support editing messages"
748
+ );
700
749
  }
701
- await replyToMessage(client, space.id, messageId, content);
750
+ await editMessage(client, space.id, messageId, content);
702
751
  }
703
752
  }
704
753
  });
@@ -1,4 +1,4 @@
1
- import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-CfiD_00g.js';
1
+ import { d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
2
2
  import * as node_readline from 'node:readline';
3
3
  import z__default from 'zod';
4
4
  import 'hotscript';
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  definePlatform
3
- } from "../../chunk-XEEDIGVK.js";
3
+ } from "../../chunk-XZTTLPHE.js";
4
4
 
5
5
  // src/providers/terminal/index.ts
6
6
  import { createInterface } from "readline";
@@ -49,9 +49,13 @@ var terminal = definePlatform("terminal", {
49
49
  },
50
50
  actions: {
51
51
  send: async ({ content }) => {
52
- if (content.type === "text") {
53
- console.log(content.text);
52
+ if (content.type !== "text") {
53
+ throw new Error(
54
+ `Terminal provider only supports text content, got "${content.type}"`
55
+ );
54
56
  }
57
+ console.log(content.text);
58
+ return { id: crypto.randomUUID(), timestamp: /* @__PURE__ */ new Date() };
55
59
  }
56
60
  }
57
61
  });
@@ -1,7 +1,7 @@
1
1
  import { M as ManagedStream } from '../../stream-DGy4geUK.js';
2
2
  import * as z from 'zod';
3
3
  import z__default from 'zod';
4
- import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-CfiD_00g.js';
4
+ import { l as SchemaMessage, d as Platform, c as PlatformDef, P as ProviderMessage } from '../../types-DZMHfgYQ.js';
5
5
  import * as zod_v4_core from 'zod/v4/core';
6
6
  import { WhatsAppClient } from '@photon-ai/whatsapp-business';
7
7
  import 'hotscript';
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  asText,
9
9
  definePlatform
10
- } from "../../chunk-XEEDIGVK.js";
10
+ } from "../../chunk-XZTTLPHE.js";
11
11
 
12
12
  // src/providers/whatsapp-business/index.ts
13
13
  import {
@@ -16,6 +16,9 @@ import {
16
16
 
17
17
  // src/providers/whatsapp-business/messages.ts
18
18
  import { extension as mimeExtension } from "mime-types";
19
+ var toSendResult = (result) => ({
20
+ id: result.messageId
21
+ });
19
22
  var mapWaPhoneType = (type) => {
20
23
  if (!type) {
21
24
  return void 0;
@@ -311,8 +314,9 @@ var messages = (client) => {
311
314
  var send = async (client, spaceId, content) => {
312
315
  switch (content.type) {
313
316
  case "text":
314
- await client.messages.send({ to: spaceId, text: content.text });
315
- break;
317
+ return toSendResult(
318
+ await client.messages.send({ to: spaceId, text: content.text })
319
+ );
316
320
  case "attachment": {
317
321
  const { mediaId } = await client.media.upload({
318
322
  file: await content.read(),
@@ -321,32 +325,35 @@ var send = async (client, spaceId, content) => {
321
325
  });
322
326
  const mediaType = mimeToMediaType(content.mimeType);
323
327
  const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
324
- await client.messages.send({
325
- to: spaceId,
326
- [mediaType]: mediaPayload
327
- });
328
- break;
328
+ return toSendResult(
329
+ await client.messages.send({
330
+ to: spaceId,
331
+ [mediaType]: mediaPayload
332
+ })
333
+ );
329
334
  }
330
335
  case "contact":
331
- await client.messages.send({
332
- to: spaceId,
333
- contacts: [contactToWa(content)]
334
- });
335
- break;
336
+ return toSendResult(
337
+ await client.messages.send({
338
+ to: spaceId,
339
+ contacts: [contactToWa(content)]
340
+ })
341
+ );
336
342
  case "voice": {
337
343
  const { mediaId } = await client.media.upload({
338
344
  file: await content.read(),
339
345
  mimeType: content.mimeType,
340
346
  filename: voiceFilename(content)
341
347
  });
342
- await client.messages.send({
343
- to: spaceId,
344
- audio: { id: mediaId }
345
- });
346
- break;
348
+ return toSendResult(
349
+ await client.messages.send({
350
+ to: spaceId,
351
+ audio: { id: mediaId }
352
+ })
353
+ );
347
354
  }
348
355
  default:
349
- break;
356
+ throw new Error(`Unsupported WhatsApp content type: ${content.type}`);
350
357
  }
351
358
  };
352
359
  var reactToMessage = async (client, spaceId, messageId, reaction) => {
@@ -358,12 +365,13 @@ var reactToMessage = async (client, spaceId, messageId, reaction) => {
358
365
  var replyToMessage = async (client, spaceId, messageId, content) => {
359
366
  switch (content.type) {
360
367
  case "text":
361
- await client.messages.send({
362
- to: spaceId,
363
- replyTo: messageId,
364
- text: content.text
365
- });
366
- break;
368
+ return toSendResult(
369
+ await client.messages.send({
370
+ to: spaceId,
371
+ replyTo: messageId,
372
+ text: content.text
373
+ })
374
+ );
367
375
  case "attachment": {
368
376
  const { mediaId } = await client.media.upload({
369
377
  file: await content.read(),
@@ -372,35 +380,38 @@ var replyToMessage = async (client, spaceId, messageId, content) => {
372
380
  });
373
381
  const mediaType = mimeToMediaType(content.mimeType);
374
382
  const mediaPayload = mediaType === "document" ? { id: mediaId, filename: content.name } : { id: mediaId };
375
- await client.messages.send({
376
- to: spaceId,
377
- replyTo: messageId,
378
- [mediaType]: mediaPayload
379
- });
380
- break;
383
+ return toSendResult(
384
+ await client.messages.send({
385
+ to: spaceId,
386
+ replyTo: messageId,
387
+ [mediaType]: mediaPayload
388
+ })
389
+ );
381
390
  }
382
391
  case "contact":
383
- await client.messages.send({
384
- to: spaceId,
385
- replyTo: messageId,
386
- contacts: [contactToWa(content)]
387
- });
388
- break;
392
+ return toSendResult(
393
+ await client.messages.send({
394
+ to: spaceId,
395
+ replyTo: messageId,
396
+ contacts: [contactToWa(content)]
397
+ })
398
+ );
389
399
  case "voice": {
390
400
  const { mediaId } = await client.media.upload({
391
401
  file: await content.read(),
392
402
  mimeType: content.mimeType,
393
403
  filename: voiceFilename(content)
394
404
  });
395
- await client.messages.send({
396
- to: spaceId,
397
- replyTo: messageId,
398
- audio: { id: mediaId }
399
- });
400
- break;
405
+ return toSendResult(
406
+ await client.messages.send({
407
+ to: spaceId,
408
+ replyTo: messageId,
409
+ audio: { id: mediaId }
410
+ })
411
+ );
401
412
  }
402
413
  default:
403
- break;
414
+ throw new Error(`Unsupported WhatsApp content type: ${content.type}`);
404
415
  }
405
416
  };
406
417
 
@@ -457,7 +468,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
457
468
  },
458
469
  actions: {
459
470
  send: async ({ space, content, client }) => {
460
- await send(client, space.id, content);
471
+ return await send(client, space.id, content);
461
472
  },
462
473
  reactToMessage: async ({ space, messageId, reaction, client }) => {
463
474
  await reactToMessage(
@@ -468,7 +479,7 @@ var whatsappBusiness = definePlatform("WhatsApp Business", {
468
479
  );
469
480
  },
470
481
  replyToMessage: async ({ space, messageId, content, client }) => {
471
- await replyToMessage(
482
+ return await replyToMessage(
472
483
  client,
473
484
  space.id,
474
485
  messageId,
@@ -92,23 +92,35 @@ interface User {
92
92
 
93
93
  interface Space<_Def = unknown> {
94
94
  readonly __platform: string;
95
+ edit(message: OutboundMessage, newContent: ContentInput): Promise<void>;
95
96
  readonly id: string;
96
97
  responding<T>(fn: () => T | Promise<T>): Promise<T>;
97
- send(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
98
+ send(content: ContentInput): Promise<OutboundMessage>;
99
+ send(...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage[]>;
98
100
  startTyping(): Promise<void>;
99
101
  stopTyping(): Promise<void>;
100
102
  }
101
103
 
102
- interface Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
104
+ interface BaseMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> {
103
105
  content: Content;
104
106
  readonly id: string;
105
107
  platform: TPlatform;
106
108
  react(reaction: string): Promise<void>;
107
- reply(...content: [ContentInput, ...ContentInput[]]): Promise<void>;
108
- sender: TSender;
109
+ reply(content: ContentInput): Promise<OutboundMessage<TPlatform, TSender, TSpace>>;
110
+ reply(...content: [ContentInput, ContentInput, ...ContentInput[]]): Promise<OutboundMessage<TPlatform, TSender, TSpace>[]>;
109
111
  space: TSpace;
110
112
  timestamp: Date;
111
113
  }
114
+ interface InboundMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> extends BaseMessage<TPlatform, TSender, TSpace> {
115
+ direction: "inbound";
116
+ sender: TSender;
117
+ }
118
+ interface OutboundMessage<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> extends BaseMessage<TPlatform, TSender, TSpace> {
119
+ direction: "outbound";
120
+ edit(newContent: ContentInput): Promise<void>;
121
+ sender: TSender | undefined;
122
+ }
123
+ type Message<TPlatform extends string = string, TSender extends User = User, TSpace extends Space = Space> = InboundMessage<TPlatform, TSender, TSpace> | OutboundMessage<TPlatform, TSender, TSpace>;
112
124
 
113
125
  type ResolvedSpace = Pick<Space, "id">;
114
126
  type SpaceRef = Pick<Space, "id" | "__platform">;
@@ -131,6 +143,11 @@ type ProviderMessage<TSender extends ResolvedUser = ResolvedUser, TSpace extends
131
143
  space: TSpace;
132
144
  timestamp?: Date;
133
145
  } & TExtra;
146
+ interface SendResult<TSender extends ResolvedUser = ResolvedUser> {
147
+ id: string;
148
+ sender?: TSender;
149
+ timestamp?: Date;
150
+ }
134
151
  type MergeSchema<TSchema extends z__default.ZodType | undefined, TBase extends object> = TSchema extends z__default.ZodType ? string extends keyof z__default.infer<TSchema> ? TBase : Omit<z__default.infer<TSchema>, keyof TBase> & TBase : TBase;
135
152
  type SchemaMessage<TUserSchema extends z__default.ZodType | undefined = undefined, TSpaceSchema extends z__default.ZodType | undefined = undefined> = ProviderMessage<MergeSchema<TUserSchema, ResolvedUser>, MergeSchema<TSpaceSchema, ResolvedSpace>>;
136
153
  type InferEventPayload<T> = T extends (ctx: never) => AsyncIterable<infer P> ? P : never;
@@ -146,7 +163,7 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
146
163
  content: Content;
147
164
  client: _Client;
148
165
  config: z__default.infer<_ConfigSchema>;
149
- }) => Promise<void>;
166
+ }) => Promise<SendResult<_ResolvedUser>>;
150
167
  startTyping?: (_: {
151
168
  space: _ResolvedSpace & SpaceRef;
152
169
  client: _Client;
@@ -170,6 +187,13 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
170
187
  content: Content;
171
188
  client: _Client;
172
189
  config: z__default.infer<_ConfigSchema>;
190
+ }) => Promise<SendResult<_ResolvedUser>>;
191
+ editMessage?: (_: {
192
+ space: _ResolvedSpace & SpaceRef;
193
+ messageId: string;
194
+ content: Content;
195
+ client: _Client;
196
+ config: z__default.infer<_ConfigSchema>;
173
197
  }) => Promise<void>;
174
198
  };
175
199
  config: _ConfigSchema;
@@ -215,11 +239,12 @@ interface PlatformDef<_Name extends string = string, _ConfigSchema extends z__de
215
239
  }
216
240
  interface AnyPlatformDef {
217
241
  actions: {
218
- send: (_: any) => Promise<void>;
242
+ send: (_: any) => Promise<SendResult>;
219
243
  startTyping?: (_: any) => Promise<void>;
220
244
  stopTyping?: (_: any) => Promise<void>;
221
245
  reactToMessage?: (_: any) => Promise<void>;
222
- replyToMessage?: (_: any) => Promise<void>;
246
+ replyToMessage?: (_: any) => Promise<SendResult>;
247
+ editMessage?: (_: any) => Promise<void>;
223
248
  };
224
249
  config: z__default.ZodType<object>;
225
250
  events: {
@@ -318,4 +343,4 @@ interface Platform<Def extends AnyPlatformDef> {
318
343
  (message: Message): PlatformMessage<Def>;
319
344
  }
320
345
 
321
- 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 };
346
+ export type { AnyPlatformDef as A, ContentBuilder as C, EventProducer as E, InboundMessage as I, Message as M, OutboundMessage as O, 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,6 +1,6 @@
1
1
  {
2
2
  "name": "spectrum-ts",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -1,199 +0,0 @@
1
- // src/content/text.ts
2
- import z from "zod";
3
- var textSchema = z.object({
4
- type: z.literal("text"),
5
- text: z.string().nonempty()
6
- });
7
- var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
8
- function text(text2) {
9
- return {
10
- build: async () => asText(text2)
11
- };
12
- }
13
-
14
- // src/content/resolve.ts
15
- var resolveContents = (items) => Promise.all(
16
- items.map((c) => typeof c === "string" ? text(c).build() : c.build())
17
- );
18
-
19
- // src/platform/define.ts
20
- function createPlatformInstance(def, runtime) {
21
- const isPlatformUser = (value) => {
22
- return typeof value === "object" && value !== null && "__platform" in value && value.__platform === def.name;
23
- };
24
- const normalizeSpaceArgs = (args) => {
25
- if (args.length === 0) {
26
- return { users: [], params: void 0 };
27
- }
28
- const [first, ...rest] = args;
29
- if (Array.isArray(first)) {
30
- return {
31
- users: first,
32
- params: rest[0]
33
- };
34
- }
35
- if (!isPlatformUser(first)) {
36
- return {
37
- users: [],
38
- params: first
39
- };
40
- }
41
- const last = args.at(-1);
42
- if (last !== void 0 && !isPlatformUser(last)) {
43
- return {
44
- users: args.slice(0, -1),
45
- params: last
46
- };
47
- }
48
- return {
49
- users: args,
50
- params: void 0
51
- };
52
- };
53
- const base = {
54
- async user(userID) {
55
- const resolved = await def.user.resolve({
56
- input: { userID },
57
- client: runtime.client,
58
- config: runtime.config
59
- });
60
- return {
61
- ...resolved,
62
- __platform: def.name
63
- };
64
- },
65
- async space(...args) {
66
- const { users, params } = normalizeSpaceArgs(args);
67
- let parsedParams = params;
68
- if (params !== void 0 && def.space.params) {
69
- parsedParams = def.space.params.parse(params);
70
- }
71
- const resolved = await def.space.resolve({
72
- input: { users, params: parsedParams },
73
- client: runtime.client,
74
- config: runtime.config
75
- });
76
- const parsedSpace = def.space.schema ? def.space.schema.parse(resolved) : resolved;
77
- const spaceRef = {
78
- id: parsedSpace.id,
79
- __platform: def.name
80
- };
81
- const typingCtx = {
82
- space: spaceRef,
83
- client: runtime.client,
84
- config: runtime.config
85
- };
86
- return {
87
- ...parsedSpace,
88
- ...spaceRef,
89
- send: async (...content) => {
90
- const built = await resolveContents(content);
91
- for (const item of built) {
92
- await def.actions.send({
93
- ...typingCtx,
94
- content: item
95
- });
96
- }
97
- },
98
- startTyping: async () => {
99
- await def.actions.startTyping?.(typingCtx);
100
- },
101
- stopTyping: async () => {
102
- await def.actions.stopTyping?.(typingCtx);
103
- },
104
- responding: async (fn) => {
105
- await def.actions.startTyping?.(typingCtx);
106
- try {
107
- return await fn();
108
- } finally {
109
- await def.actions.stopTyping?.(typingCtx).catch(() => {
110
- });
111
- }
112
- }
113
- };
114
- }
115
- };
116
- const eventProperties = {};
117
- for (const eventName of Object.keys(def.events)) {
118
- if (eventName === "messages") {
119
- continue;
120
- }
121
- const producer = def.events[eventName];
122
- if (producer) {
123
- eventProperties[eventName] = producer({
124
- client: runtime.client,
125
- config: runtime.config
126
- });
127
- }
128
- }
129
- return Object.assign(base, eventProperties);
130
- }
131
- function definePlatform(name, def) {
132
- const fullDef = { name, ...def };
133
- const platformCache = /* @__PURE__ */ new WeakMap();
134
- const narrowSpectrum = (spectrum) => {
135
- const cached = platformCache.get(spectrum);
136
- if (cached) {
137
- return cached;
138
- }
139
- const runtime = spectrum.__internal.platforms.get(name);
140
- if (!runtime) {
141
- throw new Error(`Platform "${name}" is not registered`);
142
- }
143
- const instance = createPlatformInstance(
144
- fullDef,
145
- runtime
146
- );
147
- platformCache.set(spectrum, instance);
148
- return instance;
149
- };
150
- const narrowSpace = (input) => {
151
- if (input.__platform !== name) {
152
- throw new Error(
153
- `Expected space from "${name}", got "${input.__platform}"`
154
- );
155
- }
156
- return input;
157
- };
158
- const narrowMessage = (input) => {
159
- if (input.platform !== name) {
160
- throw new Error(
161
- `Expected message from "${name}", got "${input.platform}"`
162
- );
163
- }
164
- return input;
165
- };
166
- const narrower = ((input) => {
167
- if ("__providers" in input && "__internal" in input) {
168
- return narrowSpectrum(input);
169
- }
170
- if ("__platform" in input && "send" in input) {
171
- return narrowSpace(input);
172
- }
173
- if ("platform" in input && "sender" in input && "space" in input) {
174
- return narrowMessage(input);
175
- }
176
- throw new Error("Invalid input to platform narrowing function");
177
- });
178
- narrower.config = (config) => {
179
- const resolvedConfig = config ?? {};
180
- return {
181
- __tag: "PlatformProviderConfig",
182
- __def: void 0,
183
- __name: name,
184
- config: resolvedConfig,
185
- __definition: fullDef
186
- };
187
- };
188
- if (def.static) {
189
- Object.assign(narrower, def.static);
190
- }
191
- return narrower;
192
- }
193
-
194
- export {
195
- asText,
196
- text,
197
- resolveContents,
198
- definePlatform
199
- };