@emmanuel-nike/ark-notify-js 0.2.1 → 0.2.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server-auth.ts","../../src/config.ts","../../src/utils.ts","../../src/server-stream.ts"],"names":["createHmac"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createHmac } from 'node:crypto'\nimport type {\n ConnectionCapabilities,\n CreateAuthorizedServerAuthResponseOptions,\n HandleServerAuthOptions,\n ServerAuthApprovedResponse,\n ServerAuthDeniedResponse,\n ServerAuthRequest,\n ServerAuthResponse,\n ServerAuthDecision,\n} from './types'\n\nconst CLIENT_ID_PATTERN = /^[a-zA-Z0-9_\\-.@\\+]{1,128}$/\nconst DEFAULT_TTL_SECONDS = 3600\nconst MAX_TTL_SECONDS = 86400\n\nconst DEFAULT_CAPABILITIES: ConnectionCapabilities = {\n subscribe: true,\n publish: true,\n presence: true,\n}\n\nexport function isValidClientId(clientId: unknown): clientId is string {\n return typeof clientId === 'string' && CLIENT_ID_PATTERN.test(clientId)\n}\n\nfunction normalizeCapabilities(\n capabilities?: Partial<ConnectionCapabilities> | null\n): ConnectionCapabilities {\n if (!capabilities || typeof capabilities !== 'object') {\n return { ...DEFAULT_CAPABILITIES }\n }\n\n return {\n subscribe: capabilities.subscribe !== false,\n publish: capabilities.publish !== false,\n presence: capabilities.presence !== false,\n }\n}\n\nfunction resolveTokenTtl(ttl?: number | null): number {\n if (ttl === undefined || ttl === null) {\n return DEFAULT_TTL_SECONDS\n }\n\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error('ttl must be a positive integer (seconds)')\n }\n\n return Math.min(ttl, MAX_TTL_SECONDS)\n}\n\nfunction encodePayload(payload: Record<string, unknown>): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url')\n}\n\nfunction computeConnectionTokenSignature(\n secret: string,\n appKey: string,\n payloadEncoded: string\n): string {\n return createHmac('sha256', secret).update(`${appKey}.${payloadEncoded}`).digest('hex')\n}\n\n/** Build a signed connection token in Ark Notify format. */\nexport function buildConnectionToken(\n appKey: string,\n secret: string,\n options: {\n clientId: string\n exp: number\n capabilities?: Partial<ConnectionCapabilities>\n }\n): string {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const payloadEncoded = encodePayload({\n client_id: options.clientId,\n exp: options.exp,\n capabilities: normalizeCapabilities(options.capabilities),\n })\n\n const signature = computeConnectionTokenSignature(secret, appKey, payloadEncoded)\n return `${appKey}.${payloadEncoded}.${signature}`\n}\n\n/**\n * Parse the JSON body Ark Notify sends to your `serverAuthUrl`.\n * Returns null when the payload is invalid.\n */\nexport function parseServerAuthRequest(body: unknown): ServerAuthRequest | null {\n if (!body || typeof body !== 'object') {\n return null\n }\n\n const record = body as Record<string, unknown>\n const client_id = record.client_id ?? record.clientId\n\n if (!isValidClientId(client_id)) {\n return null\n }\n\n const user_data = record.user_data ?? record.userData\n const capabilities = record.capabilities\n const ttl = record.ttl\n\n return {\n client_id,\n user_data:\n user_data === undefined\n ? null\n : user_data && typeof user_data === 'object'\n ? (user_data as Record<string, unknown>)\n : null,\n capabilities:\n capabilities && typeof capabilities === 'object'\n ? (capabilities as Partial<ConnectionCapabilities>)\n : null,\n ttl: typeof ttl === 'number' ? ttl : null,\n }\n}\n\n/**\n * Build an approved response for your `serverAuthUrl` webhook.\n *\n * - Without `credentials`: returns `{ allowed: true, client_id, ... }` (option A).\n * - With `credentials`: returns `{ token }` with a pre-signed token (option B).\n */\nexport function createAuthorizedServerAuthResponse(\n options: CreateAuthorizedServerAuthResponseOptions\n): ServerAuthApprovedResponse {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const capabilities = normalizeCapabilities(options.capabilities)\n const ttl = resolveTokenTtl(options.ttl)\n\n if (options.credentials) {\n const exp = Math.floor(Date.now() / 1000) + ttl\n return {\n token: buildConnectionToken(options.credentials.appKey, options.credentials.secret, {\n clientId: options.clientId,\n exp,\n capabilities,\n }),\n }\n }\n\n return {\n allowed: true,\n client_id: options.clientId,\n capabilities,\n ttl,\n }\n}\n\n/** Build a denied response for your `serverAuthUrl` webhook. */\nexport function createDeniedServerAuthResponse(reason?: string): ServerAuthDeniedResponse {\n return reason ? { allowed: false, reason } : { allowed: false }\n}\n\n/**\n * Authenticate an incoming `serverAuthUrl` request and return the webhook response\n * body Ark Notify expects.\n */\nexport async function handleServerAuth(\n options: HandleServerAuthOptions\n): Promise<ServerAuthResponse> {\n const decision: ServerAuthDecision = await options.isAuthorized(options.request)\n\n if (decision === false) {\n return createDeniedServerAuthResponse()\n }\n\n const clientId = decision.clientId ?? options.request.client_id\n if (!isValidClientId(clientId)) {\n return createDeniedServerAuthResponse('invalid_client_id')\n }\n\n try {\n return createAuthorizedServerAuthResponse({\n clientId,\n capabilities: decision.capabilities ?? options.request.capabilities ?? undefined,\n ttl: decision.ttl ?? options.request.ttl ?? undefined,\n credentials: options.credentials,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid_request'\n return createDeniedServerAuthResponse(message)\n }\n}\n","export const DEFAULT_BASE_URL = 'https://ark-notify-933303906015.europe-north1.run.app'\n\nlet configuredBaseUrl: string | undefined\n\nexport interface ArkNotifyGlobalConfig {\n baseUrl?: string\n}\n\n/** Set the default base URL once at application startup. */\nexport function configureArkNotify(config: ArkNotifyGlobalConfig): void {\n if (config.baseUrl !== undefined) {\n configuredBaseUrl = config.baseUrl\n }\n}\n\nexport function resolveBaseUrl(baseUrl?: string): string {\n return (baseUrl ?? configuredBaseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n}\n","import type { ApiError } from './types'\n\nexport class ArkNotifyError extends Error {\n readonly status: number\n readonly code: string\n readonly retryAfterSec?: number\n readonly reason?: string\n\n constructor(status: number, body: ApiError) {\n super(body.message)\n this.name = 'ArkNotifyError'\n this.status = status\n this.code = body.error\n this.retryAfterSec = body.retryAfterSec\n this.reason = body.reason\n }\n}\n\nexport function toWebSocketUrl(baseUrl: string, path: string): string {\n const normalizedBase = baseUrl.replace(/\\/$/, '')\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const httpUrl = `${normalizedBase}${normalizedPath}`\n // Avoid URL.protocol — not supported in React Native and some runtimes.\n return httpUrl.replace(/^https:/i, 'wss:').replace(/^http:/i, 'ws:')\n}\n\n/** Append query params without URLSearchParams (unsupported in React Native). */\nexport function appendQueryParams(\n url: string,\n params: Record<string, string | undefined | null | false>\n): string {\n const query = Object.entries(params)\n .filter((entry): entry is [string, string] => {\n const value = entry[1]\n return value !== undefined && value !== null && value !== false && value !== ''\n })\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n\n if (!query) return url\n\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${query}`\n}\n\nexport function resolveValue<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport function isPrivateChannel(channel: string): boolean {\n return channel.startsWith('private-')\n}\n","import { resolveBaseUrl } from './config'\nimport type {\n AppCredentials,\n ArkNotifyServerStreamConfig,\n EventMessage,\n PresenceMessage,\n ServerErrorMessage,\n ServerStreamConnectedMessage,\n} from './types'\nimport { appendQueryParams, ArkNotifyError } from './utils'\n\ntype ServerStreamEventMap = {\n connected: (message: ServerStreamConnectedMessage) => void\n event: (message: EventMessage) => void\n presence: (message: PresenceMessage) => void\n message: (message: ServerStreamMessage) => void\n error: (error: Error) => void\n close: () => void\n}\n\ntype ServerStreamEventName = keyof ServerStreamEventMap\n\nfunction buildAppCredentialsHeaders(credentials: AppCredentials): Record<string, string> {\n return {\n 'X-App-Key': credentials.appKey,\n 'X-App-Secret': credentials.secret,\n }\n}\n\ntype ServerStreamMessage = ServerStreamConnectedMessage | EventMessage | PresenceMessage | ServerErrorMessage\n\nfunction dispatchSseEvent(\n data: string,\n handlers: {\n onConnected: (message: ServerStreamConnectedMessage) => void\n onEvent: (message: EventMessage) => void\n onPresence: (message: PresenceMessage) => void\n onMessage: (message: ServerStreamMessage) => void\n }\n): void {\n if (!data) return\n\n let parsed: ServerStreamMessage\n try {\n parsed = JSON.parse(data) as ServerStreamMessage\n } catch {\n return\n }\n\n if (parsed.type === 'connected') {\n handlers.onConnected(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'event') {\n handlers.onEvent(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'presence') {\n handlers.onPresence(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n handlers.onMessage(parsed)\n}\n\nasync function readSseStream(\n body: ReadableStream<Uint8Array>,\n onSseData: (data: string) => void,\n signal: AbortSignal\n): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent: string | null = null\n let dataLines: string[] = []\n\n const flushEvent = () => {\n if (dataLines.length === 0 && currentEvent === null) return\n onSseData(dataLines.join('\\n'))\n currentEvent = null\n dataLines = []\n }\n\n try {\n while (!signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine\n\n if (line === '') {\n flushEvent()\n continue\n }\n\n if (line.startsWith(':')) continue\n\n if (line.startsWith('event:')) {\n currentEvent = line.slice(6).trimStart()\n continue\n }\n\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n }\n\n if (buffer.length > 0) {\n const line = buffer.endsWith('\\r') ? buffer.slice(0, -1) : buffer\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n\n flushEvent()\n } finally {\n reader.releaseLock()\n }\n}\n\nexport class ArkNotifyServerStream {\n private readonly config: ArkNotifyServerStreamConfig & { baseUrl: string }\n private readonly fetchFn: typeof fetch\n private readonly listeners = new Map<\n ServerStreamEventName,\n Set<ServerStreamEventMap[ServerStreamEventName]>\n >()\n private abortController: AbortController | null = null\n private connectionId: string | null = null\n private connecting = false\n\n constructor(config: ArkNotifyServerStreamConfig) {\n this.config = { ...config, baseUrl: resolveBaseUrl(config.baseUrl) }\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n getConnectionId(): string | null {\n return this.connectionId\n }\n\n on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n return () => this.off(event, handler)\n }\n\n off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n private emit<E extends ServerStreamEventName>(\n event: E,\n ...args: Parameters<ServerStreamEventMap[E]>\n ): void {\n for (const handler of this.listeners.get(event) ?? []) {\n ;(handler as (...a: Parameters<ServerStreamEventMap[E]>) => void)(...args)\n }\n }\n\n async connect(): Promise<void> {\n if (this.abortController || this.connecting) return\n\n this.connecting = true\n const abortController = new AbortController()\n this.abortController = abortController\n\n const base = this.config.baseUrl.replace(/\\/$/, '')\n const streamUrl = appendQueryParams(\n `${base}/api/v1/apps/${this.config.appKey}/server-stream`,\n {\n channels: this.config.channels.join(','),\n history: this.config.history ? 'true' : undefined,\n }\n )\n\n try {\n const response = await this.fetchFn(streamUrl, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...buildAppCredentialsHeaders(this.config.credentials),\n },\n signal: abortController.signal,\n })\n\n if (!response.ok) {\n let body: { error: string; message: string; reason?: string; retryAfterSec?: number }\n try {\n body = await response.json()\n } catch {\n body = { error: 'request_failed', message: response.statusText }\n }\n throw new ArkNotifyError(response.status, body)\n }\n\n if (!response.body) {\n throw new Error('Server stream response has no body')\n }\n\n void this.consumeStream(response.body, abortController)\n } catch (err) {\n if (abortController.signal.aborted) return\n this.abortController = null\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n this.emit('close')\n } finally {\n this.connecting = false\n }\n }\n\n private async consumeStream(body: ReadableStream<Uint8Array>, abortController: AbortController): Promise<void> {\n try {\n await readSseStream(\n body,\n (data) => {\n dispatchSseEvent(data, {\n onConnected: (message) => {\n this.connectionId = message.connection_id\n this.emit('connected', message)\n },\n onEvent: (message) => this.emit('event', message),\n onPresence: (message) => this.emit('presence', message),\n onMessage: (message) => this.emit('message', message),\n })\n },\n abortController.signal\n )\n } catch (err) {\n if (abortController.signal.aborted) return\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null\n this.connectionId = null\n this.emit('close')\n }\n }\n }\n\n disconnect(): void {\n if (!this.abortController) return\n this.abortController.abort()\n }\n\n bind(\n channel: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/server-auth.ts","../../src/config.ts","../../src/utils.ts","../../src/server-stream.ts"],"names":["createHmac"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createHmac } from 'node:crypto'\nimport type {\n ConnectionCapabilities,\n CreateAuthorizedServerAuthResponseOptions,\n HandleServerAuthOptions,\n ServerAuthApprovedResponse,\n ServerAuthDeniedResponse,\n ServerAuthRequest,\n ServerAuthResponse,\n ServerAuthDecision,\n} from './types'\n\nconst CLIENT_ID_PATTERN = /^[a-zA-Z0-9_\\-.@\\+]{1,128}$/\nconst DEFAULT_TTL_SECONDS = 3600\nconst MAX_TTL_SECONDS = 86400\n\nconst DEFAULT_CAPABILITIES: ConnectionCapabilities = {\n subscribe: true,\n publish: true,\n presence: true,\n}\n\nexport function isValidClientId(clientId: unknown): clientId is string {\n return typeof clientId === 'string' && CLIENT_ID_PATTERN.test(clientId)\n}\n\nfunction normalizeCapabilities(\n capabilities?: Partial<ConnectionCapabilities> | null\n): ConnectionCapabilities {\n if (!capabilities || typeof capabilities !== 'object') {\n return { ...DEFAULT_CAPABILITIES }\n }\n\n return {\n subscribe: capabilities.subscribe !== false,\n publish: capabilities.publish !== false,\n presence: capabilities.presence !== false,\n }\n}\n\nfunction resolveTokenTtl(ttl?: number | null): number {\n if (ttl === undefined || ttl === null) {\n return DEFAULT_TTL_SECONDS\n }\n\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error('ttl must be a positive integer (seconds)')\n }\n\n return Math.min(ttl, MAX_TTL_SECONDS)\n}\n\nfunction encodePayload(payload: Record<string, unknown>): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url')\n}\n\nfunction computeConnectionTokenSignature(\n secret: string,\n appKey: string,\n payloadEncoded: string\n): string {\n return createHmac('sha256', secret).update(`${appKey}.${payloadEncoded}`).digest('hex')\n}\n\n/** Build a signed connection token in Ark Notify format. */\nexport function buildConnectionToken(\n appKey: string,\n secret: string,\n options: {\n clientId: string\n exp: number\n capabilities?: Partial<ConnectionCapabilities>\n }\n): string {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const payloadEncoded = encodePayload({\n client_id: options.clientId,\n exp: options.exp,\n capabilities: normalizeCapabilities(options.capabilities),\n })\n\n const signature = computeConnectionTokenSignature(secret, appKey, payloadEncoded)\n return `${appKey}.${payloadEncoded}.${signature}`\n}\n\n/**\n * Parse the JSON body Ark Notify sends to your `serverAuthUrl`.\n * Returns null when the payload is invalid.\n */\nexport function parseServerAuthRequest(body: unknown): ServerAuthRequest | null {\n if (!body || typeof body !== 'object') {\n return null\n }\n\n const record = body as Record<string, unknown>\n const client_id = record.client_id ?? record.clientId\n\n if (!isValidClientId(client_id)) {\n return null\n }\n\n const user_data = record.user_data ?? record.userData\n const capabilities = record.capabilities\n const ttl = record.ttl\n\n return {\n client_id,\n user_data:\n user_data === undefined\n ? null\n : user_data && typeof user_data === 'object'\n ? (user_data as Record<string, unknown>)\n : null,\n capabilities:\n capabilities && typeof capabilities === 'object'\n ? (capabilities as Partial<ConnectionCapabilities>)\n : null,\n ttl: typeof ttl === 'number' ? ttl : null,\n }\n}\n\n/**\n * Build an approved response for your `serverAuthUrl` webhook.\n *\n * - Without `credentials`: returns `{ allowed: true, client_id, ... }` (option A).\n * - With `credentials`: returns `{ token }` with a pre-signed token (option B).\n */\nexport function createAuthorizedServerAuthResponse(\n options: CreateAuthorizedServerAuthResponseOptions\n): ServerAuthApprovedResponse {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const capabilities = normalizeCapabilities(options.capabilities)\n const ttl = resolveTokenTtl(options.ttl)\n\n if (options.credentials) {\n const exp = Math.floor(Date.now() / 1000) + ttl\n return {\n token: buildConnectionToken(options.credentials.appKey, options.credentials.secret, {\n clientId: options.clientId,\n exp,\n capabilities,\n }),\n }\n }\n\n return {\n allowed: true,\n client_id: options.clientId,\n capabilities,\n ttl,\n }\n}\n\n/** Build a denied response for your `serverAuthUrl` webhook. */\nexport function createDeniedServerAuthResponse(reason?: string): ServerAuthDeniedResponse {\n return reason ? { allowed: false, reason } : { allowed: false }\n}\n\n/**\n * Authenticate an incoming `serverAuthUrl` request and return the webhook response\n * body Ark Notify expects.\n */\nexport async function handleServerAuth(\n options: HandleServerAuthOptions\n): Promise<ServerAuthResponse> {\n const decision: ServerAuthDecision = await options.isAuthorized(options.request)\n\n if (decision === false) {\n return createDeniedServerAuthResponse()\n }\n\n const clientId = decision.clientId ?? options.request.client_id\n if (!isValidClientId(clientId)) {\n return createDeniedServerAuthResponse('invalid_client_id')\n }\n\n try {\n return createAuthorizedServerAuthResponse({\n clientId,\n capabilities: decision.capabilities ?? options.request.capabilities ?? undefined,\n ttl: decision.ttl ?? options.request.ttl ?? undefined,\n credentials: options.credentials,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid_request'\n return createDeniedServerAuthResponse(message)\n }\n}\n","export const DEFAULT_BASE_URL = 'https://ark-notify-933303906015.europe-north1.run.app'\n\nlet configuredBaseUrl: string | undefined\n\nexport interface ArkNotifyGlobalConfig {\n baseUrl?: string\n}\n\n/** Set the default base URL once at application startup. */\nexport function configureArkNotify(config: ArkNotifyGlobalConfig): void {\n if (config.baseUrl !== undefined) {\n configuredBaseUrl = config.baseUrl\n }\n}\n\nexport function resolveBaseUrl(baseUrl?: string): string {\n return (baseUrl ?? configuredBaseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n}\n","import type { ApiError } from './types'\n\nexport class ArkNotifyError extends Error {\n readonly status: number\n readonly code: string\n readonly retryAfterSec?: number\n readonly reason?: string\n\n constructor(status: number, body: ApiError) {\n super(body.message)\n this.name = 'ArkNotifyError'\n this.status = status\n this.code = body.error\n this.retryAfterSec = body.retryAfterSec\n this.reason = body.reason\n }\n}\n\nexport function toWebSocketUrl(baseUrl: string, path: string): string {\n const normalizedBase = baseUrl.replace(/\\/$/, '')\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const httpUrl = `${normalizedBase}${normalizedPath}`\n // Avoid URL.protocol — not supported in React Native and some runtimes.\n return httpUrl.replace(/^https:/i, 'wss:').replace(/^http:/i, 'ws:')\n}\n\n/** Append query params without URLSearchParams (unsupported in React Native). */\nexport function appendQueryParams(\n url: string,\n params: Record<string, string | undefined | null | false>\n): string {\n const query = Object.entries(params)\n .filter((entry): entry is [string, string] => {\n const value = entry[1]\n return value !== undefined && value !== null && value !== false && value !== ''\n })\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n\n if (!query) return url\n\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${query}`\n}\n\nexport function resolveValue<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport function isPrivateChannel(channel: string): boolean {\n return channel.startsWith('private-')\n}\n\n/** Whether a server-stream subscription entry is a pattern (`business-*` or `*`). */\nexport function isServerStreamPattern(subscription: string): boolean {\n return subscription === '*' || subscription.endsWith('*')\n}\n\n/** Whether a server-stream subscription entry matches all channels. */\nexport function isAllChannelsSubscription(subscription: string): boolean {\n return subscription === '*'\n}\n\n/** Whether an event channel name matches a server-stream prefix pattern or `*`. */\nexport function matchesChannelPattern(channel: string, pattern: string): boolean {\n if (pattern === '*') return true\n if (!pattern.endsWith('*')) return channel === pattern\n return channel.startsWith(pattern.slice(0, -1))\n}\n","import { resolveBaseUrl } from './config'\nimport type {\n AppCredentials,\n ArkNotifyServerStreamConfig,\n EventMessage,\n PresenceMessage,\n ServerErrorMessage,\n ServerStreamConnectedMessage,\n} from './types'\nimport { appendQueryParams, ArkNotifyError, matchesChannelPattern } from './utils'\n\nconst MAX_SERVER_STREAM_SUBSCRIPTIONS = 32\n\nfunction resolveServerStreamSubscriptions(\n config: Pick<ArkNotifyServerStreamConfig, 'subscriptions' | 'channels'>\n): string[] {\n const subscriptions = config.subscriptions ?? config.channels ?? []\n if (subscriptions.length === 0) {\n throw new Error('At least one subscription is required (exact channel, pattern, or *)')\n }\n if (subscriptions.length > MAX_SERVER_STREAM_SUBSCRIPTIONS) {\n throw new Error(`A maximum of ${MAX_SERVER_STREAM_SUBSCRIPTIONS} subscriptions is allowed per stream`)\n }\n return subscriptions\n}\n\ntype ServerStreamEventMap = {\n connected: (message: ServerStreamConnectedMessage) => void\n event: (message: EventMessage) => void\n presence: (message: PresenceMessage) => void\n message: (message: ServerStreamMessage) => void\n error: (error: Error) => void\n close: () => void\n}\n\ntype ServerStreamEventName = keyof ServerStreamEventMap\n\nfunction buildAppCredentialsHeaders(credentials: AppCredentials): Record<string, string> {\n return {\n 'X-App-Key': credentials.appKey,\n 'X-App-Secret': credentials.secret,\n }\n}\n\ntype ServerStreamMessage = ServerStreamConnectedMessage | EventMessage | PresenceMessage | ServerErrorMessage\n\nfunction dispatchSseEvent(\n data: string,\n handlers: {\n onConnected: (message: ServerStreamConnectedMessage) => void\n onEvent: (message: EventMessage) => void\n onPresence: (message: PresenceMessage) => void\n onMessage: (message: ServerStreamMessage) => void\n }\n): void {\n if (!data) return\n\n let parsed: ServerStreamMessage\n try {\n parsed = JSON.parse(data) as ServerStreamMessage\n } catch {\n return\n }\n\n if (parsed.type === 'connected') {\n handlers.onConnected(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'event') {\n handlers.onEvent(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'presence') {\n handlers.onPresence(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n handlers.onMessage(parsed)\n}\n\nasync function readSseStream(\n body: ReadableStream<Uint8Array>,\n onSseData: (data: string) => void,\n signal: AbortSignal\n): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent: string | null = null\n let dataLines: string[] = []\n\n const flushEvent = () => {\n if (dataLines.length === 0 && currentEvent === null) return\n onSseData(dataLines.join('\\n'))\n currentEvent = null\n dataLines = []\n }\n\n try {\n while (!signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine\n\n if (line === '') {\n flushEvent()\n continue\n }\n\n if (line.startsWith(':')) continue\n\n if (line.startsWith('event:')) {\n currentEvent = line.slice(6).trimStart()\n continue\n }\n\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n }\n\n if (buffer.length > 0) {\n const line = buffer.endsWith('\\r') ? buffer.slice(0, -1) : buffer\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n\n flushEvent()\n } finally {\n reader.releaseLock()\n }\n}\n\nexport class ArkNotifyServerStream {\n private readonly config: ArkNotifyServerStreamConfig & { baseUrl: string; subscriptions: string[] }\n private readonly fetchFn: typeof fetch\n private readonly listeners = new Map<\n ServerStreamEventName,\n Set<ServerStreamEventMap[ServerStreamEventName]>\n >()\n private abortController: AbortController | null = null\n private connectionId: string | null = null\n private connectedMessage: ServerStreamConnectedMessage | null = null\n private connecting = false\n\n constructor(config: ArkNotifyServerStreamConfig) {\n this.config = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n subscriptions: resolveServerStreamSubscriptions(config),\n }\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n getConnectionId(): string | null {\n return this.connectionId\n }\n\n getSubscriptions(): string[] {\n return this.connectedMessage?.subscriptions ?? [...this.config.subscriptions]\n }\n\n getChannels(): string[] {\n return this.connectedMessage?.channels ?? []\n }\n\n getPatterns(): string[] {\n return this.connectedMessage?.patterns ?? []\n }\n\n on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n return () => this.off(event, handler)\n }\n\n off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n private emit<E extends ServerStreamEventName>(\n event: E,\n ...args: Parameters<ServerStreamEventMap[E]>\n ): void {\n for (const handler of this.listeners.get(event) ?? []) {\n ;(handler as (...a: Parameters<ServerStreamEventMap[E]>) => void)(...args)\n }\n }\n\n async connect(): Promise<void> {\n if (this.abortController || this.connecting) return\n\n this.connecting = true\n const abortController = new AbortController()\n this.abortController = abortController\n\n const base = this.config.baseUrl.replace(/\\/$/, '')\n const streamUrl = appendQueryParams(\n `${base}/api/v1/apps/${this.config.appKey}/server-stream`,\n {\n channels: this.config.subscriptions.join(','),\n history: this.config.history ? 'true' : undefined,\n }\n )\n\n try {\n const response = await this.fetchFn(streamUrl, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...buildAppCredentialsHeaders(this.config.credentials),\n },\n signal: abortController.signal,\n })\n\n if (!response.ok) {\n let body: { error: string; message: string; reason?: string; retryAfterSec?: number }\n try {\n body = await response.json()\n } catch {\n body = { error: 'request_failed', message: response.statusText }\n }\n throw new ArkNotifyError(response.status, body)\n }\n\n if (!response.body) {\n throw new Error('Server stream response has no body')\n }\n\n void this.consumeStream(response.body, abortController)\n } catch (err) {\n if (abortController.signal.aborted) return\n this.abortController = null\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n this.emit('close')\n } finally {\n this.connecting = false\n }\n }\n\n private async consumeStream(body: ReadableStream<Uint8Array>, abortController: AbortController): Promise<void> {\n try {\n await readSseStream(\n body,\n (data) => {\n dispatchSseEvent(data, {\n onConnected: (message) => {\n this.connectionId = message.connection_id\n this.connectedMessage = message\n this.emit('connected', message)\n },\n onEvent: (message) => this.emit('event', message),\n onPresence: (message) => this.emit('presence', message),\n onMessage: (message) => this.emit('message', message),\n })\n },\n abortController.signal\n )\n } catch (err) {\n if (abortController.signal.aborted) return\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null\n this.connectionId = null\n this.connectedMessage = null\n this.emit('close')\n }\n }\n }\n\n disconnect(): void {\n if (!this.abortController) return\n this.abortController.abort()\n }\n\n bind(\n channel: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindMatching(\n pattern: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (matchesChannelPattern(message.channel, pattern) && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAllMatching(\n pattern: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (matchesChannelPattern(message.channel, pattern)) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
- import { n as ConnectionCapabilities, q as CreateAuthorizedServerAuthResponseOptions, F as ServerAuthApprovedResponse, I as ServerAuthDeniedResponse, H as HandleServerAuthOptions, K as ServerAuthResponse, J as ServerAuthRequest } from '../types-Aj_RUX12.cjs';
2
- export { S as ServerAuthAllowedResponse, G as ServerAuthDecision, M as ServerAuthTokenResponse } from '../types-Aj_RUX12.cjs';
3
- export { A as ArkNotifyServerStream } from '../server-stream-BK0sRKrW.cjs';
1
+ import { n as ConnectionCapabilities, q as CreateAuthorizedServerAuthResponseOptions, F as ServerAuthApprovedResponse, I as ServerAuthDeniedResponse, H as HandleServerAuthOptions, K as ServerAuthResponse, J as ServerAuthRequest } from '../types-BHemo22a.cjs';
2
+ export { S as ServerAuthAllowedResponse, G as ServerAuthDecision, M as ServerAuthTokenResponse } from '../types-BHemo22a.cjs';
3
+ export { A as ArkNotifyServerStream } from '../server-stream-CxgR5Ym7.cjs';
4
4
 
5
5
  declare function isValidClientId(clientId: unknown): clientId is string;
6
6
  /** Build a signed connection token in Ark Notify format. */
@@ -1,6 +1,6 @@
1
- import { n as ConnectionCapabilities, q as CreateAuthorizedServerAuthResponseOptions, F as ServerAuthApprovedResponse, I as ServerAuthDeniedResponse, H as HandleServerAuthOptions, K as ServerAuthResponse, J as ServerAuthRequest } from '../types-Aj_RUX12.js';
2
- export { S as ServerAuthAllowedResponse, G as ServerAuthDecision, M as ServerAuthTokenResponse } from '../types-Aj_RUX12.js';
3
- export { A as ArkNotifyServerStream } from '../server-stream-Cqe0hzxt.js';
1
+ import { n as ConnectionCapabilities, q as CreateAuthorizedServerAuthResponseOptions, F as ServerAuthApprovedResponse, I as ServerAuthDeniedResponse, H as HandleServerAuthOptions, K as ServerAuthResponse, J as ServerAuthRequest } from '../types-BHemo22a.js';
2
+ export { S as ServerAuthAllowedResponse, G as ServerAuthDecision, M as ServerAuthTokenResponse } from '../types-BHemo22a.js';
3
+ export { A as ArkNotifyServerStream } from '../server-stream-DNd6ENoz.js';
4
4
 
5
5
  declare function isValidClientId(clientId: unknown): clientId is string;
6
6
  /** Build a signed connection token in Ark Notify format. */
@@ -143,8 +143,24 @@ function appendQueryParams(url, params) {
143
143
  const separator = url.includes("?") ? "&" : "?";
144
144
  return `${url}${separator}${query}`;
145
145
  }
146
+ function matchesChannelPattern(channel, pattern) {
147
+ if (pattern === "*") return true;
148
+ if (!pattern.endsWith("*")) return channel === pattern;
149
+ return channel.startsWith(pattern.slice(0, -1));
150
+ }
146
151
 
147
152
  // src/server-stream.ts
153
+ var MAX_SERVER_STREAM_SUBSCRIPTIONS = 32;
154
+ function resolveServerStreamSubscriptions(config) {
155
+ const subscriptions = config.subscriptions ?? config.channels ?? [];
156
+ if (subscriptions.length === 0) {
157
+ throw new Error("At least one subscription is required (exact channel, pattern, or *)");
158
+ }
159
+ if (subscriptions.length > MAX_SERVER_STREAM_SUBSCRIPTIONS) {
160
+ throw new Error(`A maximum of ${MAX_SERVER_STREAM_SUBSCRIPTIONS} subscriptions is allowed per stream`);
161
+ }
162
+ return subscriptions;
163
+ }
148
164
  function buildAppCredentialsHeaders(credentials) {
149
165
  return {
150
166
  "X-App-Key": credentials.appKey,
@@ -227,13 +243,27 @@ var ArkNotifyServerStream = class {
227
243
  this.listeners = /* @__PURE__ */ new Map();
228
244
  this.abortController = null;
229
245
  this.connectionId = null;
246
+ this.connectedMessage = null;
230
247
  this.connecting = false;
231
- this.config = { ...config, baseUrl: resolveBaseUrl(config.baseUrl) };
248
+ this.config = {
249
+ ...config,
250
+ baseUrl: resolveBaseUrl(config.baseUrl),
251
+ subscriptions: resolveServerStreamSubscriptions(config)
252
+ };
232
253
  this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
233
254
  }
234
255
  getConnectionId() {
235
256
  return this.connectionId;
236
257
  }
258
+ getSubscriptions() {
259
+ return this.connectedMessage?.subscriptions ?? [...this.config.subscriptions];
260
+ }
261
+ getChannels() {
262
+ return this.connectedMessage?.channels ?? [];
263
+ }
264
+ getPatterns() {
265
+ return this.connectedMessage?.patterns ?? [];
266
+ }
237
267
  on(event, handler) {
238
268
  if (!this.listeners.has(event)) {
239
269
  this.listeners.set(event, /* @__PURE__ */ new Set());
@@ -258,7 +288,7 @@ var ArkNotifyServerStream = class {
258
288
  const streamUrl = appendQueryParams(
259
289
  `${base}/api/v1/apps/${this.config.appKey}/server-stream`,
260
290
  {
261
- channels: this.config.channels.join(","),
291
+ channels: this.config.subscriptions.join(","),
262
292
  history: this.config.history ? "true" : void 0
263
293
  }
264
294
  );
@@ -301,6 +331,7 @@ var ArkNotifyServerStream = class {
301
331
  dispatchSseEvent(data, {
302
332
  onConnected: (message) => {
303
333
  this.connectionId = message.connection_id;
334
+ this.connectedMessage = message;
304
335
  this.emit("connected", message);
305
336
  },
306
337
  onEvent: (message) => this.emit("event", message),
@@ -317,6 +348,7 @@ var ArkNotifyServerStream = class {
317
348
  if (this.abortController === abortController) {
318
349
  this.abortController = null;
319
350
  this.connectionId = null;
351
+ this.connectedMessage = null;
320
352
  this.emit("close");
321
353
  }
322
354
  }
@@ -341,6 +373,22 @@ var ArkNotifyServerStream = class {
341
373
  };
342
374
  return this.on("event", listener);
343
375
  }
376
+ bindMatching(pattern, event, handler) {
377
+ const listener = (message) => {
378
+ if (matchesChannelPattern(message.channel, pattern) && message.event === event) {
379
+ handler(message.data, message);
380
+ }
381
+ };
382
+ return this.on("event", listener);
383
+ }
384
+ bindAllMatching(pattern, handler) {
385
+ const listener = (message) => {
386
+ if (matchesChannelPattern(message.channel, pattern)) {
387
+ handler(message.data, message);
388
+ }
389
+ };
390
+ return this.on("event", listener);
391
+ }
344
392
  };
345
393
 
346
394
  export { ArkNotifyServerStream, buildConnectionToken, createAuthorizedServerAuthResponse, createDeniedServerAuthResponse, handleServerAuth, isValidClientId, parseServerAuthRequest };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server-auth.ts","../../src/config.ts","../../src/utils.ts","../../src/server-stream.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createHmac } from 'node:crypto'\nimport type {\n ConnectionCapabilities,\n CreateAuthorizedServerAuthResponseOptions,\n HandleServerAuthOptions,\n ServerAuthApprovedResponse,\n ServerAuthDeniedResponse,\n ServerAuthRequest,\n ServerAuthResponse,\n ServerAuthDecision,\n} from './types'\n\nconst CLIENT_ID_PATTERN = /^[a-zA-Z0-9_\\-.@\\+]{1,128}$/\nconst DEFAULT_TTL_SECONDS = 3600\nconst MAX_TTL_SECONDS = 86400\n\nconst DEFAULT_CAPABILITIES: ConnectionCapabilities = {\n subscribe: true,\n publish: true,\n presence: true,\n}\n\nexport function isValidClientId(clientId: unknown): clientId is string {\n return typeof clientId === 'string' && CLIENT_ID_PATTERN.test(clientId)\n}\n\nfunction normalizeCapabilities(\n capabilities?: Partial<ConnectionCapabilities> | null\n): ConnectionCapabilities {\n if (!capabilities || typeof capabilities !== 'object') {\n return { ...DEFAULT_CAPABILITIES }\n }\n\n return {\n subscribe: capabilities.subscribe !== false,\n publish: capabilities.publish !== false,\n presence: capabilities.presence !== false,\n }\n}\n\nfunction resolveTokenTtl(ttl?: number | null): number {\n if (ttl === undefined || ttl === null) {\n return DEFAULT_TTL_SECONDS\n }\n\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error('ttl must be a positive integer (seconds)')\n }\n\n return Math.min(ttl, MAX_TTL_SECONDS)\n}\n\nfunction encodePayload(payload: Record<string, unknown>): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url')\n}\n\nfunction computeConnectionTokenSignature(\n secret: string,\n appKey: string,\n payloadEncoded: string\n): string {\n return createHmac('sha256', secret).update(`${appKey}.${payloadEncoded}`).digest('hex')\n}\n\n/** Build a signed connection token in Ark Notify format. */\nexport function buildConnectionToken(\n appKey: string,\n secret: string,\n options: {\n clientId: string\n exp: number\n capabilities?: Partial<ConnectionCapabilities>\n }\n): string {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const payloadEncoded = encodePayload({\n client_id: options.clientId,\n exp: options.exp,\n capabilities: normalizeCapabilities(options.capabilities),\n })\n\n const signature = computeConnectionTokenSignature(secret, appKey, payloadEncoded)\n return `${appKey}.${payloadEncoded}.${signature}`\n}\n\n/**\n * Parse the JSON body Ark Notify sends to your `serverAuthUrl`.\n * Returns null when the payload is invalid.\n */\nexport function parseServerAuthRequest(body: unknown): ServerAuthRequest | null {\n if (!body || typeof body !== 'object') {\n return null\n }\n\n const record = body as Record<string, unknown>\n const client_id = record.client_id ?? record.clientId\n\n if (!isValidClientId(client_id)) {\n return null\n }\n\n const user_data = record.user_data ?? record.userData\n const capabilities = record.capabilities\n const ttl = record.ttl\n\n return {\n client_id,\n user_data:\n user_data === undefined\n ? null\n : user_data && typeof user_data === 'object'\n ? (user_data as Record<string, unknown>)\n : null,\n capabilities:\n capabilities && typeof capabilities === 'object'\n ? (capabilities as Partial<ConnectionCapabilities>)\n : null,\n ttl: typeof ttl === 'number' ? ttl : null,\n }\n}\n\n/**\n * Build an approved response for your `serverAuthUrl` webhook.\n *\n * - Without `credentials`: returns `{ allowed: true, client_id, ... }` (option A).\n * - With `credentials`: returns `{ token }` with a pre-signed token (option B).\n */\nexport function createAuthorizedServerAuthResponse(\n options: CreateAuthorizedServerAuthResponseOptions\n): ServerAuthApprovedResponse {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const capabilities = normalizeCapabilities(options.capabilities)\n const ttl = resolveTokenTtl(options.ttl)\n\n if (options.credentials) {\n const exp = Math.floor(Date.now() / 1000) + ttl\n return {\n token: buildConnectionToken(options.credentials.appKey, options.credentials.secret, {\n clientId: options.clientId,\n exp,\n capabilities,\n }),\n }\n }\n\n return {\n allowed: true,\n client_id: options.clientId,\n capabilities,\n ttl,\n }\n}\n\n/** Build a denied response for your `serverAuthUrl` webhook. */\nexport function createDeniedServerAuthResponse(reason?: string): ServerAuthDeniedResponse {\n return reason ? { allowed: false, reason } : { allowed: false }\n}\n\n/**\n * Authenticate an incoming `serverAuthUrl` request and return the webhook response\n * body Ark Notify expects.\n */\nexport async function handleServerAuth(\n options: HandleServerAuthOptions\n): Promise<ServerAuthResponse> {\n const decision: ServerAuthDecision = await options.isAuthorized(options.request)\n\n if (decision === false) {\n return createDeniedServerAuthResponse()\n }\n\n const clientId = decision.clientId ?? options.request.client_id\n if (!isValidClientId(clientId)) {\n return createDeniedServerAuthResponse('invalid_client_id')\n }\n\n try {\n return createAuthorizedServerAuthResponse({\n clientId,\n capabilities: decision.capabilities ?? options.request.capabilities ?? undefined,\n ttl: decision.ttl ?? options.request.ttl ?? undefined,\n credentials: options.credentials,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid_request'\n return createDeniedServerAuthResponse(message)\n }\n}\n","export const DEFAULT_BASE_URL = 'https://ark-notify-933303906015.europe-north1.run.app'\n\nlet configuredBaseUrl: string | undefined\n\nexport interface ArkNotifyGlobalConfig {\n baseUrl?: string\n}\n\n/** Set the default base URL once at application startup. */\nexport function configureArkNotify(config: ArkNotifyGlobalConfig): void {\n if (config.baseUrl !== undefined) {\n configuredBaseUrl = config.baseUrl\n }\n}\n\nexport function resolveBaseUrl(baseUrl?: string): string {\n return (baseUrl ?? configuredBaseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n}\n","import type { ApiError } from './types'\n\nexport class ArkNotifyError extends Error {\n readonly status: number\n readonly code: string\n readonly retryAfterSec?: number\n readonly reason?: string\n\n constructor(status: number, body: ApiError) {\n super(body.message)\n this.name = 'ArkNotifyError'\n this.status = status\n this.code = body.error\n this.retryAfterSec = body.retryAfterSec\n this.reason = body.reason\n }\n}\n\nexport function toWebSocketUrl(baseUrl: string, path: string): string {\n const normalizedBase = baseUrl.replace(/\\/$/, '')\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const httpUrl = `${normalizedBase}${normalizedPath}`\n // Avoid URL.protocol — not supported in React Native and some runtimes.\n return httpUrl.replace(/^https:/i, 'wss:').replace(/^http:/i, 'ws:')\n}\n\n/** Append query params without URLSearchParams (unsupported in React Native). */\nexport function appendQueryParams(\n url: string,\n params: Record<string, string | undefined | null | false>\n): string {\n const query = Object.entries(params)\n .filter((entry): entry is [string, string] => {\n const value = entry[1]\n return value !== undefined && value !== null && value !== false && value !== ''\n })\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n\n if (!query) return url\n\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${query}`\n}\n\nexport function resolveValue<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport function isPrivateChannel(channel: string): boolean {\n return channel.startsWith('private-')\n}\n","import { resolveBaseUrl } from './config'\nimport type {\n AppCredentials,\n ArkNotifyServerStreamConfig,\n EventMessage,\n PresenceMessage,\n ServerErrorMessage,\n ServerStreamConnectedMessage,\n} from './types'\nimport { appendQueryParams, ArkNotifyError } from './utils'\n\ntype ServerStreamEventMap = {\n connected: (message: ServerStreamConnectedMessage) => void\n event: (message: EventMessage) => void\n presence: (message: PresenceMessage) => void\n message: (message: ServerStreamMessage) => void\n error: (error: Error) => void\n close: () => void\n}\n\ntype ServerStreamEventName = keyof ServerStreamEventMap\n\nfunction buildAppCredentialsHeaders(credentials: AppCredentials): Record<string, string> {\n return {\n 'X-App-Key': credentials.appKey,\n 'X-App-Secret': credentials.secret,\n }\n}\n\ntype ServerStreamMessage = ServerStreamConnectedMessage | EventMessage | PresenceMessage | ServerErrorMessage\n\nfunction dispatchSseEvent(\n data: string,\n handlers: {\n onConnected: (message: ServerStreamConnectedMessage) => void\n onEvent: (message: EventMessage) => void\n onPresence: (message: PresenceMessage) => void\n onMessage: (message: ServerStreamMessage) => void\n }\n): void {\n if (!data) return\n\n let parsed: ServerStreamMessage\n try {\n parsed = JSON.parse(data) as ServerStreamMessage\n } catch {\n return\n }\n\n if (parsed.type === 'connected') {\n handlers.onConnected(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'event') {\n handlers.onEvent(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'presence') {\n handlers.onPresence(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n handlers.onMessage(parsed)\n}\n\nasync function readSseStream(\n body: ReadableStream<Uint8Array>,\n onSseData: (data: string) => void,\n signal: AbortSignal\n): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent: string | null = null\n let dataLines: string[] = []\n\n const flushEvent = () => {\n if (dataLines.length === 0 && currentEvent === null) return\n onSseData(dataLines.join('\\n'))\n currentEvent = null\n dataLines = []\n }\n\n try {\n while (!signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine\n\n if (line === '') {\n flushEvent()\n continue\n }\n\n if (line.startsWith(':')) continue\n\n if (line.startsWith('event:')) {\n currentEvent = line.slice(6).trimStart()\n continue\n }\n\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n }\n\n if (buffer.length > 0) {\n const line = buffer.endsWith('\\r') ? buffer.slice(0, -1) : buffer\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n\n flushEvent()\n } finally {\n reader.releaseLock()\n }\n}\n\nexport class ArkNotifyServerStream {\n private readonly config: ArkNotifyServerStreamConfig & { baseUrl: string }\n private readonly fetchFn: typeof fetch\n private readonly listeners = new Map<\n ServerStreamEventName,\n Set<ServerStreamEventMap[ServerStreamEventName]>\n >()\n private abortController: AbortController | null = null\n private connectionId: string | null = null\n private connecting = false\n\n constructor(config: ArkNotifyServerStreamConfig) {\n this.config = { ...config, baseUrl: resolveBaseUrl(config.baseUrl) }\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n getConnectionId(): string | null {\n return this.connectionId\n }\n\n on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n return () => this.off(event, handler)\n }\n\n off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n private emit<E extends ServerStreamEventName>(\n event: E,\n ...args: Parameters<ServerStreamEventMap[E]>\n ): void {\n for (const handler of this.listeners.get(event) ?? []) {\n ;(handler as (...a: Parameters<ServerStreamEventMap[E]>) => void)(...args)\n }\n }\n\n async connect(): Promise<void> {\n if (this.abortController || this.connecting) return\n\n this.connecting = true\n const abortController = new AbortController()\n this.abortController = abortController\n\n const base = this.config.baseUrl.replace(/\\/$/, '')\n const streamUrl = appendQueryParams(\n `${base}/api/v1/apps/${this.config.appKey}/server-stream`,\n {\n channels: this.config.channels.join(','),\n history: this.config.history ? 'true' : undefined,\n }\n )\n\n try {\n const response = await this.fetchFn(streamUrl, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...buildAppCredentialsHeaders(this.config.credentials),\n },\n signal: abortController.signal,\n })\n\n if (!response.ok) {\n let body: { error: string; message: string; reason?: string; retryAfterSec?: number }\n try {\n body = await response.json()\n } catch {\n body = { error: 'request_failed', message: response.statusText }\n }\n throw new ArkNotifyError(response.status, body)\n }\n\n if (!response.body) {\n throw new Error('Server stream response has no body')\n }\n\n void this.consumeStream(response.body, abortController)\n } catch (err) {\n if (abortController.signal.aborted) return\n this.abortController = null\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n this.emit('close')\n } finally {\n this.connecting = false\n }\n }\n\n private async consumeStream(body: ReadableStream<Uint8Array>, abortController: AbortController): Promise<void> {\n try {\n await readSseStream(\n body,\n (data) => {\n dispatchSseEvent(data, {\n onConnected: (message) => {\n this.connectionId = message.connection_id\n this.emit('connected', message)\n },\n onEvent: (message) => this.emit('event', message),\n onPresence: (message) => this.emit('presence', message),\n onMessage: (message) => this.emit('message', message),\n })\n },\n abortController.signal\n )\n } catch (err) {\n if (abortController.signal.aborted) return\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null\n this.connectionId = null\n this.emit('close')\n }\n }\n }\n\n disconnect(): void {\n if (!this.abortController) return\n this.abortController.abort()\n }\n\n bind(\n channel: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/server-auth.ts","../../src/config.ts","../../src/utils.ts","../../src/server-stream.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createHmac } from 'node:crypto'\nimport type {\n ConnectionCapabilities,\n CreateAuthorizedServerAuthResponseOptions,\n HandleServerAuthOptions,\n ServerAuthApprovedResponse,\n ServerAuthDeniedResponse,\n ServerAuthRequest,\n ServerAuthResponse,\n ServerAuthDecision,\n} from './types'\n\nconst CLIENT_ID_PATTERN = /^[a-zA-Z0-9_\\-.@\\+]{1,128}$/\nconst DEFAULT_TTL_SECONDS = 3600\nconst MAX_TTL_SECONDS = 86400\n\nconst DEFAULT_CAPABILITIES: ConnectionCapabilities = {\n subscribe: true,\n publish: true,\n presence: true,\n}\n\nexport function isValidClientId(clientId: unknown): clientId is string {\n return typeof clientId === 'string' && CLIENT_ID_PATTERN.test(clientId)\n}\n\nfunction normalizeCapabilities(\n capabilities?: Partial<ConnectionCapabilities> | null\n): ConnectionCapabilities {\n if (!capabilities || typeof capabilities !== 'object') {\n return { ...DEFAULT_CAPABILITIES }\n }\n\n return {\n subscribe: capabilities.subscribe !== false,\n publish: capabilities.publish !== false,\n presence: capabilities.presence !== false,\n }\n}\n\nfunction resolveTokenTtl(ttl?: number | null): number {\n if (ttl === undefined || ttl === null) {\n return DEFAULT_TTL_SECONDS\n }\n\n if (!Number.isInteger(ttl) || ttl <= 0) {\n throw new Error('ttl must be a positive integer (seconds)')\n }\n\n return Math.min(ttl, MAX_TTL_SECONDS)\n}\n\nfunction encodePayload(payload: Record<string, unknown>): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url')\n}\n\nfunction computeConnectionTokenSignature(\n secret: string,\n appKey: string,\n payloadEncoded: string\n): string {\n return createHmac('sha256', secret).update(`${appKey}.${payloadEncoded}`).digest('hex')\n}\n\n/** Build a signed connection token in Ark Notify format. */\nexport function buildConnectionToken(\n appKey: string,\n secret: string,\n options: {\n clientId: string\n exp: number\n capabilities?: Partial<ConnectionCapabilities>\n }\n): string {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const payloadEncoded = encodePayload({\n client_id: options.clientId,\n exp: options.exp,\n capabilities: normalizeCapabilities(options.capabilities),\n })\n\n const signature = computeConnectionTokenSignature(secret, appKey, payloadEncoded)\n return `${appKey}.${payloadEncoded}.${signature}`\n}\n\n/**\n * Parse the JSON body Ark Notify sends to your `serverAuthUrl`.\n * Returns null when the payload is invalid.\n */\nexport function parseServerAuthRequest(body: unknown): ServerAuthRequest | null {\n if (!body || typeof body !== 'object') {\n return null\n }\n\n const record = body as Record<string, unknown>\n const client_id = record.client_id ?? record.clientId\n\n if (!isValidClientId(client_id)) {\n return null\n }\n\n const user_data = record.user_data ?? record.userData\n const capabilities = record.capabilities\n const ttl = record.ttl\n\n return {\n client_id,\n user_data:\n user_data === undefined\n ? null\n : user_data && typeof user_data === 'object'\n ? (user_data as Record<string, unknown>)\n : null,\n capabilities:\n capabilities && typeof capabilities === 'object'\n ? (capabilities as Partial<ConnectionCapabilities>)\n : null,\n ttl: typeof ttl === 'number' ? ttl : null,\n }\n}\n\n/**\n * Build an approved response for your `serverAuthUrl` webhook.\n *\n * - Without `credentials`: returns `{ allowed: true, client_id, ... }` (option A).\n * - With `credentials`: returns `{ token }` with a pre-signed token (option B).\n */\nexport function createAuthorizedServerAuthResponse(\n options: CreateAuthorizedServerAuthResponseOptions\n): ServerAuthApprovedResponse {\n if (!isValidClientId(options.clientId)) {\n throw new Error('clientId must be 1-128 alphanumeric characters')\n }\n\n const capabilities = normalizeCapabilities(options.capabilities)\n const ttl = resolveTokenTtl(options.ttl)\n\n if (options.credentials) {\n const exp = Math.floor(Date.now() / 1000) + ttl\n return {\n token: buildConnectionToken(options.credentials.appKey, options.credentials.secret, {\n clientId: options.clientId,\n exp,\n capabilities,\n }),\n }\n }\n\n return {\n allowed: true,\n client_id: options.clientId,\n capabilities,\n ttl,\n }\n}\n\n/** Build a denied response for your `serverAuthUrl` webhook. */\nexport function createDeniedServerAuthResponse(reason?: string): ServerAuthDeniedResponse {\n return reason ? { allowed: false, reason } : { allowed: false }\n}\n\n/**\n * Authenticate an incoming `serverAuthUrl` request and return the webhook response\n * body Ark Notify expects.\n */\nexport async function handleServerAuth(\n options: HandleServerAuthOptions\n): Promise<ServerAuthResponse> {\n const decision: ServerAuthDecision = await options.isAuthorized(options.request)\n\n if (decision === false) {\n return createDeniedServerAuthResponse()\n }\n\n const clientId = decision.clientId ?? options.request.client_id\n if (!isValidClientId(clientId)) {\n return createDeniedServerAuthResponse('invalid_client_id')\n }\n\n try {\n return createAuthorizedServerAuthResponse({\n clientId,\n capabilities: decision.capabilities ?? options.request.capabilities ?? undefined,\n ttl: decision.ttl ?? options.request.ttl ?? undefined,\n credentials: options.credentials,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : 'invalid_request'\n return createDeniedServerAuthResponse(message)\n }\n}\n","export const DEFAULT_BASE_URL = 'https://ark-notify-933303906015.europe-north1.run.app'\n\nlet configuredBaseUrl: string | undefined\n\nexport interface ArkNotifyGlobalConfig {\n baseUrl?: string\n}\n\n/** Set the default base URL once at application startup. */\nexport function configureArkNotify(config: ArkNotifyGlobalConfig): void {\n if (config.baseUrl !== undefined) {\n configuredBaseUrl = config.baseUrl\n }\n}\n\nexport function resolveBaseUrl(baseUrl?: string): string {\n return (baseUrl ?? configuredBaseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n}\n","import type { ApiError } from './types'\n\nexport class ArkNotifyError extends Error {\n readonly status: number\n readonly code: string\n readonly retryAfterSec?: number\n readonly reason?: string\n\n constructor(status: number, body: ApiError) {\n super(body.message)\n this.name = 'ArkNotifyError'\n this.status = status\n this.code = body.error\n this.retryAfterSec = body.retryAfterSec\n this.reason = body.reason\n }\n}\n\nexport function toWebSocketUrl(baseUrl: string, path: string): string {\n const normalizedBase = baseUrl.replace(/\\/$/, '')\n const normalizedPath = path.startsWith('/') ? path : `/${path}`\n const httpUrl = `${normalizedBase}${normalizedPath}`\n // Avoid URL.protocol — not supported in React Native and some runtimes.\n return httpUrl.replace(/^https:/i, 'wss:').replace(/^http:/i, 'ws:')\n}\n\n/** Append query params without URLSearchParams (unsupported in React Native). */\nexport function appendQueryParams(\n url: string,\n params: Record<string, string | undefined | null | false>\n): string {\n const query = Object.entries(params)\n .filter((entry): entry is [string, string] => {\n const value = entry[1]\n return value !== undefined && value !== null && value !== false && value !== ''\n })\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n\n if (!query) return url\n\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}${query}`\n}\n\nexport function resolveValue<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value\n}\n\nexport function isPrivateChannel(channel: string): boolean {\n return channel.startsWith('private-')\n}\n\n/** Whether a server-stream subscription entry is a pattern (`business-*` or `*`). */\nexport function isServerStreamPattern(subscription: string): boolean {\n return subscription === '*' || subscription.endsWith('*')\n}\n\n/** Whether a server-stream subscription entry matches all channels. */\nexport function isAllChannelsSubscription(subscription: string): boolean {\n return subscription === '*'\n}\n\n/** Whether an event channel name matches a server-stream prefix pattern or `*`. */\nexport function matchesChannelPattern(channel: string, pattern: string): boolean {\n if (pattern === '*') return true\n if (!pattern.endsWith('*')) return channel === pattern\n return channel.startsWith(pattern.slice(0, -1))\n}\n","import { resolveBaseUrl } from './config'\nimport type {\n AppCredentials,\n ArkNotifyServerStreamConfig,\n EventMessage,\n PresenceMessage,\n ServerErrorMessage,\n ServerStreamConnectedMessage,\n} from './types'\nimport { appendQueryParams, ArkNotifyError, matchesChannelPattern } from './utils'\n\nconst MAX_SERVER_STREAM_SUBSCRIPTIONS = 32\n\nfunction resolveServerStreamSubscriptions(\n config: Pick<ArkNotifyServerStreamConfig, 'subscriptions' | 'channels'>\n): string[] {\n const subscriptions = config.subscriptions ?? config.channels ?? []\n if (subscriptions.length === 0) {\n throw new Error('At least one subscription is required (exact channel, pattern, or *)')\n }\n if (subscriptions.length > MAX_SERVER_STREAM_SUBSCRIPTIONS) {\n throw new Error(`A maximum of ${MAX_SERVER_STREAM_SUBSCRIPTIONS} subscriptions is allowed per stream`)\n }\n return subscriptions\n}\n\ntype ServerStreamEventMap = {\n connected: (message: ServerStreamConnectedMessage) => void\n event: (message: EventMessage) => void\n presence: (message: PresenceMessage) => void\n message: (message: ServerStreamMessage) => void\n error: (error: Error) => void\n close: () => void\n}\n\ntype ServerStreamEventName = keyof ServerStreamEventMap\n\nfunction buildAppCredentialsHeaders(credentials: AppCredentials): Record<string, string> {\n return {\n 'X-App-Key': credentials.appKey,\n 'X-App-Secret': credentials.secret,\n }\n}\n\ntype ServerStreamMessage = ServerStreamConnectedMessage | EventMessage | PresenceMessage | ServerErrorMessage\n\nfunction dispatchSseEvent(\n data: string,\n handlers: {\n onConnected: (message: ServerStreamConnectedMessage) => void\n onEvent: (message: EventMessage) => void\n onPresence: (message: PresenceMessage) => void\n onMessage: (message: ServerStreamMessage) => void\n }\n): void {\n if (!data) return\n\n let parsed: ServerStreamMessage\n try {\n parsed = JSON.parse(data) as ServerStreamMessage\n } catch {\n return\n }\n\n if (parsed.type === 'connected') {\n handlers.onConnected(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'event') {\n handlers.onEvent(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n if (parsed.type === 'presence') {\n handlers.onPresence(parsed)\n handlers.onMessage(parsed)\n return\n }\n\n handlers.onMessage(parsed)\n}\n\nasync function readSseStream(\n body: ReadableStream<Uint8Array>,\n onSseData: (data: string) => void,\n signal: AbortSignal\n): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent: string | null = null\n let dataLines: string[] = []\n\n const flushEvent = () => {\n if (dataLines.length === 0 && currentEvent === null) return\n onSseData(dataLines.join('\\n'))\n currentEvent = null\n dataLines = []\n }\n\n try {\n while (!signal.aborted) {\n const { done, value } = await reader.read()\n if (done) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith('\\r') ? rawLine.slice(0, -1) : rawLine\n\n if (line === '') {\n flushEvent()\n continue\n }\n\n if (line.startsWith(':')) continue\n\n if (line.startsWith('event:')) {\n currentEvent = line.slice(6).trimStart()\n continue\n }\n\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n }\n\n if (buffer.length > 0) {\n const line = buffer.endsWith('\\r') ? buffer.slice(0, -1) : buffer\n if (line.startsWith('data:')) {\n dataLines.push(line.slice(5).trimStart())\n }\n }\n\n flushEvent()\n } finally {\n reader.releaseLock()\n }\n}\n\nexport class ArkNotifyServerStream {\n private readonly config: ArkNotifyServerStreamConfig & { baseUrl: string; subscriptions: string[] }\n private readonly fetchFn: typeof fetch\n private readonly listeners = new Map<\n ServerStreamEventName,\n Set<ServerStreamEventMap[ServerStreamEventName]>\n >()\n private abortController: AbortController | null = null\n private connectionId: string | null = null\n private connectedMessage: ServerStreamConnectedMessage | null = null\n private connecting = false\n\n constructor(config: ArkNotifyServerStreamConfig) {\n this.config = {\n ...config,\n baseUrl: resolveBaseUrl(config.baseUrl),\n subscriptions: resolveServerStreamSubscriptions(config),\n }\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis)\n }\n\n getConnectionId(): string | null {\n return this.connectionId\n }\n\n getSubscriptions(): string[] {\n return this.connectedMessage?.subscriptions ?? [...this.config.subscriptions]\n }\n\n getChannels(): string[] {\n return this.connectedMessage?.channels ?? []\n }\n\n getPatterns(): string[] {\n return this.connectedMessage?.patterns ?? []\n }\n\n on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set())\n }\n this.listeners.get(event)!.add(handler)\n return () => this.off(event, handler)\n }\n\n off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void {\n this.listeners.get(event)?.delete(handler)\n }\n\n private emit<E extends ServerStreamEventName>(\n event: E,\n ...args: Parameters<ServerStreamEventMap[E]>\n ): void {\n for (const handler of this.listeners.get(event) ?? []) {\n ;(handler as (...a: Parameters<ServerStreamEventMap[E]>) => void)(...args)\n }\n }\n\n async connect(): Promise<void> {\n if (this.abortController || this.connecting) return\n\n this.connecting = true\n const abortController = new AbortController()\n this.abortController = abortController\n\n const base = this.config.baseUrl.replace(/\\/$/, '')\n const streamUrl = appendQueryParams(\n `${base}/api/v1/apps/${this.config.appKey}/server-stream`,\n {\n channels: this.config.subscriptions.join(','),\n history: this.config.history ? 'true' : undefined,\n }\n )\n\n try {\n const response = await this.fetchFn(streamUrl, {\n method: 'GET',\n headers: {\n Accept: 'text/event-stream',\n ...buildAppCredentialsHeaders(this.config.credentials),\n },\n signal: abortController.signal,\n })\n\n if (!response.ok) {\n let body: { error: string; message: string; reason?: string; retryAfterSec?: number }\n try {\n body = await response.json()\n } catch {\n body = { error: 'request_failed', message: response.statusText }\n }\n throw new ArkNotifyError(response.status, body)\n }\n\n if (!response.body) {\n throw new Error('Server stream response has no body')\n }\n\n void this.consumeStream(response.body, abortController)\n } catch (err) {\n if (abortController.signal.aborted) return\n this.abortController = null\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n this.emit('close')\n } finally {\n this.connecting = false\n }\n }\n\n private async consumeStream(body: ReadableStream<Uint8Array>, abortController: AbortController): Promise<void> {\n try {\n await readSseStream(\n body,\n (data) => {\n dispatchSseEvent(data, {\n onConnected: (message) => {\n this.connectionId = message.connection_id\n this.connectedMessage = message\n this.emit('connected', message)\n },\n onEvent: (message) => this.emit('event', message),\n onPresence: (message) => this.emit('presence', message),\n onMessage: (message) => this.emit('message', message),\n })\n },\n abortController.signal\n )\n } catch (err) {\n if (abortController.signal.aborted) return\n this.emit('error', err instanceof Error ? err : new Error(String(err)))\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null\n this.connectionId = null\n this.connectedMessage = null\n this.emit('close')\n }\n }\n }\n\n disconnect(): void {\n if (!this.abortController) return\n this.abortController.abort()\n }\n\n bind(\n channel: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void {\n const listener = (message: EventMessage) => {\n if (message.channel === channel) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindMatching(\n pattern: string,\n event: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (matchesChannelPattern(message.channel, pattern) && message.event === event) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n\n bindAllMatching(\n pattern: string,\n handler: (data: unknown, message: EventMessage) => void\n ): () => void {\n const listener = (message: EventMessage) => {\n if (matchesChannelPattern(message.channel, pattern)) {\n handler(message.data, message)\n }\n }\n return this.on('event', listener)\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { g as ArkNotifyServerStreamConfig, Q as ServerStreamConnectedMessage, E as EventMessage, w as PresenceMessage, N as ServerErrorMessage } from './types-Aj_RUX12.js';
1
+ import { g as ArkNotifyServerStreamConfig, Q as ServerStreamConnectedMessage, E as EventMessage, w as PresenceMessage, N as ServerErrorMessage } from './types-BHemo22a.cjs';
2
2
 
3
3
  type ServerStreamEventMap = {
4
4
  connected: (message: ServerStreamConnectedMessage) => void;
@@ -16,9 +16,13 @@ declare class ArkNotifyServerStream {
16
16
  private readonly listeners;
17
17
  private abortController;
18
18
  private connectionId;
19
+ private connectedMessage;
19
20
  private connecting;
20
21
  constructor(config: ArkNotifyServerStreamConfig);
21
22
  getConnectionId(): string | null;
23
+ getSubscriptions(): string[];
24
+ getChannels(): string[];
25
+ getPatterns(): string[];
22
26
  on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void;
23
27
  off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void;
24
28
  private emit;
@@ -27,6 +31,8 @@ declare class ArkNotifyServerStream {
27
31
  disconnect(): void;
28
32
  bind(channel: string, event: string, handler: (data: unknown, message: EventMessage) => void): () => void;
29
33
  bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void;
34
+ bindMatching(pattern: string, event: string, handler: (data: unknown, message: EventMessage) => void): () => void;
35
+ bindAllMatching(pattern: string, handler: (data: unknown, message: EventMessage) => void): () => void;
30
36
  }
31
37
 
32
38
  export { ArkNotifyServerStream as A };
@@ -1,4 +1,4 @@
1
- import { g as ArkNotifyServerStreamConfig, Q as ServerStreamConnectedMessage, E as EventMessage, w as PresenceMessage, N as ServerErrorMessage } from './types-Aj_RUX12.cjs';
1
+ import { g as ArkNotifyServerStreamConfig, Q as ServerStreamConnectedMessage, E as EventMessage, w as PresenceMessage, N as ServerErrorMessage } from './types-BHemo22a.js';
2
2
 
3
3
  type ServerStreamEventMap = {
4
4
  connected: (message: ServerStreamConnectedMessage) => void;
@@ -16,9 +16,13 @@ declare class ArkNotifyServerStream {
16
16
  private readonly listeners;
17
17
  private abortController;
18
18
  private connectionId;
19
+ private connectedMessage;
19
20
  private connecting;
20
21
  constructor(config: ArkNotifyServerStreamConfig);
21
22
  getConnectionId(): string | null;
23
+ getSubscriptions(): string[];
24
+ getChannels(): string[];
25
+ getPatterns(): string[];
22
26
  on<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): () => void;
23
27
  off<E extends ServerStreamEventName>(event: E, handler: ServerStreamEventMap[E]): void;
24
28
  private emit;
@@ -27,6 +31,8 @@ declare class ArkNotifyServerStream {
27
31
  disconnect(): void;
28
32
  bind(channel: string, event: string, handler: (data: unknown, message: EventMessage) => void): () => void;
29
33
  bindAll(channel: string, handler: (data: unknown, message: EventMessage) => void): () => void;
34
+ bindMatching(pattern: string, event: string, handler: (data: unknown, message: EventMessage) => void): () => void;
35
+ bindAllMatching(pattern: string, handler: (data: unknown, message: EventMessage) => void): () => void;
30
36
  }
31
37
 
32
38
  export { ArkNotifyServerStream as A };
@@ -142,7 +142,12 @@ interface ServerStreamConnectedMessage {
142
142
  type: 'connected';
143
143
  connection_id: string;
144
144
  app_key: string;
145
+ /** Exact channel names subscribed on this stream. */
145
146
  channels: string[];
147
+ /** Prefix patterns (`business-*`) or `*` for all channels. */
148
+ patterns: string[];
149
+ /** Combined list passed in the `channels` query param. */
150
+ subscriptions: string[];
146
151
  transport: 'server-stream';
147
152
  }
148
153
  interface EventMessage {
@@ -254,7 +259,14 @@ interface ArkNotifyServerStreamConfig {
254
259
  baseUrl?: string;
255
260
  appKey: string;
256
261
  credentials: AppCredentials;
257
- channels: string[];
262
+ /**
263
+ * Channel subscriptions: exact names (`room-1`), prefix patterns (`business-*`),
264
+ * or `*` for all channels. Max 32 entries.
265
+ */
266
+ subscriptions?: string[];
267
+ /** @deprecated Use `subscriptions`. */
268
+ channels?: string[];
269
+ /** Replay stored messages for exact channel names only (not patterns or `*`). */
258
270
  history?: boolean;
259
271
  fetch?: typeof fetch;
260
272
  }
@@ -142,7 +142,12 @@ interface ServerStreamConnectedMessage {
142
142
  type: 'connected';
143
143
  connection_id: string;
144
144
  app_key: string;
145
+ /** Exact channel names subscribed on this stream. */
145
146
  channels: string[];
147
+ /** Prefix patterns (`business-*`) or `*` for all channels. */
148
+ patterns: string[];
149
+ /** Combined list passed in the `channels` query param. */
150
+ subscriptions: string[];
146
151
  transport: 'server-stream';
147
152
  }
148
153
  interface EventMessage {
@@ -254,7 +259,14 @@ interface ArkNotifyServerStreamConfig {
254
259
  baseUrl?: string;
255
260
  appKey: string;
256
261
  credentials: AppCredentials;
257
- channels: string[];
262
+ /**
263
+ * Channel subscriptions: exact names (`room-1`), prefix patterns (`business-*`),
264
+ * or `*` for all channels. Max 32 entries.
265
+ */
266
+ subscriptions?: string[];
267
+ /** @deprecated Use `subscriptions`. */
268
+ channels?: string[];
269
+ /** Replay stored messages for exact channel names only (not patterns or `*`). */
258
270
  history?: boolean;
259
271
  fetch?: typeof fetch;
260
272
  }
@@ -1,4 +1,4 @@
1
- import { d as ArkNotifyClientConfig, r as HealthResponse, L as LoginInput, h as AuthResponse, W as User, c as Application, p as CreateApplicationInput, V as UpdateApplicationInput, A as AppCredentials, z as PublishEventInput, B as PublishEventResponse, i as ChannelAuthInput, j as ChannelAuthResponse, C as ConnectionTokenInput, a as ConnectionTokenResponse, e as ArkNotifyConnectionConfig, o as ConnectionState, m as ConnectedMessage, E as EventMessage, w as PresenceMessage, O as ServerMessage, R as SubscribeOptions, k as ChannelEventHandler, f as ArkNotifySSEConfig, b as ApiError } from './types-Aj_RUX12.js';
1
+ import { d as ArkNotifyClientConfig, r as HealthResponse, L as LoginInput, h as AuthResponse, W as User, c as Application, p as CreateApplicationInput, V as UpdateApplicationInput, A as AppCredentials, z as PublishEventInput, B as PublishEventResponse, i as ChannelAuthInput, j as ChannelAuthResponse, C as ConnectionTokenInput, a as ConnectionTokenResponse, e as ArkNotifyConnectionConfig, o as ConnectionState, m as ConnectedMessage, E as EventMessage, w as PresenceMessage, O as ServerMessage, R as SubscribeOptions, k as ChannelEventHandler, f as ArkNotifySSEConfig, b as ApiError } from './types-BHemo22a.js';
2
2
 
3
3
  declare const DEFAULT_BASE_URL = "https://ark-notify-933303906015.europe-north1.run.app";
4
4
  interface ArkNotifyGlobalConfig {
@@ -144,5 +144,11 @@ declare function toWebSocketUrl(baseUrl: string, path: string): string;
144
144
  declare function appendQueryParams(url: string, params: Record<string, string | undefined | null | false>): string;
145
145
  declare function resolveValue<T>(value: T | (() => T)): T;
146
146
  declare function isPrivateChannel(channel: string): boolean;
147
+ /** Whether a server-stream subscription entry is a pattern (`business-*` or `*`). */
148
+ declare function isServerStreamPattern(subscription: string): boolean;
149
+ /** Whether a server-stream subscription entry matches all channels. */
150
+ declare function isAllChannelsSubscription(subscription: string): boolean;
151
+ /** Whether an event channel name matches a server-stream prefix pattern or `*`. */
152
+ declare function matchesChannelPattern(channel: string, pattern: string): boolean;
147
153
 
148
- export { ArkNotifyClient as A, DEFAULT_BASE_URL as D, ArkNotifyConnection as a, ArkNotifyError as b, type ArkNotifyGlobalConfig as c, ArkNotifySSE as d, appendQueryParams as e, configureArkNotify as f, resolveValue as g, isPrivateChannel as i, resolveBaseUrl as r, toWebSocketUrl as t };
154
+ export { ArkNotifyClient as A, DEFAULT_BASE_URL as D, ArkNotifyConnection as a, ArkNotifyError as b, type ArkNotifyGlobalConfig as c, ArkNotifySSE as d, appendQueryParams as e, configureArkNotify as f, isPrivateChannel as g, isServerStreamPattern as h, isAllChannelsSubscription as i, resolveValue as j, matchesChannelPattern as m, resolveBaseUrl as r, toWebSocketUrl as t };
@@ -1,4 +1,4 @@
1
- import { d as ArkNotifyClientConfig, r as HealthResponse, L as LoginInput, h as AuthResponse, W as User, c as Application, p as CreateApplicationInput, V as UpdateApplicationInput, A as AppCredentials, z as PublishEventInput, B as PublishEventResponse, i as ChannelAuthInput, j as ChannelAuthResponse, C as ConnectionTokenInput, a as ConnectionTokenResponse, e as ArkNotifyConnectionConfig, o as ConnectionState, m as ConnectedMessage, E as EventMessage, w as PresenceMessage, O as ServerMessage, R as SubscribeOptions, k as ChannelEventHandler, f as ArkNotifySSEConfig, b as ApiError } from './types-Aj_RUX12.cjs';
1
+ import { d as ArkNotifyClientConfig, r as HealthResponse, L as LoginInput, h as AuthResponse, W as User, c as Application, p as CreateApplicationInput, V as UpdateApplicationInput, A as AppCredentials, z as PublishEventInput, B as PublishEventResponse, i as ChannelAuthInput, j as ChannelAuthResponse, C as ConnectionTokenInput, a as ConnectionTokenResponse, e as ArkNotifyConnectionConfig, o as ConnectionState, m as ConnectedMessage, E as EventMessage, w as PresenceMessage, O as ServerMessage, R as SubscribeOptions, k as ChannelEventHandler, f as ArkNotifySSEConfig, b as ApiError } from './types-BHemo22a.cjs';
2
2
 
3
3
  declare const DEFAULT_BASE_URL = "https://ark-notify-933303906015.europe-north1.run.app";
4
4
  interface ArkNotifyGlobalConfig {
@@ -144,5 +144,11 @@ declare function toWebSocketUrl(baseUrl: string, path: string): string;
144
144
  declare function appendQueryParams(url: string, params: Record<string, string | undefined | null | false>): string;
145
145
  declare function resolveValue<T>(value: T | (() => T)): T;
146
146
  declare function isPrivateChannel(channel: string): boolean;
147
+ /** Whether a server-stream subscription entry is a pattern (`business-*` or `*`). */
148
+ declare function isServerStreamPattern(subscription: string): boolean;
149
+ /** Whether a server-stream subscription entry matches all channels. */
150
+ declare function isAllChannelsSubscription(subscription: string): boolean;
151
+ /** Whether an event channel name matches a server-stream prefix pattern or `*`. */
152
+ declare function matchesChannelPattern(channel: string, pattern: string): boolean;
147
153
 
148
- export { ArkNotifyClient as A, DEFAULT_BASE_URL as D, ArkNotifyConnection as a, ArkNotifyError as b, type ArkNotifyGlobalConfig as c, ArkNotifySSE as d, appendQueryParams as e, configureArkNotify as f, resolveValue as g, isPrivateChannel as i, resolveBaseUrl as r, toWebSocketUrl as t };
154
+ export { ArkNotifyClient as A, DEFAULT_BASE_URL as D, ArkNotifyConnection as a, ArkNotifyError as b, type ArkNotifyGlobalConfig as c, ArkNotifySSE as d, appendQueryParams as e, configureArkNotify as f, isPrivateChannel as g, isServerStreamPattern as h, isAllChannelsSubscription as i, resolveValue as j, matchesChannelPattern as m, resolveBaseUrl as r, toWebSocketUrl as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emmanuel-nike/ark-notify-js",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "JavaScript SDK for Ark Notify — real-time pub/sub, presence, and platform management",
5
5
  "license": "MIT",
6
6
  "type": "module",