imessage-sdk 0.1.0-beta.1 → 0.1.1
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/README.md +14 -11
- package/dist/index.d.ts +8 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,13 +9,10 @@ provider dependencies they use.
|
|
|
9
9
|
|
|
10
10
|
The package is ESM-only and ships JavaScript plus TypeScript declarations.
|
|
11
11
|
|
|
12
|
-
> This is a beta release. Install the prerelease with `pnpm add
|
|
13
|
-
imessage-sdk@beta` while the public API is being validated.
|
|
14
|
-
|
|
15
12
|
## Install
|
|
16
13
|
|
|
17
14
|
```bash
|
|
18
|
-
pnpm add imessage-sdk
|
|
15
|
+
pnpm add imessage-sdk @imessage-sdk/blooio
|
|
19
16
|
```
|
|
20
17
|
|
|
21
18
|
## Creating a client
|
|
@@ -327,6 +324,10 @@ construction, while stream providers connect lazily when subscribed.
|
|
|
327
324
|
`client.close()` is always available and idempotent. It is a no-op when the
|
|
328
325
|
provider has no cleanup and releases resources for stream or local transports.
|
|
329
326
|
|
|
327
|
+
All available normalized v0.1 operations are stable except webhook handling.
|
|
328
|
+
`client.webhooks`, `ProviderWebhooks`, and webhook event normalization are
|
|
329
|
+
marked experimental and may change incompatibly during the 0.1 release line.
|
|
330
|
+
|
|
330
331
|
## Blooio operations
|
|
331
332
|
|
|
332
333
|
The v0.1 Blooio adapter supports text and public URL attachments, inline
|
|
@@ -347,9 +348,9 @@ await client.typing.stop(sent.conversationId);
|
|
|
347
348
|
await client.conversations.markRead(sent.conversationId);
|
|
348
349
|
```
|
|
349
350
|
|
|
350
|
-
|
|
351
|
-
array because one provider delivery can represent zero, one, or
|
|
352
|
-
normalized events:
|
|
351
|
+
Experimental webhook handling verifies `X-Blooio-Signature` before parsing and
|
|
352
|
+
returns an array because one provider delivery can represent zero, one, or
|
|
353
|
+
multiple normalized events:
|
|
353
354
|
|
|
354
355
|
```ts
|
|
355
356
|
const events = await client.webhooks.handle(request);
|
|
@@ -448,12 +449,14 @@ within 60 seconds:
|
|
|
448
449
|
pnpm --filter @imessage-sdk/photon test:integration:stream
|
|
449
450
|
```
|
|
450
451
|
|
|
451
|
-
## v0.1
|
|
452
|
+
## v0.1 scope and stability
|
|
452
453
|
|
|
453
454
|
The initial model includes text, URL/blob/byte attachments, thread replies,
|
|
454
|
-
direct conversations, statuses, reactions, typing,
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
direct conversations, statuses, reactions, typing, typed capabilities, and
|
|
456
|
+
typed errors. These available normalized operations are stable. Webhook
|
|
457
|
+
verification and normalized webhook events remain experimental. Photon streams
|
|
458
|
+
and both providers' group implementations remain experimental provider-level
|
|
459
|
+
APIs.
|
|
457
460
|
|
|
458
461
|
It intentionally excludes FaceTime, polls, location sharing, contacts, message
|
|
459
462
|
effects, scheduling, provisioning, and automatic provider fallback.
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ interface IMessageCapabilities {
|
|
|
21
21
|
readonly readReceipts: boolean;
|
|
22
22
|
};
|
|
23
23
|
readonly events: {
|
|
24
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
24
25
|
readonly webhooks: boolean;
|
|
25
26
|
readonly stream: boolean;
|
|
26
27
|
};
|
|
@@ -289,6 +290,11 @@ interface ProviderTyping {
|
|
|
289
290
|
start(conversationId: string): Promise<void>;
|
|
290
291
|
stop?(conversationId: string): Promise<void>;
|
|
291
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Provider webhook verification and normalization contract.
|
|
295
|
+
*
|
|
296
|
+
* @experimental Webhook normalization may change before a future stable release.
|
|
297
|
+
*/
|
|
292
298
|
interface ProviderWebhooks {
|
|
293
299
|
verify(request: Request): Promise<boolean>;
|
|
294
300
|
parse(request: Request): Promise<readonly ProviderEvent[]>;
|
|
@@ -309,6 +315,7 @@ interface IMessageProvider<TName extends IMessageProviderName = IMessageProvider
|
|
|
309
315
|
readonly conversations: ProviderConversations;
|
|
310
316
|
readonly reactions?: ProviderReactions;
|
|
311
317
|
readonly typing?: ProviderTyping;
|
|
318
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
312
319
|
readonly webhooks?: ProviderWebhooks;
|
|
313
320
|
readonly events?: ProviderEvents;
|
|
314
321
|
close?(): Promise<void>;
|
|
@@ -349,6 +356,7 @@ interface IMessageClient<TProvider extends AnyIMessageProvider = AnyIMessageProv
|
|
|
349
356
|
start(conversationId: string): Promise<void>;
|
|
350
357
|
stop(conversationId: string): Promise<void>;
|
|
351
358
|
};
|
|
359
|
+
/** @experimental Webhook normalization may change before a future stable release. */
|
|
352
360
|
readonly webhooks: {
|
|
353
361
|
handle(request: Request): Promise<readonly IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>[]>;
|
|
354
362
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/conversation-id.ts","../src/core/errors.ts","../src/core/client.ts","../src/core/provider.ts"],"names":["options"],"mappings":"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","file":"index.js","sourcesContent":["const FALLBACK_CONVERSATION_ID_PREFIX = 'imsg-sdk-v1-';\n\ninterface FallbackConversationIdPayload {\n readonly message: string;\n readonly timestamp: string;\n}\n\n/**\n * Creates a diagnostic fallback when a provider message omits its native\n * conversation ID. Fallback IDs are stable for the same message and timestamp,\n * but are not provider-routable conversation handles.\n */\nexport function createFallbackConversationId(message: string, timestamp: Date): string {\n if (message.length === 0) {\n throw new TypeError('Fallback conversation message must not be empty.');\n }\n if (Number.isNaN(timestamp.getTime())) {\n throw new TypeError('Fallback conversation timestamp must be valid.');\n }\n\n const payload: FallbackConversationIdPayload = {\n message,\n timestamp: timestamp.toISOString(),\n };\n const encoded = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64url');\n return `${FALLBACK_CONVERSATION_ID_PREFIX}${encoded}`;\n}\n\nexport function isFallbackConversationId(value: string): boolean {\n return value.startsWith(FALLBACK_CONVERSATION_ID_PREFIX);\n}\n","export interface IMessageSDKErrorOptions {\n readonly provider?: string;\n readonly connectionId?: string;\n readonly code?: string;\n readonly statusCode?: number;\n readonly retryable?: boolean;\n readonly retryAfter?: number;\n readonly traceId?: string;\n readonly raw?: unknown;\n}\n\nexport class IMessageSDKError extends Error {\n readonly provider: string | undefined;\n readonly connectionId: string | undefined;\n readonly code: string | undefined;\n readonly statusCode: number | undefined;\n readonly retryable: boolean;\n readonly retryAfter: number | undefined;\n readonly traceId: string | undefined;\n readonly raw: unknown;\n\n constructor(message: string, options: IMessageSDKErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.provider = options.provider;\n this.connectionId = options.connectionId;\n this.code = options.code;\n this.statusCode = options.statusCode;\n this.retryable = options.retryable ?? false;\n this.retryAfter = options.retryAfter;\n this.traceId = options.traceId;\n this.raw = options.raw;\n }\n}\n\nexport class ValidationError extends IMessageSDKError {}\n\nexport class AuthenticationError extends IMessageSDKError {}\n\nexport class NotFoundError extends IMessageSDKError {}\n\nexport class ConflictError extends IMessageSDKError {}\n\nexport class RateLimitError extends IMessageSDKError {}\n\nexport class ProviderUnavailableError extends IMessageSDKError {}\n\n/** A send may have reached the provider, so blindly retrying could duplicate it. */\nexport class AmbiguousDeliveryError extends IMessageSDKError {}\n\nexport class UnsupportedCapabilityError extends IMessageSDKError {\n readonly capability: string;\n\n constructor(\n capability: string,\n options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {},\n ) {\n super(`The selected provider does not support ${capability}.`, {\n ...options,\n code: 'unsupported_capability',\n });\n this.capability = capability;\n }\n}\n\nexport class WebhookVerificationError extends IMessageSDKError {\n constructor(options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {}) {\n super('Webhook signature verification failed.', {\n ...options,\n code: 'webhook_verification_failed',\n });\n }\n}\n\nexport class ClientClosedError extends IMessageSDKError {\n constructor(options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {}) {\n super('This iMessage client has already been closed.', {\n ...options,\n code: 'client_closed',\n });\n }\n}\n","import type { IMessageEvent, ProviderEvent } from './events.js';\nimport type { AnyIMessageProvider } from './provider.js';\nimport type {\n AddReactionInput,\n Conversation,\n EditMessageInput,\n IMessageProviderName,\n Message,\n MessageLocator,\n OpenConversationInput,\n ProviderConversation,\n ProviderMessage,\n RemoveReactionInput,\n SendMessageInput,\n SentMessage,\n SubscribeOptions,\n} from './types.js';\nimport { createFallbackConversationId, isFallbackConversationId } from './conversation-id.js';\nimport {\n ClientClosedError,\n UnsupportedCapabilityError,\n ValidationError,\n WebhookVerificationError,\n} from './errors.js';\n\ntype ProviderNameOf<TProvider extends AnyIMessageProvider> = TProvider['name'];\n\nexport const DEFAULT_CONNECTION_ID = 'default' as const;\n\nexport type ClientProvider<TProvider extends AnyIMessageProvider> = TProvider;\n\nexport type ClientProviders<TProvider extends AnyIMessageProvider> = {\n readonly [TName in TProvider['name']]: ClientProvider<\n Extract<TProvider, { readonly name: TName }>\n >;\n};\n\nexport interface IMessageClient<\n TProvider extends AnyIMessageProvider = AnyIMessageProvider,\n TConnectionId extends string = string,\n> {\n readonly provider: ProviderNameOf<TProvider>;\n readonly connectionId: TConnectionId;\n readonly capabilities: TProvider['capabilities'];\n readonly providers: ClientProviders<TProvider>;\n\n readonly messages: {\n send(input: SendMessageInput): Promise<SentMessage<ProviderNameOf<TProvider>, TConnectionId>>;\n get(message: MessageLocator): Promise<Message<ProviderNameOf<TProvider>, TConnectionId> | null>;\n edit(\n message: MessageLocator,\n input: EditMessageInput,\n ): Promise<Message<ProviderNameOf<TProvider>, TConnectionId>>;\n delete(message: MessageLocator): Promise<void>;\n };\n\n readonly conversations: {\n open(\n input: OpenConversationInput,\n ): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId>>;\n get(\n conversationId: string,\n ): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId> | null>;\n markRead(conversationId: string): Promise<void>;\n };\n\n readonly reactions: {\n add(input: AddReactionInput): Promise<void>;\n remove(input: RemoveReactionInput): Promise<void>;\n };\n\n readonly typing: {\n start(conversationId: string): Promise<void>;\n stop(conversationId: string): Promise<void>;\n };\n\n readonly webhooks: {\n handle(\n request: Request,\n ): Promise<readonly IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>[]>;\n };\n\n readonly events: {\n subscribe(\n options?: SubscribeOptions,\n ): AsyncIterable<IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>>;\n };\n\n close(): Promise<void>;\n}\n\nexport interface CreateIMessageClientOptions<\n TProvider extends AnyIMessageProvider,\n TConnectionId extends string = typeof DEFAULT_CONNECTION_ID,\n> {\n readonly connectionId?: TConnectionId;\n readonly provider: TProvider;\n}\n\nfunction validateProvider(provider: AnyIMessageProvider): void {\n const capabilities = provider.capabilities;\n\n const requirements: readonly [boolean, unknown, string][] = [\n [capabilities.messages.get, provider.messages.get, 'messages.get'],\n [capabilities.messages.edit, provider.messages.edit, 'messages.edit'],\n [capabilities.messages.delete, provider.messages.delete, 'messages.delete'],\n [capabilities.conversations.get, provider.conversations.get, 'conversations.get'],\n [\n capabilities.conversations.markRead,\n provider.conversations.markRead,\n 'conversations.markRead',\n ],\n [capabilities.interactions.reactions, provider.reactions, 'reactions'],\n [capabilities.interactions.typingStart, provider.typing, 'typing.start'],\n [capabilities.interactions.typingStop, provider.typing?.stop, 'typing.stop'],\n [capabilities.events.webhooks, provider.webhooks, 'webhooks'],\n [capabilities.events.stream, provider.events, 'events.subscribe'],\n ];\n\n for (const [enabled, implementation, capability] of requirements) {\n if (enabled && implementation === undefined) {\n throw new ValidationError(\n `Provider ${provider.name} declares ${capability} but does not implement it.`,\n { provider: provider.name, code: 'invalid_provider_contract' },\n );\n }\n }\n}\n\nfunction decorateMessage<TProvider extends IMessageProviderName, TConnectionId extends string>(\n message: ProviderMessage,\n provider: TProvider,\n connectionId: TConnectionId,\n): Message<TProvider, TConnectionId> {\n return {\n ...message,\n id: message.providerMessageId,\n conversationId:\n message.conversationId ??\n createFallbackConversationId(message.providerMessageId, message.createdAt),\n provider,\n connectionId,\n };\n}\n\nfunction decorateConversation<TProvider extends IMessageProviderName, TConnectionId extends string>(\n conversation: ProviderConversation,\n provider: TProvider,\n connectionId: TConnectionId,\n): Conversation<TProvider, TConnectionId> {\n return {\n ...conversation,\n id: conversation.providerConversationId,\n provider,\n connectionId,\n };\n}\n\nfunction decorateEvent<TProvider extends IMessageProviderName, TConnectionId extends string>(\n event: ProviderEvent,\n provider: TProvider,\n connectionId: TConnectionId,\n): IMessageEvent<TProvider, TConnectionId> {\n switch (event.type) {\n case 'message.received':\n case 'message.sent':\n case 'message.delivered':\n case 'message.read':\n case 'message.failed':\n case 'message.edited':\n return {\n ...event,\n provider,\n connectionId,\n message: decorateMessage(event.message, provider, connectionId),\n };\n case 'message.deleted':\n case 'reaction.added':\n case 'reaction.removed':\n case 'typing.started':\n case 'typing.stopped':\n return { ...event, provider, connectionId };\n }\n}\n\nfunction mapEvents<TProvider extends IMessageProviderName, TConnectionId extends string>(\n events: AsyncIterable<ProviderEvent>,\n provider: TProvider,\n connectionId: TConnectionId,\n): AsyncIterable<IMessageEvent<TProvider, TConnectionId>> {\n return {\n async *[Symbol.asyncIterator]() {\n for await (const event of events) {\n yield decorateEvent(event, provider, connectionId);\n }\n },\n };\n}\n\nexport function createIMessageClient<\n const TProvider extends AnyIMessageProvider,\n const TConnectionId extends string = typeof DEFAULT_CONNECTION_ID,\n>(\n options: CreateIMessageClientOptions<TProvider, TConnectionId>,\n): IMessageClient<TProvider, TConnectionId> {\n const { provider } = options;\n const connectionId = (options.connectionId ?? DEFAULT_CONNECTION_ID) as TConnectionId;\n\n if (connectionId.trim().length === 0) {\n throw new ValidationError('connectionId must not be empty.', {\n provider: provider.name,\n code: 'invalid_connection_id',\n });\n }\n\n validateProvider(provider);\n\n let closed = false;\n let closePromise: Promise<void> | undefined;\n\n const errorContext = {\n provider: provider.name,\n connectionId,\n } as const;\n\n const assertOpen = (): void => {\n if (closed) {\n throw new ClientClosedError(errorContext);\n }\n };\n\n const unsupported = (capability: string): never => {\n throw new UnsupportedCapabilityError(capability, errorContext);\n };\n\n const assertRoutableConversationId = (conversationId: string): void => {\n if (isFallbackConversationId(conversationId)) {\n throw new ValidationError(\n 'SDK fallback conversation IDs are diagnostic and cannot be used for provider operations.',\n { ...errorContext, code: 'non_routable_conversation_id' },\n );\n }\n };\n\n const requireImplementation = <T>(implementation: T | undefined, capability: string): T => {\n if (implementation === undefined) {\n throw new UnsupportedCapabilityError(capability, errorContext);\n }\n\n return implementation;\n };\n\n const providers = Object.freeze({\n [provider.name]: provider,\n }) as ClientProviders<TProvider>;\n\n return {\n provider: provider.name,\n connectionId,\n capabilities: provider.capabilities,\n providers,\n messages: {\n async send(input) {\n assertOpen();\n\n if (input.conversationId !== undefined) {\n assertRoutableConversationId(input.conversationId);\n }\n\n if (input.text !== undefined && !provider.capabilities.messages.text) {\n unsupported('messages.text');\n }\n\n if (\n input.attachments !== undefined &&\n input.attachments.length > 0 &&\n !provider.capabilities.messages.attachments\n ) {\n unsupported('messages.attachments');\n }\n\n if (input.replyTo !== undefined && !provider.capabilities.messages.replies) {\n unsupported('messages.replies');\n }\n\n if (input.to !== undefined) {\n const recipients = Array.isArray(input.to) ? input.to : [input.to];\n const isGroup = recipients.length > 1;\n\n if (isGroup && !provider.capabilities.conversations.groups) {\n unsupported('conversations.groups');\n }\n\n if (!isGroup && !provider.capabilities.conversations.direct) {\n unsupported('conversations.direct');\n }\n }\n\n const message = await provider.messages.send(input);\n return decorateMessage(message, provider.name, connectionId) as SentMessage<\n ProviderNameOf<TProvider>,\n TConnectionId\n >;\n },\n async get(message) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.get) {\n unsupported('messages.get');\n }\n\n const get = requireImplementation(provider.messages.get, 'messages.get');\n\n const result = await get.call(provider.messages, message);\n return result === null ? null : decorateMessage(result, provider.name, connectionId);\n },\n async edit(message, input) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.edit) {\n unsupported('messages.edit');\n }\n\n const edit = requireImplementation(provider.messages.edit, 'messages.edit');\n\n const result = await edit.call(provider.messages, message, input);\n return decorateMessage(result, provider.name, connectionId);\n },\n async delete(message) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.delete) {\n unsupported('messages.delete');\n }\n\n const deleteMessage = requireImplementation(provider.messages.delete, 'messages.delete');\n\n await deleteMessage.call(provider.messages, message);\n },\n },\n conversations: {\n async open(input) {\n assertOpen();\n const isGroup = input.participants.length > 1;\n\n if (isGroup && !provider.capabilities.conversations.groups) {\n unsupported('conversations.groups');\n }\n\n if (!isGroup && !provider.capabilities.conversations.direct) {\n unsupported('conversations.direct');\n }\n\n const conversation = await provider.conversations.open(input);\n return decorateConversation(conversation, provider.name, connectionId);\n },\n async get(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.conversations.get) {\n unsupported('conversations.get');\n }\n\n const get = requireImplementation(provider.conversations.get, 'conversations.get');\n\n const conversation = await get.call(provider.conversations, conversationId);\n return conversation === null\n ? null\n : decorateConversation(conversation, provider.name, connectionId);\n },\n async markRead(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.conversations.markRead) {\n unsupported('conversations.markRead');\n }\n\n const markRead = requireImplementation(\n provider.conversations.markRead,\n 'conversations.markRead',\n );\n await markRead.call(provider.conversations, conversationId);\n },\n },\n reactions: {\n async add(input) {\n assertOpen();\n assertRoutableConversationId(input.conversationId);\n\n if (!provider.capabilities.interactions.reactions) {\n unsupported('reactions.add');\n }\n\n const reactions = requireImplementation(provider.reactions, 'reactions.add');\n\n await reactions.add(input);\n },\n async remove(input) {\n assertOpen();\n assertRoutableConversationId(input.conversationId);\n\n if (!provider.capabilities.interactions.reactions) {\n unsupported('reactions.remove');\n }\n\n const reactions = requireImplementation(provider.reactions, 'reactions.remove');\n\n await reactions.remove(input);\n },\n },\n typing: {\n async start(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.interactions.typingStart) {\n unsupported('typing.start');\n }\n\n const typing = requireImplementation(provider.typing, 'typing.start');\n\n await typing.start(conversationId);\n },\n async stop(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.interactions.typingStop) {\n unsupported('typing.stop');\n }\n\n const typing = requireImplementation(provider.typing, 'typing.stop');\n const stop = requireImplementation(typing.stop, 'typing.stop');\n\n await stop.call(typing, conversationId);\n },\n },\n webhooks: {\n async handle(request) {\n assertOpen();\n\n if (!provider.capabilities.events.webhooks) {\n unsupported('webhooks.handle');\n }\n\n const webhooks = requireImplementation(provider.webhooks, 'webhooks.handle');\n\n const verified = await webhooks.verify(request.clone());\n if (!verified) {\n throw new WebhookVerificationError(errorContext);\n }\n\n const events = await webhooks.parse(request);\n return events.map((event) => decorateEvent(event, provider.name, connectionId));\n },\n },\n events: {\n subscribe(options) {\n assertOpen();\n\n if (!provider.capabilities.events.stream) {\n unsupported('events.subscribe');\n }\n\n const events = requireImplementation(provider.events, 'events.subscribe');\n\n return mapEvents(events.subscribe(options), provider.name, connectionId);\n },\n },\n close() {\n if (closePromise !== undefined) {\n return closePromise;\n }\n\n closed = true;\n closePromise = Promise.resolve().then(async () => await provider.close?.());\n return closePromise;\n },\n };\n}\n","import type { IMessageCapabilities } from './capabilities.js';\nimport type { ProviderEvent } from './events.js';\nimport type {\n AddReactionInput,\n EditMessageInput,\n IMessageProviderName,\n MessageLocator,\n OpenConversationInput,\n ProviderConversation,\n ProviderMessage,\n ProviderSentMessage,\n RemoveReactionInput,\n SendMessageInput,\n SubscribeOptions,\n} from './types.js';\n\nexport interface ProviderMessages {\n send(input: SendMessageInput): Promise<ProviderSentMessage>;\n get?(message: MessageLocator): Promise<ProviderMessage | null>;\n edit?(message: MessageLocator, input: EditMessageInput): Promise<ProviderMessage>;\n delete?(message: MessageLocator): Promise<void>;\n}\n\nexport interface ProviderConversations {\n open(input: OpenConversationInput): Promise<ProviderConversation>;\n get?(conversationId: string): Promise<ProviderConversation | null>;\n markRead?(conversationId: string): Promise<void>;\n}\n\nexport interface ProviderReactions {\n add(input: AddReactionInput): Promise<void>;\n remove(input: RemoveReactionInput): Promise<void>;\n}\n\nexport interface ProviderTyping {\n start(conversationId: string): Promise<void>;\n stop?(conversationId: string): Promise<void>;\n}\n\nexport interface ProviderWebhooks {\n verify(request: Request): Promise<boolean>;\n parse(request: Request): Promise<readonly ProviderEvent[]>;\n}\n\nexport interface ProviderEvents {\n subscribe(options?: SubscribeOptions): AsyncIterable<ProviderEvent>;\n}\n\n/**\n * Contract implemented by a provider adapter.\n *\n * The complete adapter is exposed at `client.providers.<name>`, so\n * provider-specific APIs should be defined directly on the concrete provider.\n */\nexport interface IMessageProvider<\n TName extends IMessageProviderName = IMessageProviderName,\n TCapabilities extends IMessageCapabilities = IMessageCapabilities,\n> {\n readonly name: TName;\n readonly capabilities: TCapabilities;\n readonly messages: ProviderMessages;\n readonly conversations: ProviderConversations;\n readonly reactions?: ProviderReactions;\n readonly typing?: ProviderTyping;\n readonly webhooks?: ProviderWebhooks;\n readonly events?: ProviderEvents;\n close?(): Promise<void>;\n}\n\nexport type AnyIMessageProvider = IMessageProvider<IMessageProviderName, IMessageCapabilities>;\n\n/** Preserves the concrete name, capabilities, and methods of an adapter. */\nexport function defineProvider<const TProvider extends AnyIMessageProvider>(\n provider: TProvider,\n): TProvider {\n return provider;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/conversation-id.ts","../src/core/errors.ts","../src/core/client.ts","../src/core/provider.ts"],"names":["options"],"mappings":"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","file":"index.js","sourcesContent":["const FALLBACK_CONVERSATION_ID_PREFIX = 'imsg-sdk-v1-';\n\ninterface FallbackConversationIdPayload {\n readonly message: string;\n readonly timestamp: string;\n}\n\n/**\n * Creates a diagnostic fallback when a provider message omits its native\n * conversation ID. Fallback IDs are stable for the same message and timestamp,\n * but are not provider-routable conversation handles.\n */\nexport function createFallbackConversationId(message: string, timestamp: Date): string {\n if (message.length === 0) {\n throw new TypeError('Fallback conversation message must not be empty.');\n }\n if (Number.isNaN(timestamp.getTime())) {\n throw new TypeError('Fallback conversation timestamp must be valid.');\n }\n\n const payload: FallbackConversationIdPayload = {\n message,\n timestamp: timestamp.toISOString(),\n };\n const encoded = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64url');\n return `${FALLBACK_CONVERSATION_ID_PREFIX}${encoded}`;\n}\n\nexport function isFallbackConversationId(value: string): boolean {\n return value.startsWith(FALLBACK_CONVERSATION_ID_PREFIX);\n}\n","export interface IMessageSDKErrorOptions {\n readonly provider?: string;\n readonly connectionId?: string;\n readonly code?: string;\n readonly statusCode?: number;\n readonly retryable?: boolean;\n readonly retryAfter?: number;\n readonly traceId?: string;\n readonly raw?: unknown;\n}\n\nexport class IMessageSDKError extends Error {\n readonly provider: string | undefined;\n readonly connectionId: string | undefined;\n readonly code: string | undefined;\n readonly statusCode: number | undefined;\n readonly retryable: boolean;\n readonly retryAfter: number | undefined;\n readonly traceId: string | undefined;\n readonly raw: unknown;\n\n constructor(message: string, options: IMessageSDKErrorOptions = {}) {\n super(message);\n this.name = new.target.name;\n this.provider = options.provider;\n this.connectionId = options.connectionId;\n this.code = options.code;\n this.statusCode = options.statusCode;\n this.retryable = options.retryable ?? false;\n this.retryAfter = options.retryAfter;\n this.traceId = options.traceId;\n this.raw = options.raw;\n }\n}\n\nexport class ValidationError extends IMessageSDKError {}\n\nexport class AuthenticationError extends IMessageSDKError {}\n\nexport class NotFoundError extends IMessageSDKError {}\n\nexport class ConflictError extends IMessageSDKError {}\n\nexport class RateLimitError extends IMessageSDKError {}\n\nexport class ProviderUnavailableError extends IMessageSDKError {}\n\n/** A send may have reached the provider, so blindly retrying could duplicate it. */\nexport class AmbiguousDeliveryError extends IMessageSDKError {}\n\nexport class UnsupportedCapabilityError extends IMessageSDKError {\n readonly capability: string;\n\n constructor(\n capability: string,\n options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {},\n ) {\n super(`The selected provider does not support ${capability}.`, {\n ...options,\n code: 'unsupported_capability',\n });\n this.capability = capability;\n }\n}\n\nexport class WebhookVerificationError extends IMessageSDKError {\n constructor(options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {}) {\n super('Webhook signature verification failed.', {\n ...options,\n code: 'webhook_verification_failed',\n });\n }\n}\n\nexport class ClientClosedError extends IMessageSDKError {\n constructor(options: Pick<IMessageSDKErrorOptions, 'provider' | 'connectionId'> = {}) {\n super('This iMessage client has already been closed.', {\n ...options,\n code: 'client_closed',\n });\n }\n}\n","import type { IMessageEvent, ProviderEvent } from './events.js';\nimport type { AnyIMessageProvider } from './provider.js';\nimport type {\n AddReactionInput,\n Conversation,\n EditMessageInput,\n IMessageProviderName,\n Message,\n MessageLocator,\n OpenConversationInput,\n ProviderConversation,\n ProviderMessage,\n RemoveReactionInput,\n SendMessageInput,\n SentMessage,\n SubscribeOptions,\n} from './types.js';\nimport { createFallbackConversationId, isFallbackConversationId } from './conversation-id.js';\nimport {\n ClientClosedError,\n UnsupportedCapabilityError,\n ValidationError,\n WebhookVerificationError,\n} from './errors.js';\n\ntype ProviderNameOf<TProvider extends AnyIMessageProvider> = TProvider['name'];\n\nexport const DEFAULT_CONNECTION_ID = 'default' as const;\n\nexport type ClientProvider<TProvider extends AnyIMessageProvider> = TProvider;\n\nexport type ClientProviders<TProvider extends AnyIMessageProvider> = {\n readonly [TName in TProvider['name']]: ClientProvider<\n Extract<TProvider, { readonly name: TName }>\n >;\n};\n\nexport interface IMessageClient<\n TProvider extends AnyIMessageProvider = AnyIMessageProvider,\n TConnectionId extends string = string,\n> {\n readonly provider: ProviderNameOf<TProvider>;\n readonly connectionId: TConnectionId;\n readonly capabilities: TProvider['capabilities'];\n readonly providers: ClientProviders<TProvider>;\n\n readonly messages: {\n send(input: SendMessageInput): Promise<SentMessage<ProviderNameOf<TProvider>, TConnectionId>>;\n get(message: MessageLocator): Promise<Message<ProviderNameOf<TProvider>, TConnectionId> | null>;\n edit(\n message: MessageLocator,\n input: EditMessageInput,\n ): Promise<Message<ProviderNameOf<TProvider>, TConnectionId>>;\n delete(message: MessageLocator): Promise<void>;\n };\n\n readonly conversations: {\n open(\n input: OpenConversationInput,\n ): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId>>;\n get(\n conversationId: string,\n ): Promise<Conversation<ProviderNameOf<TProvider>, TConnectionId> | null>;\n markRead(conversationId: string): Promise<void>;\n };\n\n readonly reactions: {\n add(input: AddReactionInput): Promise<void>;\n remove(input: RemoveReactionInput): Promise<void>;\n };\n\n readonly typing: {\n start(conversationId: string): Promise<void>;\n stop(conversationId: string): Promise<void>;\n };\n\n /** @experimental Webhook normalization may change before a future stable release. */\n readonly webhooks: {\n handle(\n request: Request,\n ): Promise<readonly IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>[]>;\n };\n\n readonly events: {\n subscribe(\n options?: SubscribeOptions,\n ): AsyncIterable<IMessageEvent<ProviderNameOf<TProvider>, TConnectionId>>;\n };\n\n close(): Promise<void>;\n}\n\nexport interface CreateIMessageClientOptions<\n TProvider extends AnyIMessageProvider,\n TConnectionId extends string = typeof DEFAULT_CONNECTION_ID,\n> {\n readonly connectionId?: TConnectionId;\n readonly provider: TProvider;\n}\n\nfunction validateProvider(provider: AnyIMessageProvider): void {\n const capabilities = provider.capabilities;\n\n const requirements: readonly [boolean, unknown, string][] = [\n [capabilities.messages.get, provider.messages.get, 'messages.get'],\n [capabilities.messages.edit, provider.messages.edit, 'messages.edit'],\n [capabilities.messages.delete, provider.messages.delete, 'messages.delete'],\n [capabilities.conversations.get, provider.conversations.get, 'conversations.get'],\n [\n capabilities.conversations.markRead,\n provider.conversations.markRead,\n 'conversations.markRead',\n ],\n [capabilities.interactions.reactions, provider.reactions, 'reactions'],\n [capabilities.interactions.typingStart, provider.typing, 'typing.start'],\n [capabilities.interactions.typingStop, provider.typing?.stop, 'typing.stop'],\n [capabilities.events.webhooks, provider.webhooks, 'webhooks'],\n [capabilities.events.stream, provider.events, 'events.subscribe'],\n ];\n\n for (const [enabled, implementation, capability] of requirements) {\n if (enabled && implementation === undefined) {\n throw new ValidationError(\n `Provider ${provider.name} declares ${capability} but does not implement it.`,\n { provider: provider.name, code: 'invalid_provider_contract' },\n );\n }\n }\n}\n\nfunction decorateMessage<TProvider extends IMessageProviderName, TConnectionId extends string>(\n message: ProviderMessage,\n provider: TProvider,\n connectionId: TConnectionId,\n): Message<TProvider, TConnectionId> {\n return {\n ...message,\n id: message.providerMessageId,\n conversationId:\n message.conversationId ??\n createFallbackConversationId(message.providerMessageId, message.createdAt),\n provider,\n connectionId,\n };\n}\n\nfunction decorateConversation<TProvider extends IMessageProviderName, TConnectionId extends string>(\n conversation: ProviderConversation,\n provider: TProvider,\n connectionId: TConnectionId,\n): Conversation<TProvider, TConnectionId> {\n return {\n ...conversation,\n id: conversation.providerConversationId,\n provider,\n connectionId,\n };\n}\n\nfunction decorateEvent<TProvider extends IMessageProviderName, TConnectionId extends string>(\n event: ProviderEvent,\n provider: TProvider,\n connectionId: TConnectionId,\n): IMessageEvent<TProvider, TConnectionId> {\n switch (event.type) {\n case 'message.received':\n case 'message.sent':\n case 'message.delivered':\n case 'message.read':\n case 'message.failed':\n case 'message.edited':\n return {\n ...event,\n provider,\n connectionId,\n message: decorateMessage(event.message, provider, connectionId),\n };\n case 'message.deleted':\n case 'reaction.added':\n case 'reaction.removed':\n case 'typing.started':\n case 'typing.stopped':\n return { ...event, provider, connectionId };\n }\n}\n\nfunction mapEvents<TProvider extends IMessageProviderName, TConnectionId extends string>(\n events: AsyncIterable<ProviderEvent>,\n provider: TProvider,\n connectionId: TConnectionId,\n): AsyncIterable<IMessageEvent<TProvider, TConnectionId>> {\n return {\n async *[Symbol.asyncIterator]() {\n for await (const event of events) {\n yield decorateEvent(event, provider, connectionId);\n }\n },\n };\n}\n\nexport function createIMessageClient<\n const TProvider extends AnyIMessageProvider,\n const TConnectionId extends string = typeof DEFAULT_CONNECTION_ID,\n>(\n options: CreateIMessageClientOptions<TProvider, TConnectionId>,\n): IMessageClient<TProvider, TConnectionId> {\n const { provider } = options;\n const connectionId = (options.connectionId ?? DEFAULT_CONNECTION_ID) as TConnectionId;\n\n if (connectionId.trim().length === 0) {\n throw new ValidationError('connectionId must not be empty.', {\n provider: provider.name,\n code: 'invalid_connection_id',\n });\n }\n\n validateProvider(provider);\n\n let closed = false;\n let closePromise: Promise<void> | undefined;\n\n const errorContext = {\n provider: provider.name,\n connectionId,\n } as const;\n\n const assertOpen = (): void => {\n if (closed) {\n throw new ClientClosedError(errorContext);\n }\n };\n\n const unsupported = (capability: string): never => {\n throw new UnsupportedCapabilityError(capability, errorContext);\n };\n\n const assertRoutableConversationId = (conversationId: string): void => {\n if (isFallbackConversationId(conversationId)) {\n throw new ValidationError(\n 'SDK fallback conversation IDs are diagnostic and cannot be used for provider operations.',\n { ...errorContext, code: 'non_routable_conversation_id' },\n );\n }\n };\n\n const requireImplementation = <T>(implementation: T | undefined, capability: string): T => {\n if (implementation === undefined) {\n throw new UnsupportedCapabilityError(capability, errorContext);\n }\n\n return implementation;\n };\n\n const providers = Object.freeze({\n [provider.name]: provider,\n }) as ClientProviders<TProvider>;\n\n return {\n provider: provider.name,\n connectionId,\n capabilities: provider.capabilities,\n providers,\n messages: {\n async send(input) {\n assertOpen();\n\n if (input.conversationId !== undefined) {\n assertRoutableConversationId(input.conversationId);\n }\n\n if (input.text !== undefined && !provider.capabilities.messages.text) {\n unsupported('messages.text');\n }\n\n if (\n input.attachments !== undefined &&\n input.attachments.length > 0 &&\n !provider.capabilities.messages.attachments\n ) {\n unsupported('messages.attachments');\n }\n\n if (input.replyTo !== undefined && !provider.capabilities.messages.replies) {\n unsupported('messages.replies');\n }\n\n if (input.to !== undefined) {\n const recipients = Array.isArray(input.to) ? input.to : [input.to];\n const isGroup = recipients.length > 1;\n\n if (isGroup && !provider.capabilities.conversations.groups) {\n unsupported('conversations.groups');\n }\n\n if (!isGroup && !provider.capabilities.conversations.direct) {\n unsupported('conversations.direct');\n }\n }\n\n const message = await provider.messages.send(input);\n return decorateMessage(message, provider.name, connectionId) as SentMessage<\n ProviderNameOf<TProvider>,\n TConnectionId\n >;\n },\n async get(message) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.get) {\n unsupported('messages.get');\n }\n\n const get = requireImplementation(provider.messages.get, 'messages.get');\n\n const result = await get.call(provider.messages, message);\n return result === null ? null : decorateMessage(result, provider.name, connectionId);\n },\n async edit(message, input) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.edit) {\n unsupported('messages.edit');\n }\n\n const edit = requireImplementation(provider.messages.edit, 'messages.edit');\n\n const result = await edit.call(provider.messages, message, input);\n return decorateMessage(result, provider.name, connectionId);\n },\n async delete(message) {\n assertOpen();\n assertRoutableConversationId(message.conversationId);\n\n if (!provider.capabilities.messages.delete) {\n unsupported('messages.delete');\n }\n\n const deleteMessage = requireImplementation(provider.messages.delete, 'messages.delete');\n\n await deleteMessage.call(provider.messages, message);\n },\n },\n conversations: {\n async open(input) {\n assertOpen();\n const isGroup = input.participants.length > 1;\n\n if (isGroup && !provider.capabilities.conversations.groups) {\n unsupported('conversations.groups');\n }\n\n if (!isGroup && !provider.capabilities.conversations.direct) {\n unsupported('conversations.direct');\n }\n\n const conversation = await provider.conversations.open(input);\n return decorateConversation(conversation, provider.name, connectionId);\n },\n async get(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.conversations.get) {\n unsupported('conversations.get');\n }\n\n const get = requireImplementation(provider.conversations.get, 'conversations.get');\n\n const conversation = await get.call(provider.conversations, conversationId);\n return conversation === null\n ? null\n : decorateConversation(conversation, provider.name, connectionId);\n },\n async markRead(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.conversations.markRead) {\n unsupported('conversations.markRead');\n }\n\n const markRead = requireImplementation(\n provider.conversations.markRead,\n 'conversations.markRead',\n );\n await markRead.call(provider.conversations, conversationId);\n },\n },\n reactions: {\n async add(input) {\n assertOpen();\n assertRoutableConversationId(input.conversationId);\n\n if (!provider.capabilities.interactions.reactions) {\n unsupported('reactions.add');\n }\n\n const reactions = requireImplementation(provider.reactions, 'reactions.add');\n\n await reactions.add(input);\n },\n async remove(input) {\n assertOpen();\n assertRoutableConversationId(input.conversationId);\n\n if (!provider.capabilities.interactions.reactions) {\n unsupported('reactions.remove');\n }\n\n const reactions = requireImplementation(provider.reactions, 'reactions.remove');\n\n await reactions.remove(input);\n },\n },\n typing: {\n async start(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.interactions.typingStart) {\n unsupported('typing.start');\n }\n\n const typing = requireImplementation(provider.typing, 'typing.start');\n\n await typing.start(conversationId);\n },\n async stop(conversationId) {\n assertOpen();\n assertRoutableConversationId(conversationId);\n\n if (!provider.capabilities.interactions.typingStop) {\n unsupported('typing.stop');\n }\n\n const typing = requireImplementation(provider.typing, 'typing.stop');\n const stop = requireImplementation(typing.stop, 'typing.stop');\n\n await stop.call(typing, conversationId);\n },\n },\n webhooks: {\n async handle(request) {\n assertOpen();\n\n if (!provider.capabilities.events.webhooks) {\n unsupported('webhooks.handle');\n }\n\n const webhooks = requireImplementation(provider.webhooks, 'webhooks.handle');\n\n const verified = await webhooks.verify(request.clone());\n if (!verified) {\n throw new WebhookVerificationError(errorContext);\n }\n\n const events = await webhooks.parse(request);\n return events.map((event) => decorateEvent(event, provider.name, connectionId));\n },\n },\n events: {\n subscribe(options) {\n assertOpen();\n\n if (!provider.capabilities.events.stream) {\n unsupported('events.subscribe');\n }\n\n const events = requireImplementation(provider.events, 'events.subscribe');\n\n return mapEvents(events.subscribe(options), provider.name, connectionId);\n },\n },\n close() {\n if (closePromise !== undefined) {\n return closePromise;\n }\n\n closed = true;\n closePromise = Promise.resolve().then(async () => await provider.close?.());\n return closePromise;\n },\n };\n}\n","import type { IMessageCapabilities } from './capabilities.js';\nimport type { ProviderEvent } from './events.js';\nimport type {\n AddReactionInput,\n EditMessageInput,\n IMessageProviderName,\n MessageLocator,\n OpenConversationInput,\n ProviderConversation,\n ProviderMessage,\n ProviderSentMessage,\n RemoveReactionInput,\n SendMessageInput,\n SubscribeOptions,\n} from './types.js';\n\nexport interface ProviderMessages {\n send(input: SendMessageInput): Promise<ProviderSentMessage>;\n get?(message: MessageLocator): Promise<ProviderMessage | null>;\n edit?(message: MessageLocator, input: EditMessageInput): Promise<ProviderMessage>;\n delete?(message: MessageLocator): Promise<void>;\n}\n\nexport interface ProviderConversations {\n open(input: OpenConversationInput): Promise<ProviderConversation>;\n get?(conversationId: string): Promise<ProviderConversation | null>;\n markRead?(conversationId: string): Promise<void>;\n}\n\nexport interface ProviderReactions {\n add(input: AddReactionInput): Promise<void>;\n remove(input: RemoveReactionInput): Promise<void>;\n}\n\nexport interface ProviderTyping {\n start(conversationId: string): Promise<void>;\n stop?(conversationId: string): Promise<void>;\n}\n\n/**\n * Provider webhook verification and normalization contract.\n *\n * @experimental Webhook normalization may change before a future stable release.\n */\nexport interface ProviderWebhooks {\n verify(request: Request): Promise<boolean>;\n parse(request: Request): Promise<readonly ProviderEvent[]>;\n}\n\nexport interface ProviderEvents {\n subscribe(options?: SubscribeOptions): AsyncIterable<ProviderEvent>;\n}\n\n/**\n * Contract implemented by a provider adapter.\n *\n * The complete adapter is exposed at `client.providers.<name>`, so\n * provider-specific APIs should be defined directly on the concrete provider.\n */\nexport interface IMessageProvider<\n TName extends IMessageProviderName = IMessageProviderName,\n TCapabilities extends IMessageCapabilities = IMessageCapabilities,\n> {\n readonly name: TName;\n readonly capabilities: TCapabilities;\n readonly messages: ProviderMessages;\n readonly conversations: ProviderConversations;\n readonly reactions?: ProviderReactions;\n readonly typing?: ProviderTyping;\n /** @experimental Webhook normalization may change before a future stable release. */\n readonly webhooks?: ProviderWebhooks;\n readonly events?: ProviderEvents;\n close?(): Promise<void>;\n}\n\nexport type AnyIMessageProvider = IMessageProvider<IMessageProviderName, IMessageCapabilities>;\n\n/** Preserves the concrete name, capabilities, and methods of an adapter. */\nexport function defineProvider<const TProvider extends AnyIMessageProvider>(\n provider: TProvider,\n): TProvider {\n return provider;\n}\n"]}
|