From 0c83fb4b3de315f048b72c12650069987ede29e0 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:27:49 +0530 Subject: [PATCH 01/19] pre-requisites for data_sync: handle error array during exceptional cases, include PUT type where needed. update body include cases when body present while making http requests. --- src/core/components/request.ts | 6 +++- src/core/types/transport-request.ts | 4 +++ src/errors/pubnub-api-error.ts | 52 +++++++++++++++++++++++++++++ src/transport/middleware.ts | 2 +- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/core/components/request.ts b/src/core/components/request.ts index 8d7ef34cd..17c8d577c 100644 --- a/src/core/components/request.ts +++ b/src/core/components/request.ts @@ -123,7 +123,11 @@ export abstract class AbstractRequest 0 + ) { + // Handle DataSync-style structured error responses: + // { errors: [{ errorCode: "SYN-0008", message: "...", path: "/id" }] } + errorData = errorResponse; + + const errors = errorResponse.errors as Array<{ + errorCode?: string; + message?: string; + path?: string; + }>; + + message = errors + .map((e) => { + const parts: string[] = []; + if (e.errorCode) parts.push(e.errorCode); + if (e.message) parts.push(e.message); + return parts.join(': '); + }) + .join('; '); } else errorData = errorResponse; if ('error' in errorResponse && errorResponse.error instanceof Error) errorData = errorResponse.error; @@ -229,6 +252,35 @@ export class PubNubAPIError extends Error { }; } + /** + * Format a user-facing error message for this API error. + * + * When the error contains structured details extracted from the service response + * (e.g., DataSync `errors` array), those details are included in the message. + * Otherwise, falls back to a generic description. + * + * @param operation - Request operation during which error happened. + * + * @returns Formatted error message string. + */ + public toFormattedMessage(operation: RequestOperation): string { + const fallback = 'REST API request processing error, check status for details'; + + // When errorData contains a structured `errors` array, `this.message` was already + // constructed from it in `createFromServiceResponse` — prefer it over the generic fallback. + if ( + this.errorData && + typeof this.errorData === 'object' && + !('name' in this.errorData && 'message' in this.errorData && 'stack' in this.errorData) && + 'errors' in this.errorData && + Array.isArray((this.errorData as Record).errors) + ) { + return `${operation}: ${this.message}`; + } + + return fallback; + } + /** * Convert API error object to PubNub client error object. * diff --git a/src/transport/middleware.ts b/src/transport/middleware.ts index 40a5a1d1e..648783c31 100644 --- a/src/transport/middleware.ts +++ b/src/transport/middleware.ts @@ -66,7 +66,7 @@ class RequestSignature { const method = req.path.startsWith('/publish') ? TransportMethod.GET : req.method; let signatureInput = `${method}\n${this.publishKey}\n${req.path}\n${this.queryParameters(req.queryParameters!)}\n`; - if (method === TransportMethod.POST || method === TransportMethod.PATCH) { + if (method === TransportMethod.POST || method === TransportMethod.PATCH || method === TransportMethod.PUT) { const body = req.body; let payload: string | undefined; From 5502af931db770311feb801f8cc4479e699dc300 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:29:05 +0530 Subject: [PATCH 02/19] data-sync: channel endpoint apis --- .../endpoints/data_sync/channel/create.ts | 74 ++++++++++++++ .../endpoints/data_sync/channel/get-all.ts | 74 ++++++++++++++ src/core/endpoints/data_sync/channel/get.ts | 57 +++++++++++ src/core/endpoints/data_sync/channel/patch.ts | 98 +++++++++++++++++++ .../endpoints/data_sync/channel/remove.ts | 72 ++++++++++++++ .../endpoints/data_sync/channel/update.ts | 79 +++++++++++++++ 6 files changed, 454 insertions(+) create mode 100644 src/core/endpoints/data_sync/channel/create.ts create mode 100644 src/core/endpoints/data_sync/channel/get-all.ts create mode 100644 src/core/endpoints/data_sync/channel/get.ts create mode 100644 src/core/endpoints/data_sync/channel/patch.ts create mode 100644 src/core/endpoints/data_sync/channel/remove.ts create mode 100644 src/core/endpoints/data_sync/channel/update.ts diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts new file mode 100644 index 000000000..b4a9c0ab4 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -0,0 +1,74 @@ +/** + * Create Channel REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.CreateChannelParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Create Channel request. + * + * @internal + */ +export class CreateChannelRequest< + Response extends DataSync.CreateChannelResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.POST }); + } + + operation(): RequestOperation { + return RequestOperation.PNCreateChannelOperation; + } + + validate(): string | undefined { + if (!this.parameters.channel) return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/channels`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.channel }); + } +} diff --git a/src/core/endpoints/data_sync/channel/get-all.ts b/src/core/endpoints/data_sync/channel/get-all.ts new file mode 100644 index 000000000..e5a204da2 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/get-all.ts @@ -0,0 +1,74 @@ +/** + * Get All Channels REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet, Query } from '../../../types/api'; + +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults + +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetAllChannelsParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get All Channels request. + * + * @internal + */ +export class GetAllChannelsRequest< + Response extends DataSync.GetAllChannelsResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + + // Apply defaults. + parameters.limit ??= DEFAULT_LIMIT; + } + + operation(): RequestOperation { + return RequestOperation.PNGetAllChannelsOperation; + } + + protected get path(): string { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`; + } + + protected get queryParameters(): Query { + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + + return { + ...(entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {}), + ...(cursor ? { cursor } : {}), + ...(limit ? { limit: `${limit}` } : {}), + ...(filter ? { filter } : {}), + ...(sort ? { sort } : {}), + ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), + }; + } +} diff --git a/src/core/endpoints/data_sync/channel/get.ts b/src/core/endpoints/data_sync/channel/get.ts new file mode 100644 index 000000000..251de4434 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/get.ts @@ -0,0 +1,57 @@ +/** + * Get Channel REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetChannelParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get Channel request. + * + * @internal + */ +export class GetChannelRequest< + Response extends DataSync.GetChannelResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + } + + operation(): RequestOperation { + return RequestOperation.PNGetChannelOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Channel id cannot be empty'; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/channel/patch.ts b/src/core/endpoints/data_sync/channel/patch.ts new file mode 100644 index 000000000..01476cc81 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/patch.ts @@ -0,0 +1,98 @@ +/** + * Patch Channel REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { toJsonPatchOperations } from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.PatchChannelParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Patch Channel request. + * + * @internal + */ +export class PatchChannelRequest< + Response extends DataSync.PatchChannelResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PATCH }); + } + + operation(): RequestOperation { + return RequestOperation.PNPatchChannelOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Channel id cannot be empty'; + + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) return 'At least one of add, replace, or remove must be provided'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/json-patch+json', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input: Record) => + Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} diff --git a/src/core/endpoints/data_sync/channel/remove.ts b/src/core/endpoints/data_sync/channel/remove.ts new file mode 100644 index 000000000..cac10fd68 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/remove.ts @@ -0,0 +1,72 @@ +/** + * Remove Channel REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.RemoveChannelParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Remove Channel request. + * + * @internal + */ +export class RemoveChannelRequest< + Response extends DataSync.RemoveChannelResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.DELETE }); + } + + operation(): RequestOperation { + return RequestOperation.PNRemoveChannelOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Channel id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return Object.keys(headers).length > 0 ? headers : undefined; + } + + async parse(response: TransportResponse): Promise { + return { status: response.status } as Response; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts new file mode 100644 index 000000000..71ff5d386 --- /dev/null +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -0,0 +1,79 @@ +/** + * Update Channel REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.UpdateChannelParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Update Channel request. + * + * @internal + */ +export class UpdateChannelRequest< + Response extends DataSync.UpdateChannelResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PUT }); + } + + operation(): RequestOperation { + return RequestOperation.PNUpdateChannelOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Channel id cannot be empty'; + if (!this.parameters.channel) return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.channel }); + } +} From ea6da8398dc88453fa30ed96e95efea057787bec Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:29:33 +0530 Subject: [PATCH 03/19] data-sync:user endpoint apis --- src/core/endpoints/data_sync/user/create.ts | 74 +++++++++++++++ src/core/endpoints/data_sync/user/get-all.ts | 74 +++++++++++++++ src/core/endpoints/data_sync/user/get.ts | 57 ++++++++++++ src/core/endpoints/data_sync/user/patch.ts | 98 ++++++++++++++++++++ src/core/endpoints/data_sync/user/remove.ts | 72 ++++++++++++++ src/core/endpoints/data_sync/user/update.ts | 79 ++++++++++++++++ 6 files changed, 454 insertions(+) create mode 100644 src/core/endpoints/data_sync/user/create.ts create mode 100644 src/core/endpoints/data_sync/user/get-all.ts create mode 100644 src/core/endpoints/data_sync/user/get.ts create mode 100644 src/core/endpoints/data_sync/user/patch.ts create mode 100644 src/core/endpoints/data_sync/user/remove.ts create mode 100644 src/core/endpoints/data_sync/user/update.ts diff --git a/src/core/endpoints/data_sync/user/create.ts b/src/core/endpoints/data_sync/user/create.ts new file mode 100644 index 000000000..ea0ae4f65 --- /dev/null +++ b/src/core/endpoints/data_sync/user/create.ts @@ -0,0 +1,74 @@ +/** + * Create User REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.CreateUserParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Create User request. + * + * @internal + */ +export class CreateUserRequest< + Response extends DataSync.CreateUserResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.POST }); + } + + operation(): RequestOperation { + return RequestOperation.PNCreateUserOperation; + } + + validate(): string | undefined { + if (!this.parameters.user) return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/users`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.user }); + } +} diff --git a/src/core/endpoints/data_sync/user/get-all.ts b/src/core/endpoints/data_sync/user/get-all.ts new file mode 100644 index 000000000..3acfe0803 --- /dev/null +++ b/src/core/endpoints/data_sync/user/get-all.ts @@ -0,0 +1,74 @@ +/** + * Get All Users REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet, Query } from '../../../types/api'; + +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults + +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetAllUsersParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get All Users request. + * + * @internal + */ +export class GetAllUsersRequest< + Response extends DataSync.GetAllUsersResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + + // Apply defaults. + parameters.limit ??= DEFAULT_LIMIT; + } + + operation(): RequestOperation { + return RequestOperation.PNGetAllUsersOperation; + } + + protected get path(): string { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`; + } + + protected get queryParameters(): Query { + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + + return { + ...(entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {}), + ...(cursor ? { cursor } : {}), + ...(limit ? { limit: `${limit}` } : {}), + ...(filter ? { filter } : {}), + ...(sort ? { sort } : {}), + ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), + }; + } +} diff --git a/src/core/endpoints/data_sync/user/get.ts b/src/core/endpoints/data_sync/user/get.ts new file mode 100644 index 000000000..5fd12ef43 --- /dev/null +++ b/src/core/endpoints/data_sync/user/get.ts @@ -0,0 +1,57 @@ +/** + * Get User REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetUserParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get User request. + * + * @internal + */ +export class GetUserRequest< + Response extends DataSync.GetUserResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + } + + operation(): RequestOperation { + return RequestOperation.PNGetUserOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'User id cannot be empty'; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/patch.ts new file mode 100644 index 000000000..8d97b75aa --- /dev/null +++ b/src/core/endpoints/data_sync/user/patch.ts @@ -0,0 +1,98 @@ +/** + * Patch User REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { toJsonPatchOperations } from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.PatchUserParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Patch User request. + * + * @internal + */ +export class PatchUserRequest< + Response extends DataSync.PatchUserResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PATCH }); + } + + operation(): RequestOperation { + return RequestOperation.PNPatchUserOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'User id cannot be empty'; + + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) return 'At least one of add, replace, or remove must be provided'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/json-patch+json', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input: Record) => + Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} diff --git a/src/core/endpoints/data_sync/user/remove.ts b/src/core/endpoints/data_sync/user/remove.ts new file mode 100644 index 000000000..d553462ad --- /dev/null +++ b/src/core/endpoints/data_sync/user/remove.ts @@ -0,0 +1,72 @@ +/** + * Remove User REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.RemoveUserParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Remove User request. + * + * @internal + */ +export class RemoveUserRequest< + Response extends DataSync.RemoveUserResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.DELETE }); + } + + operation(): RequestOperation { + return RequestOperation.PNRemoveUserOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'User id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return Object.keys(headers).length > 0 ? headers : undefined; + } + + async parse(response: TransportResponse): Promise { + return { status: response.status } as Response; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/user/update.ts b/src/core/endpoints/data_sync/user/update.ts new file mode 100644 index 000000000..34e693d65 --- /dev/null +++ b/src/core/endpoints/data_sync/user/update.ts @@ -0,0 +1,79 @@ +/** + * Update User REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.UpdateUserParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Update User request. + * + * @internal + */ +export class UpdateUserRequest< + Response extends DataSync.UpdateUserResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PUT }); + } + + operation(): RequestOperation { + return RequestOperation.PNUpdateUserOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'User id cannot be empty'; + if (!this.parameters.user) return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.user }); + } +} From f128cbc20886e3da79966ec7ead682e47e355347 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:30:10 +0530 Subject: [PATCH 04/19] data-sync:membership endpoint apis --- .../endpoints/data_sync/membership/create.ts | 75 ++++++++++++++ .../endpoints/data_sync/membership/get-all.ts | 79 +++++++++++++++ .../endpoints/data_sync/membership/get.ts | 57 +++++++++++ .../endpoints/data_sync/membership/patch.ts | 98 +++++++++++++++++++ .../endpoints/data_sync/membership/remove.ts | 72 ++++++++++++++ .../endpoints/data_sync/membership/update.ts | 79 +++++++++++++++ 6 files changed, 460 insertions(+) create mode 100644 src/core/endpoints/data_sync/membership/create.ts create mode 100644 src/core/endpoints/data_sync/membership/get-all.ts create mode 100644 src/core/endpoints/data_sync/membership/get.ts create mode 100644 src/core/endpoints/data_sync/membership/patch.ts create mode 100644 src/core/endpoints/data_sync/membership/remove.ts create mode 100644 src/core/endpoints/data_sync/membership/update.ts diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts new file mode 100644 index 000000000..40a0a27a5 --- /dev/null +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -0,0 +1,75 @@ +/** + * Create Membership REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.CreateMembershipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Create Membership request. + * + * @internal + */ +export class CreateMembershipRequest< + Response extends DataSync.CreateMembershipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.POST }); + } + + operation(): RequestOperation { + return RequestOperation.PNCreateMembershipOperation; + } + + validate(): string | undefined { + if (!this.parameters.membership) return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) return 'Relationship class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/memberships`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.membership }); + } +} diff --git a/src/core/endpoints/data_sync/membership/get-all.ts b/src/core/endpoints/data_sync/membership/get-all.ts new file mode 100644 index 000000000..5ba206399 --- /dev/null +++ b/src/core/endpoints/data_sync/membership/get-all.ts @@ -0,0 +1,79 @@ +/** + * Get All Memberships REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet, Query } from '../../../types/api'; + +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults + +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetAllMembershipsParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get All Memberships request. + * + * @internal + */ +export class GetAllMembershipsRequest< + Response extends DataSync.GetAllMembershipsResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + + // Apply defaults. + parameters.limit ??= DEFAULT_LIMIT; + } + + operation(): RequestOperation { + return RequestOperation.PNGetAllMembershipsOperation; + } + + protected get path(): string { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`; + } + + protected get queryParameters(): Query { + const { userId, channelId, relationshipClassVersion, cursor, limit, filter, sort, filterAdvanced } = + this.parameters; + + return { + ...(userId ? { user_id: userId } : {}), + ...(channelId ? { channel_id: channelId } : {}), + ...(relationshipClassVersion !== undefined + ? { relationship_class_version: `${relationshipClassVersion}` } + : {}), + ...(cursor ? { cursor } : {}), + ...(limit ? { limit: `${limit}` } : {}), + ...(filter ? { filter } : {}), + ...(sort ? { sort } : {}), + ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), + }; + } +} diff --git a/src/core/endpoints/data_sync/membership/get.ts b/src/core/endpoints/data_sync/membership/get.ts new file mode 100644 index 000000000..9909e258f --- /dev/null +++ b/src/core/endpoints/data_sync/membership/get.ts @@ -0,0 +1,57 @@ +/** + * Get Membership REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetMembershipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get Membership request. + * + * @internal + */ +export class GetMembershipRequest< + Response extends DataSync.GetMembershipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + } + + operation(): RequestOperation { + return RequestOperation.PNGetMembershipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Membership id cannot be empty'; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/membership/patch.ts b/src/core/endpoints/data_sync/membership/patch.ts new file mode 100644 index 000000000..efab09b08 --- /dev/null +++ b/src/core/endpoints/data_sync/membership/patch.ts @@ -0,0 +1,98 @@ +/** + * Patch Membership REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { toJsonPatchOperations } from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.PatchMembershipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Patch Membership request. + * + * @internal + */ +export class PatchMembershipRequest< + Response extends DataSync.PatchMembershipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PATCH }); + } + + operation(): RequestOperation { + return RequestOperation.PNPatchMembershipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Membership id cannot be empty'; + + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) return 'At least one of add, replace, or remove must be provided'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/json-patch+json', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input: Record) => + Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} diff --git a/src/core/endpoints/data_sync/membership/remove.ts b/src/core/endpoints/data_sync/membership/remove.ts new file mode 100644 index 000000000..32461f73f --- /dev/null +++ b/src/core/endpoints/data_sync/membership/remove.ts @@ -0,0 +1,72 @@ +/** + * Remove Membership REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.RemoveMembershipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Remove Membership request. + * + * @internal + */ +export class RemoveMembershipRequest< + Response extends DataSync.RemoveMembershipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.DELETE }); + } + + operation(): RequestOperation { + return RequestOperation.PNRemoveMembershipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Membership id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return Object.keys(headers).length > 0 ? headers : undefined; + } + + async parse(response: TransportResponse): Promise { + return { status: response.status } as Response; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/membership/update.ts b/src/core/endpoints/data_sync/membership/update.ts new file mode 100644 index 000000000..f6d4d236e --- /dev/null +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -0,0 +1,79 @@ +/** + * Update Membership REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.UpdateMembershipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Update Membership request. + * + * @internal + */ +export class UpdateMembershipRequest< + Response extends DataSync.UpdateMembershipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PUT }); + } + + operation(): RequestOperation { + return RequestOperation.PNUpdateMembershipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Membership id cannot be empty'; + if (!this.parameters.membership) return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) return 'Channel id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.membership }); + } +} From fbe3e3cfedab88a81f36c0faefa9ee6b09efb35c Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:30:34 +0530 Subject: [PATCH 05/19] data-sync: entity endpoint apis --- src/core/endpoints/data_sync/entity/create.ts | 75 ++++++++++++++ .../endpoints/data_sync/entity/get-all.ts | 79 +++++++++++++++ src/core/endpoints/data_sync/entity/get.ts | 57 +++++++++++ src/core/endpoints/data_sync/entity/patch.ts | 98 +++++++++++++++++++ src/core/endpoints/data_sync/entity/remove.ts | 72 ++++++++++++++ src/core/endpoints/data_sync/entity/update.ts | 80 +++++++++++++++ 6 files changed, 461 insertions(+) create mode 100644 src/core/endpoints/data_sync/entity/create.ts create mode 100644 src/core/endpoints/data_sync/entity/get-all.ts create mode 100644 src/core/endpoints/data_sync/entity/get.ts create mode 100644 src/core/endpoints/data_sync/entity/patch.ts create mode 100644 src/core/endpoints/data_sync/entity/remove.ts create mode 100644 src/core/endpoints/data_sync/entity/update.ts diff --git a/src/core/endpoints/data_sync/entity/create.ts b/src/core/endpoints/data_sync/entity/create.ts new file mode 100644 index 000000000..8e77b1a59 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -0,0 +1,75 @@ +/** + * Create Entity REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.CreateEntityParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Create Entity request. + * + * @internal + */ +export class CreateEntityRequest< + Response extends DataSync.CreateEntityResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.POST }); + } + + operation(): RequestOperation { + return RequestOperation.PNCreateEntityOperation; + } + + validate(): string | undefined { + if (!this.parameters.entity) return 'Entity cannot be empty'; + if (!this.parameters.entity.entityClass) return 'Entity class cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/entities`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.entity }); + } +} diff --git a/src/core/endpoints/data_sync/entity/get-all.ts b/src/core/endpoints/data_sync/entity/get-all.ts new file mode 100644 index 000000000..00ffb0ea9 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/get-all.ts @@ -0,0 +1,79 @@ +/** + * Get All Entities REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet, Query } from '../../../types/api'; + +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults + +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetAllEntitiesParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get All Entities request. + * + * @internal + */ +export class GetAllEntitiesRequest< + Response extends DataSync.GetAllEntitiesResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + + // Apply defaults. + parameters.limit ??= DEFAULT_LIMIT; + } + + operation(): RequestOperation { + return RequestOperation.PNGetAllEntitiesOperation; + } + + validate(): string | undefined { + if (!this.parameters.entityClass) return 'Entity class cannot be empty'; + } + + protected get path(): string { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + } + + protected get queryParameters(): Query { + const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + + return { + entity_class: entityClass, + ...(entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {}), + ...(cursor ? { cursor } : {}), + ...(limit ? { limit: `${limit}` } : {}), + ...(filter ? { filter } : {}), + ...(sort ? { sort } : {}), + ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), + }; + } +} diff --git a/src/core/endpoints/data_sync/entity/get.ts b/src/core/endpoints/data_sync/entity/get.ts new file mode 100644 index 000000000..004b5e534 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/get.ts @@ -0,0 +1,57 @@ +/** + * Get Entity REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetEntityParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get Entity request. + * + * @internal + */ +export class GetEntityRequest< + Response extends DataSync.GetEntityResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + } + + operation(): RequestOperation { + return RequestOperation.PNGetEntityOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Entity id cannot be empty'; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/patch.ts new file mode 100644 index 000000000..17d759176 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/patch.ts @@ -0,0 +1,98 @@ +/** + * Patch Entity REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { toJsonPatchOperations } from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.PatchEntityParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Patch Entity request. + * + * @internal + */ +export class PatchEntityRequest< + Response extends DataSync.PatchEntityResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PATCH }); + } + + operation(): RequestOperation { + return RequestOperation.PNPatchEntityOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Entity id cannot be empty'; + + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) return 'At least one of add, replace, or remove must be provided'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/json-patch+json', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. + const prefixWithPayload = (input: Record) => + Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} diff --git a/src/core/endpoints/data_sync/entity/remove.ts b/src/core/endpoints/data_sync/entity/remove.ts new file mode 100644 index 000000000..c80b537b1 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/remove.ts @@ -0,0 +1,72 @@ +/** + * Remove Entity REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.RemoveEntityParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Remove Entity request. + * + * @internal + */ +export class RemoveEntityRequest< + Response extends DataSync.RemoveEntityResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.DELETE }); + } + + operation(): RequestOperation { + return RequestOperation.PNRemoveEntityOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Entity id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return Object.keys(headers).length > 0 ? headers : undefined; + } + + async parse(response: TransportResponse): Promise { + return { status: response.status } as Response; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/entity/update.ts b/src/core/endpoints/data_sync/entity/update.ts new file mode 100644 index 000000000..6c68bf143 --- /dev/null +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -0,0 +1,80 @@ +/** + * Update Entity REST API module. + * + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.UpdateEntityParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Update Entity request. + * + * @internal + */ +export class UpdateEntityRequest< + Response extends DataSync.UpdateEntityResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PUT }); + } + + operation(): RequestOperation { + return RequestOperation.PNUpdateEntityOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Entity id cannot be empty'; + if (!this.parameters.entity) return 'Entity cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.entity }); + } +} From 87340923705faf36bea34c6db251d321b20d6887 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:31:01 +0530 Subject: [PATCH 06/19] data-sync: entity-relationship endpoint apis --- .../data_sync/relationship/create.ts | 76 ++++++++++++++ .../data_sync/relationship/get-all.ts | 75 ++++++++++++++ .../endpoints/data_sync/relationship/get.ts | 57 +++++++++++ .../endpoints/data_sync/relationship/patch.ts | 98 +++++++++++++++++++ .../data_sync/relationship/remove.ts | 72 ++++++++++++++ .../data_sync/relationship/update.ts | 79 +++++++++++++++ 6 files changed, 457 insertions(+) create mode 100644 src/core/endpoints/data_sync/relationship/create.ts create mode 100644 src/core/endpoints/data_sync/relationship/get-all.ts create mode 100644 src/core/endpoints/data_sync/relationship/get.ts create mode 100644 src/core/endpoints/data_sync/relationship/patch.ts create mode 100644 src/core/endpoints/data_sync/relationship/remove.ts create mode 100644 src/core/endpoints/data_sync/relationship/update.ts diff --git a/src/core/endpoints/data_sync/relationship/create.ts b/src/core/endpoints/data_sync/relationship/create.ts new file mode 100644 index 000000000..9f371b4d3 --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/create.ts @@ -0,0 +1,76 @@ +/** + * Create Relationship REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.CreateRelationshipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Create Relationship request. + * + * @internal + */ +export class CreateRelationshipRequest< + Response extends DataSync.CreateRelationshipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.POST }); + } + + operation(): RequestOperation { + return RequestOperation.PNCreateRelationshipOperation; + } + + validate(): string | undefined { + if (!this.parameters.relationship) return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) return 'Entity B id cannot be empty'; + if (!this.parameters.relationship.relationshipClass) return 'Relationship class cannot be empty'; + if (!this.parameters.relationship.relationshipClassVersion) return 'Relationship class version cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/relationships`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.relationship }); + } +} diff --git a/src/core/endpoints/data_sync/relationship/get-all.ts b/src/core/endpoints/data_sync/relationship/get-all.ts new file mode 100644 index 000000000..a23aa3278 --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/get-all.ts @@ -0,0 +1,75 @@ +/** + * Get All Relationships REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet, Query } from '../../../types/api'; + +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults + +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetAllRelationshipsParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get All Relationships request. + * + * @internal + */ +export class GetAllRelationshipsRequest< + Response extends DataSync.GetAllRelationshipsResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + + // Apply defaults. + parameters.limit ??= DEFAULT_LIMIT; + } + + operation(): RequestOperation { + return RequestOperation.PNGetAllRelationshipsOperation; + } + + protected get path(): string { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + } + + protected get queryParameters(): Query { + const { entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + + return { + ...(entityAId ? { entity_a_id: entityAId } : {}), + ...(entityBId ? { entity_b_id: entityBId } : {}), + ...(cursor ? { cursor } : {}), + ...(limit ? { limit: `${limit}` } : {}), + ...(filter ? { filter } : {}), + ...(sort ? { sort } : {}), + ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), + }; + } +} diff --git a/src/core/endpoints/data_sync/relationship/get.ts b/src/core/endpoints/data_sync/relationship/get.ts new file mode 100644 index 000000000..73be5ee90 --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/get.ts @@ -0,0 +1,57 @@ +/** + * Get Relationship REST API module. + * + * @internal + */ + +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.GetRelationshipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Get Relationship request. + * + * @internal + */ +export class GetRelationshipRequest< + Response extends DataSync.GetRelationshipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super(); + } + + operation(): RequestOperation { + return RequestOperation.PNGetRelationshipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Relationship id cannot be empty'; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/relationship/patch.ts b/src/core/endpoints/data_sync/relationship/patch.ts new file mode 100644 index 000000000..71063bdcc --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/patch.ts @@ -0,0 +1,98 @@ +/** + * Patch Relationship REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { toJsonPatchOperations } from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.PatchRelationshipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Patch Relationship request. + * + * @internal + */ +export class PatchRelationshipRequest< + Response extends DataSync.PatchRelationshipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PATCH }); + } + + operation(): RequestOperation { + return RequestOperation.PNPatchRelationshipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Relationship id cannot be empty'; + + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) return 'At least one of add, replace, or remove must be provided'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + if (this.parameters.idempotencyKey) + headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + + return { + ...headers, + 'Content-Type': 'application/json-patch+json', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'role') and the SDK produces '/payload/role' on the wire. + const prefixWithPayload = (input: Record) => + Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} diff --git a/src/core/endpoints/data_sync/relationship/remove.ts b/src/core/endpoints/data_sync/relationship/remove.ts new file mode 100644 index 000000000..275a15a26 --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/remove.ts @@ -0,0 +1,72 @@ +/** + * Remove Relationship REST API module. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.RemoveRelationshipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Remove Relationship request. + * + * @internal + */ +export class RemoveRelationshipRequest< + Response extends DataSync.RemoveRelationshipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.DELETE }); + } + + operation(): RequestOperation { + return RequestOperation.PNRemoveRelationshipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Relationship id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return Object.keys(headers).length > 0 ? headers : undefined; + } + + async parse(response: TransportResponse): Promise { + return { status: response.status } as Response; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } +} diff --git a/src/core/endpoints/data_sync/relationship/update.ts b/src/core/endpoints/data_sync/relationship/update.ts new file mode 100644 index 000000000..1b8041f06 --- /dev/null +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -0,0 +1,79 @@ +/** + * Update Relationship REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + +import { TransportMethod } from '../../../types/transport-request'; +import { AbstractRequest } from '../../../components/request'; +import RequestOperation from '../../../constants/operations'; +import * as DataSync from '../../../types/api/data-sync'; +import { KeySet } from '../../../types/api'; +import { encodeString } from '../../../utils'; + +// -------------------------------------------------------- +// ------------------------ Types ------------------------- +// -------------------------------------------------------- +// region Types + +/** + * Request configuration parameters. + */ +type RequestParameters = DataSync.UpdateRelationshipParameters & { + /** + * PubNub REST API access key set. + */ + keySet: KeySet; +}; +// endregion + +/** + * Update Relationship request. + * + * @internal + */ +export class UpdateRelationshipRequest< + Response extends DataSync.UpdateRelationshipResponse, +> extends AbstractRequest { + constructor(private readonly parameters: RequestParameters) { + super({ method: TransportMethod.PUT }); + } + + operation(): RequestOperation { + return RequestOperation.PNUpdateRelationshipOperation; + } + + validate(): string | undefined { + if (!this.parameters.id) return 'Relationship id cannot be empty'; + if (!this.parameters.relationship) return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) return 'Entity B id cannot be empty'; + } + + protected get headers(): Record | undefined { + let headers = super.headers ?? {}; + + if (this.parameters.ifMatchesEtag) + headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + + return { + ...headers, + 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1', + }; + } + + protected get path(): string { + const { + keySet: { subscribeKey }, + id, + } = this.parameters; + + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + + protected get body(): ArrayBuffer | string | undefined { + return JSON.stringify({ data: this.parameters.relationship }); + } +} From 18431657144917b9cb7bb9994fb3118475108839 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:32:37 +0530 Subject: [PATCH 07/19] data-sync: apis domain object export, added operation constants, type definition, updated pubnub-common file to have datasync apis support --- src/core/constants/operations.ts | 154 +++ src/core/pubnub-common.ts | 33 +- src/core/pubnub-data-sync.ts | 1650 ++++++++++++++++++++++++++++++ src/core/types/api/data-sync.ts | 1347 ++++++++++++++++++++++++ 4 files changed, 3179 insertions(+), 5 deletions(-) create mode 100644 src/core/pubnub-data-sync.ts create mode 100644 src/core/types/api/data-sync.ts diff --git a/src/core/constants/operations.ts b/src/core/constants/operations.ts index b2167587e..2487172ee 100644 --- a/src/core/constants/operations.ts +++ b/src/core/constants/operations.ts @@ -175,6 +175,160 @@ enum RequestOperation { */ PNSetMembershipsOperation = 'PNSetMembershipsOperation', + // -------------------------------------------------------- + // ------------------- DataSync API ---------------------- + // -------------------------------------------------------- + + /** + * Create entity REST API operation. + */ + PNCreateEntityOperation = 'PNCreateEntityOperation', + + /** + * Get entity REST API operation. + */ + PNGetEntityOperation = 'PNGetEntityOperation', + + /** + * Get all entities REST API operation. + */ + PNGetAllEntitiesOperation = 'PNGetAllEntitiesOperation', + + /** + * Update entity REST API operation. + */ + PNUpdateEntityOperation = 'PNUpdateEntityOperation', + + /** + * Patch entity REST API operation. + */ + PNPatchEntityOperation = 'PNPatchEntityOperation', + + /** + * Remove entity REST API operation. + */ + PNRemoveEntityOperation = 'PNRemoveEntityOperation', + + /** + * Create relationship REST API operation. + */ + PNCreateRelationshipOperation = 'PNCreateRelationshipOperation', + + /** + * Get relationship REST API operation. + */ + PNGetRelationshipOperation = 'PNGetRelationshipOperation', + + /** + * Get all relationships REST API operation. + */ + PNGetAllRelationshipsOperation = 'PNGetAllRelationshipsOperation', + + /** + * Update relationship REST API operation. + */ + PNUpdateRelationshipOperation = 'PNUpdateRelationshipOperation', + + /** + * Patch relationship REST API operation. + */ + PNPatchRelationshipOperation = 'PNPatchRelationshipOperation', + + /** + * Remove relationship REST API operation. + */ + PNRemoveRelationshipOperation = 'PNRemoveRelationshipOperation', + + /** + * Create user REST API operation. + */ + PNCreateUserOperation = 'PNCreateUserOperation', + + /** + * Get user REST API operation. + */ + PNGetUserOperation = 'PNGetUserOperation', + + /** + * Get all users REST API operation. + */ + PNGetAllUsersOperation = 'PNGetAllUsersOperation', + + /** + * Update user REST API operation. + */ + PNUpdateUserOperation = 'PNUpdateUserOperation', + + /** + * Patch user REST API operation. + */ + PNPatchUserOperation = 'PNPatchUserOperation', + + /** + * Remove user REST API operation. + */ + PNRemoveUserOperation = 'PNRemoveUserOperation', + + /** + * Create channel REST API operation. + */ + PNCreateChannelOperation = 'PNCreateChannelOperation', + + /** + * Get channel REST API operation. + */ + PNGetChannelOperation = 'PNGetChannelOperation', + + /** + * Get all channels REST API operation. + */ + PNGetAllChannelsOperation = 'PNGetAllChannelsOperation', + + /** + * Update channel REST API operation. + */ + PNUpdateChannelOperation = 'PNUpdateChannelOperation', + + /** + * Patch channel REST API operation. + */ + PNPatchChannelOperation = 'PNPatchChannelOperation', + + /** + * Remove channel REST API operation. + */ + PNRemoveChannelOperation = 'PNRemoveChannelOperation', + + /** + * Create membership REST API operation. + */ + PNCreateMembershipOperation = 'PNCreateMembershipOperation', + + /** + * Get membership REST API operation. + */ + PNGetMembershipOperation = 'PNGetMembershipOperation', + + /** + * Get all memberships REST API operation. + */ + PNGetAllMembershipsOperation = 'PNGetAllMembershipsOperation', + + /** + * Update membership REST API operation. + */ + PNUpdateMembershipOperation = 'PNUpdateMembershipOperation', + + /** + * Patch membership REST API operation. + */ + PNPatchMembershipOperation = 'PNPatchMembershipOperation', + + /** + * Remove membership REST API operation. + */ + PNRemoveMembershipOperation = 'PNRemoveMembershipOperation', + // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- diff --git a/src/core/pubnub-common.ts b/src/core/pubnub-common.ts index cf21deceb..41f6f97f4 100644 --- a/src/core/pubnub-common.ts +++ b/src/core/pubnub-common.ts @@ -115,6 +115,9 @@ import PubNubPushNotifications from './pubnub-push'; import * as AppContext from './types/api/app-context'; import PubNubObjects from './pubnub-objects'; // endregion +// region DataSync +import PubNubDataSync from './pubnub-data-sync'; +// endregion // region Time import * as Time from './endpoints/time'; // endregion @@ -315,6 +318,13 @@ export class PubNubCore< // @ts-expect-error Allowed to simplify interface when module can be disabled. private readonly _objects: PubNubObjects; + /** + * PubNub DataSync REST API entry point. + * + * @internal + */ + private readonly _dataSync: PubNubDataSync; + /** * PubNub Channel Group REST API entry point. * @@ -433,6 +443,7 @@ export class PubNubCore< // API group entry points initialization. if (process.env.APP_CONTEXT_MODULE !== 'disabled') this._objects = new PubNubObjects(this._configuration, this.sendRequest.bind(this)); + this._dataSync = new PubNubDataSync(this._configuration, this.sendRequest.bind(this)); if (process.env.CHANNEL_GROUPS_MODULE !== 'disabled') this._channelGroups = new PubNubChannelGroups( this._configuration.logger(), @@ -1146,23 +1157,21 @@ export class PubNubCore< }) .catch((error: Error) => { const apiError = !(error instanceof PubNubAPIError) ? PubNubAPIError.create(error) : error; + const errorMessage = apiError.toFormattedMessage(operation); // Notify callback (if possible). if (callback) { if (apiError.category !== Categories.PNCancelledCategory) { this.logger.error('PubNub', () => ({ messageType: 'error', - message: apiError.toPubNubError(operation, 'REST API request processing error, check status for details'), + message: apiError.toPubNubError(operation, errorMessage), })); } return callback(apiError.toStatus(operation), null); } - const pubNubError = apiError.toPubNubError( - operation, - 'REST API request processing error, check status for details', - ); + const pubNubError = apiError.toPubNubError(operation, errorMessage); if (apiError.category !== Categories.PNCancelledCategory) this.logger.error('PubNub', () => ({ messageType: 'error', message: pubNubError })); @@ -3232,6 +3241,20 @@ export class PubNubCore< return this._objects; } + // -------------------------------------------------------- + // -------------------- DataSync API --------------------- + // -------------------------------------------------------- + // region DataSync API + + /** + * PubNub DataSync API group. + */ + get dataSync(): PubNubDataSync { + return this._dataSync; + } + + // endregion + // region Deprecated API /** * Fetch a paginated list of User objects. diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts new file mode 100644 index 000000000..9f47d0e47 --- /dev/null +++ b/src/core/pubnub-data-sync.ts @@ -0,0 +1,1650 @@ +/** + * PubNub DataSync API module. + */ + +import { CreateUserRequest } from './endpoints/data_sync/user/create'; +import { GetAllUsersRequest } from './endpoints/data_sync/user/get-all'; +import { UpdateUserRequest } from './endpoints/data_sync/user/update'; +import { RemoveUserRequest } from './endpoints/data_sync/user/remove'; +import { PatchUserRequest } from './endpoints/data_sync/user/patch'; +import { GetUserRequest } from './endpoints/data_sync/user/get'; +import { CreateChannelRequest } from './endpoints/data_sync/channel/create'; +import { GetAllChannelsRequest } from './endpoints/data_sync/channel/get-all'; +import { UpdateChannelRequest } from './endpoints/data_sync/channel/update'; +import { RemoveChannelRequest } from './endpoints/data_sync/channel/remove'; +import { PatchChannelRequest } from './endpoints/data_sync/channel/patch'; +import { GetChannelRequest } from './endpoints/data_sync/channel/get'; +import { CreateMembershipRequest } from './endpoints/data_sync/membership/create'; +import { GetAllMembershipsRequest } from './endpoints/data_sync/membership/get-all'; +import { UpdateMembershipRequest } from './endpoints/data_sync/membership/update'; +import { RemoveMembershipRequest } from './endpoints/data_sync/membership/remove'; +import { PatchMembershipRequest } from './endpoints/data_sync/membership/patch'; +import { GetMembershipRequest } from './endpoints/data_sync/membership/get'; +import { CreateRelationshipRequest } from './endpoints/data_sync/relationship/create'; +import { GetAllRelationshipsRequest } from './endpoints/data_sync/relationship/get-all'; +import { UpdateRelationshipRequest } from './endpoints/data_sync/relationship/update'; +import { RemoveRelationshipRequest } from './endpoints/data_sync/relationship/remove'; +import { PatchRelationshipRequest } from './endpoints/data_sync/relationship/patch'; +import { GetRelationshipRequest } from './endpoints/data_sync/relationship/get'; +import { CreateEntityRequest } from './endpoints/data_sync/entity/create'; +import { GetAllEntitiesRequest } from './endpoints/data_sync/entity/get-all'; +import { UpdateEntityRequest } from './endpoints/data_sync/entity/update'; +import { RemoveEntityRequest } from './endpoints/data_sync/entity/remove'; +import { PatchEntityRequest } from './endpoints/data_sync/entity/patch'; +import { GetEntityRequest } from './endpoints/data_sync/entity/get'; +import { KeySet, ResultCallback, SendRequestFunction } from './types/api'; +import { PrivateClientConfiguration } from './interfaces/configuration'; +import * as DataSync from './types/api/data-sync'; +import { LoggerManager } from './components/logger-manager'; + +/** + * PubNub DataSync API interface. + */ +export default class PubNubDataSync { + /** + * Extended PubNub client configuration object. + * + * @internal + */ + private readonly configuration: PrivateClientConfiguration; + + /* eslint-disable @typescript-eslint/no-explicit-any */ + /** + * Function which should be used to send REST API calls. + * + * @internal + */ + private readonly sendRequest: SendRequestFunction; + + /** + * REST API endpoints access credentials. + * + * @internal + */ + private readonly keySet: KeySet; + + /** + * Create DataSync API access object. + * + * @param configuration - Extended PubNub client configuration object. + * @param sendRequest - Function which should be used to send REST API calls. + * + * @internal + */ + constructor( + configuration: PrivateClientConfiguration, + /* eslint-disable @typescript-eslint/no-explicit-any */ + sendRequest: SendRequestFunction, + ) { + this.keySet = configuration.keySet; + this.configuration = configuration; + this.sendRequest = sendRequest; + } + + /** + * Get registered loggers' manager. + * + * @returns Registered loggers' manager. + * + * @internal + */ + get logger(): LoggerManager { + return this.configuration.logger(); + } + + // -------------------------------------------------------- + // ------------------- Entity API ------------------------ + // -------------------------------------------------------- + // region Entity API + + // region Create Entity + + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public createEntity( + parameters: DataSync.CreateEntityParameters, + callback: ResultCallback, + ): void; + + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create entity response. + */ + public async createEntity( + parameters: DataSync.CreateEntityParameters, + ): Promise; + + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create entity response or `void` in case if `callback` provided. + */ + async createEntity( + parameters: DataSync.CreateEntityParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Create Entity with parameters:', + })); + + const request = new CreateEntityRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get Entity + + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getEntity( + parameters: DataSync.GetEntityParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get entity response. + */ + public async getEntity( + parameters: DataSync.GetEntityParameters, + ): Promise; + + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get entity response or `void` in case if `callback` provided. + */ + async getEntity( + parameters: DataSync.GetEntityParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get Entity with parameters:', + })); + + const request = new GetEntityRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get All Entities + + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getAllEntities( + parameters: DataSync.GetAllEntitiesParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get all entities response. + */ + public async getAllEntities( + parameters: DataSync.GetAllEntitiesParameters, + ): Promise; + + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all entities response or `void` in case if `callback` provided. + */ + async getAllEntities( + parameters: DataSync.GetAllEntitiesParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get all Entities with parameters:', + })); + + const request = new GetAllEntitiesRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Update Entity + + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback: ResultCallback, + ): void; + + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update entity response. + */ + public async updateEntity( + parameters: DataSync.UpdateEntityParameters, + ): Promise; + + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update entity response or `void` in case if `callback` provided. + */ + async updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Update Entity with parameters:', + })); + + const request = new UpdateEntityRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Patch Entity + + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public patchEntity( + parameters: DataSync.PatchEntityParameters, + callback: ResultCallback, + ): void; + + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch entity response. + */ + public async patchEntity( + parameters: DataSync.PatchEntityParameters, + ): Promise; + + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch entity response or `void` in case if `callback` provided. + */ + async patchEntity( + parameters: DataSync.PatchEntityParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Patch Entity with parameters:', + })); + + const request = new PatchEntityRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Remove Entity + + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public removeEntity( + parameters: DataSync.RemoveEntityParameters, + callback: ResultCallback, + ): void; + + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove entity response. + */ + public async removeEntity( + parameters: DataSync.RemoveEntityParameters, + ): Promise; + + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove entity response or `void` in case if `callback` provided. + */ + async removeEntity( + parameters: DataSync.RemoveEntityParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Remove Entity with parameters:', + })); + + const request = new RemoveEntityRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // endregion + + // -------------------------------------------------------- + // --------------- Relationship API ---------------------- + // -------------------------------------------------------- + // region Relationship API + + // region Create Relationship + + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public createRelationship( + parameters: DataSync.CreateRelationshipParameters, + callback: ResultCallback, + ): void; + + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create relationship response. + */ + public async createRelationship( + parameters: DataSync.CreateRelationshipParameters, + ): Promise; + + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create relationship response or `void` in case if `callback` provided. + */ + async createRelationship( + parameters: DataSync.CreateRelationshipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Create Relationship with parameters:', + })); + + const request = new CreateRelationshipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get Relationship + + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getRelationship( + parameters: DataSync.GetRelationshipParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get relationship response. + */ + public async getRelationship( + parameters: DataSync.GetRelationshipParameters, + ): Promise; + + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get relationship response or `void` in case if `callback` provided. + */ + async getRelationship( + parameters: DataSync.GetRelationshipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get Relationship with parameters:', + })); + + const request = new GetRelationshipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get All Relationships + + /** + * Fetch a paginated list of Relationships. + * + * @param callback - Request completion handler callback. + */ + public getAllRelationships( + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Relationships. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getAllRelationships( + parameters: DataSync.GetAllRelationshipsParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Relationships. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all relationships response. + */ + public async getAllRelationships( + parameters?: DataSync.GetAllRelationshipsParameters, + ): Promise; + + /** + * Fetch a paginated list of Relationships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + */ + async getAllRelationships( + parametersOrCallback?: + | DataSync.GetAllRelationshipsParameters + | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetAllRelationshipsParameters = + parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; + + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get all Relationships with parameters:', + })); + + const request = new GetAllRelationshipsRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Update Relationship + + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback: ResultCallback, + ): void; + + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update relationship response. + */ + public async updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + ): Promise; + + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. + */ + async updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Update Relationship with parameters:', + })); + + const request = new UpdateRelationshipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Patch Relationship + + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public patchRelationship( + parameters: DataSync.PatchRelationshipParameters, + callback: ResultCallback, + ): void; + + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch relationship response. + */ + public async patchRelationship( + parameters: DataSync.PatchRelationshipParameters, + ): Promise; + + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch relationship response or `void` in case if `callback` provided. + */ + async patchRelationship( + parameters: DataSync.PatchRelationshipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Patch Relationship with parameters:', + })); + + const request = new PatchRelationshipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Remove Relationship + + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public removeRelationship( + parameters: DataSync.RemoveRelationshipParameters, + callback: ResultCallback, + ): void; + + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove relationship response. + */ + public async removeRelationship( + parameters: DataSync.RemoveRelationshipParameters, + ): Promise; + + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove relationship response or `void` in case if `callback` provided. + */ + async removeRelationship( + parameters: DataSync.RemoveRelationshipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Remove Relationship with parameters:', + })); + + const request = new RemoveRelationshipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // endregion + + // -------------------------------------------------------- + // -------------------- User API ------------------------- + // -------------------------------------------------------- + // region User API + + // region Create User + + /** + * Create a new User. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public createUser( + parameters: DataSync.CreateUserParameters, + callback: ResultCallback, + ): void; + + /** + * Create a new User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create user response. + */ + public async createUser(parameters: DataSync.CreateUserParameters): Promise; + + /** + * Create a new User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create user response or `void` in case if `callback` provided. + */ + async createUser( + parameters: DataSync.CreateUserParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Create User with parameters:', + })); + + const request = new CreateUserRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get User + + /** + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getUser(parameters: DataSync.GetUserParameters, callback: ResultCallback): void; + + /** + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get user response. + */ + public async getUser(parameters: DataSync.GetUserParameters): Promise; + + /** + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get user response or `void` in case if `callback` provided. + */ + async getUser( + parameters: DataSync.GetUserParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get User with parameters:', + })); + + const request = new GetUserRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get All Users + + /** + * Fetch a paginated list of Users. + * + * @param callback - Request completion handler callback. + */ + public getAllUsers(callback: ResultCallback): void; + + /** + * Fetch a paginated list of Users. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getAllUsers( + parameters: DataSync.GetAllUsersParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Users. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all users response. + */ + public async getAllUsers(parameters?: DataSync.GetAllUsersParameters): Promise; + + /** + * Fetch a paginated list of Users. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all users response or `void` in case if `callback` provided. + */ + async getAllUsers( + parametersOrCallback?: DataSync.GetAllUsersParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetAllUsersParameters = + parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; + + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get all Users with parameters:', + })); + + const request = new GetAllUsersRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Update User + + /** + * Update a User (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public updateUser( + parameters: DataSync.UpdateUserParameters, + callback: ResultCallback, + ): void; + + /** + * Update a User (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update user response. + */ + public async updateUser(parameters: DataSync.UpdateUserParameters): Promise; + + /** + * Update a User (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update user response or `void` in case if `callback` provided. + */ + async updateUser( + parameters: DataSync.UpdateUserParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Update User with parameters:', + })); + + const request = new UpdateUserRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Patch User + + /** + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public patchUser( + parameters: DataSync.PatchUserParameters, + callback: ResultCallback, + ): void; + + /** + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch user response. + */ + public async patchUser(parameters: DataSync.PatchUserParameters): Promise; + + /** + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch user response or `void` in case if `callback` provided. + */ + async patchUser( + parameters: DataSync.PatchUserParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Patch User with parameters:', + })); + + const request = new PatchUserRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Remove User + + /** + * Remove a User. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public removeUser( + parameters: DataSync.RemoveUserParameters, + callback: ResultCallback, + ): void; + + /** + * Remove a User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove user response. + */ + public async removeUser(parameters: DataSync.RemoveUserParameters): Promise; + + /** + * Remove a User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove user response or `void` in case if `callback` provided. + */ + async removeUser( + parameters: DataSync.RemoveUserParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Remove User with parameters:', + })); + + const request = new RemoveUserRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // endregion + + // -------------------------------------------------------- + // ------------------ Channel API ------------------------ + // -------------------------------------------------------- + // region Channel API + + // region Create Channel + + /** + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public createChannel( + parameters: DataSync.CreateChannelParameters, + callback: ResultCallback, + ): void; + + /** + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create channel response. + */ + public async createChannel(parameters: DataSync.CreateChannelParameters): Promise; + + /** + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create channel response or `void` in case if `callback` provided. + */ + async createChannel( + parameters: DataSync.CreateChannelParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Create Channel with parameters:', + })); + + const request = new CreateChannelRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get Channel + + /** + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getChannel( + parameters: DataSync.GetChannelParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get channel response. + */ + public async getChannel(parameters: DataSync.GetChannelParameters): Promise; + + /** + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get channel response or `void` in case if `callback` provided. + */ + async getChannel( + parameters: DataSync.GetChannelParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get Channel with parameters:', + })); + + const request = new GetChannelRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get All Channels + + /** + * Fetch a paginated list of Channels. + * + * @param callback - Request completion handler callback. + */ + public getAllChannels(callback: ResultCallback): void; + + /** + * Fetch a paginated list of Channels. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getAllChannels( + parameters: DataSync.GetAllChannelsParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Channels. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all channels response. + */ + public async getAllChannels( + parameters?: DataSync.GetAllChannelsParameters, + ): Promise; + + /** + * Fetch a paginated list of Channels. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all channels response or `void` in case if `callback` provided. + */ + async getAllChannels( + parametersOrCallback?: DataSync.GetAllChannelsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetAllChannelsParameters = + parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; + + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get all Channels with parameters:', + })); + + const request = new GetAllChannelsRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Update Channel + + /** + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback: ResultCallback, + ): void; + + /** + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update channel response. + */ + public async updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; + + /** + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update channel response or `void` in case if `callback` provided. + */ + async updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Update Channel with parameters:', + })); + + const request = new UpdateChannelRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Patch Channel + + /** + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public patchChannel( + parameters: DataSync.PatchChannelParameters, + callback: ResultCallback, + ): void; + + /** + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch channel response. + */ + public async patchChannel(parameters: DataSync.PatchChannelParameters): Promise; + + /** + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch channel response or `void` in case if `callback` provided. + */ + async patchChannel( + parameters: DataSync.PatchChannelParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Patch Channel with parameters:', + })); + + const request = new PatchChannelRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Remove Channel + + /** + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public removeChannel( + parameters: DataSync.RemoveChannelParameters, + callback: ResultCallback, + ): void; + + /** + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove channel response. + */ + public async removeChannel(parameters: DataSync.RemoveChannelParameters): Promise; + + /** + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove channel response or `void` in case if `callback` provided. + */ + async removeChannel( + parameters: DataSync.RemoveChannelParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Remove Channel with parameters:', + })); + + const request = new RemoveChannelRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // endregion + + // -------------------------------------------------------- + // ----------------- Membership API ---------------------- + // -------------------------------------------------------- + // region Membership API + + // region Create Membership + + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public createMembership( + parameters: DataSync.CreateMembershipParameters, + callback: ResultCallback, + ): void; + + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create membership response. + */ + public async createMembership( + parameters: DataSync.CreateMembershipParameters, + ): Promise; + + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create membership response or `void` in case if `callback` provided. + */ + async createMembership( + parameters: DataSync.CreateMembershipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Create Membership with parameters:', + })); + + const request = new CreateMembershipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get Membership + + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getMembership( + parameters: DataSync.GetMembershipParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get membership response. + */ + public async getMembership(parameters: DataSync.GetMembershipParameters): Promise; + + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get membership response or `void` in case if `callback` provided. + */ + async getMembership( + parameters: DataSync.GetMembershipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get Membership with parameters:', + })); + + const request = new GetMembershipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Get All Memberships + + /** + * Fetch a paginated list of Memberships. + * + * @param callback - Request completion handler callback. + */ + public getAllMemberships(callback: ResultCallback): void; + + /** + * Fetch a paginated list of Memberships. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public getAllMemberships( + parameters: DataSync.GetAllMembershipsParameters, + callback: ResultCallback, + ): void; + + /** + * Fetch a paginated list of Memberships. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all memberships response. + */ + public async getAllMemberships( + parameters?: DataSync.GetAllMembershipsParameters, + ): Promise; + + /** + * Fetch a paginated list of Memberships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all memberships response or `void` in case if `callback` provided. + */ + async getAllMemberships( + parametersOrCallback?: DataSync.GetAllMembershipsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetAllMembershipsParameters = + parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; + + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Get all Memberships with parameters:', + })); + + const request = new GetAllMembershipsRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Update Membership + + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback: ResultCallback, + ): void; + + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update membership response. + */ + public async updateMembership( + parameters: DataSync.UpdateMembershipParameters, + ): Promise; + + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update membership response or `void` in case if `callback` provided. + */ + async updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Update Membership with parameters:', + })); + + const request = new UpdateMembershipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Patch Membership + + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public patchMembership( + parameters: DataSync.PatchMembershipParameters, + callback: ResultCallback, + ): void; + + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch membership response. + */ + public async patchMembership( + parameters: DataSync.PatchMembershipParameters, + ): Promise; + + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch membership response or `void` in case if `callback` provided. + */ + async patchMembership( + parameters: DataSync.PatchMembershipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Patch Membership with parameters:', + })); + + const request = new PatchMembershipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // region Remove Membership + + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + public removeMembership( + parameters: DataSync.RemoveMembershipParameters, + callback: ResultCallback, + ): void; + + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove membership response. + */ + public async removeMembership( + parameters: DataSync.RemoveMembershipParameters, + ): Promise; + + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove membership response or `void` in case if `callback` provided. + */ + async removeMembership( + parameters: DataSync.RemoveMembershipParameters, + callback?: ResultCallback, + ): Promise { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: { ...parameters }, + details: 'Remove Membership with parameters:', + })); + + const request = new RemoveMembershipRequest({ ...parameters, keySet: this.keySet }); + + if (callback) return this.sendRequest(request, callback); + return this.sendRequest(request); + } + + // endregion + // endregion +} diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts new file mode 100644 index 000000000..7e60516cb --- /dev/null +++ b/src/core/types/api/data-sync.ts @@ -0,0 +1,1347 @@ +/** + * PubNub DataSync API type definitions. + * + * Types for Entity Class CRUD operations. + */ + +// -------------------------------------------------------- +// -------------------- Common Types ---------------------- +// -------------------------------------------------------- + +/** + * Filterable field definition for entity classes. + */ +export type FilterableField = { + /** Unique semantic identifier for the property. */ + name: string; + + /** JSON Pointer (RFC 6901) to the property location. */ + path: string; + + /** Data type of the property value. */ + valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; + + /** + * Whether the property should be indexed for full-text search. + * @default false + */ + enabledAdvancedFiltering?: boolean; + + /** + * Whether the property can have null values. + * @default true + */ + isNullable?: boolean; + }; + + /** + * Cursor-based pagination metadata returned by the server. + */ + export type DataSyncPageMeta = { + /** Opaque cursor for the next page. Null if no more results. */ + next_cursor: string | null; + + /** Opaque cursor for the previous page. Null if first page. */ + prev_cursor: string | null; + + /** Whether there are more results after this page. */ + has_next: boolean; + + /** Whether there are results before this page. */ + has_prev: boolean; + + /** The limit applied to this page. */ + limit: number; + }; + + /** + * HATEOAS navigation links. + */ + export type DataSyncLinks = { + /** Link to the current page. */ + self: string; + + /** Link to the next page, if available. */ + next?: string | null; + + /** Link to the previous page, if available. */ + prev?: string | null; + + /** Additional links for related resources. */ + [key: string]: string | null | undefined; + }; + + /** + * Common parameters for paginated list requests. + */ + type PagedRequestParameters = { + /** Opaque cursor for pagination. Omit for the first page. */ + cursor?: string; + + /** + * Maximum number of items per page. + * @default 20 + * @max 100 + */ + limit?: number; + + /** Filter expression for results. */ + filter?: string; + + /** + * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). + * Example: "+name,-createdAt" + */ + sort?: string; + }; + + /** + * Single-entity response envelope. + */ + type DataSyncEntityResponse = { + /** HTTP status code. */ + status: number; + + /** Response data. */ + data: T; + + /** HATEOAS links. */ + links?: DataSyncLinks; + + /** Response metadata. */ + meta?: DataSyncPageMeta; + }; + + /** + * Paged list response envelope. + */ + type DataSyncPagedResponse = { + /** HTTP status code. */ + status: number; + + /** Array of response items. */ + data: T[]; + + /** HATEOAS links for pagination. */ + links?: DataSyncLinks; + + /** Cursor-based pagination metadata. */ + meta?: DataSyncPageMeta; + }; + + // -------------------------------------------------------- + // -------------- Patch Operation Types ------------------- + // -------------------------------------------------------- + + /** + * JSON Patch operation as defined by RFC 6902. + * + * Internal wire format. Developers use `add`/`replace`/`remove` with dot notation instead. + * + * @internal + */ + export type JsonPatchOperation = { + op: 'add' | 'remove' | 'replace'; + path: string; + value?: unknown; + }; + + /** + * Convert dot-notation path to JSON Pointer (RFC 6901). + * + * "config.ttlSec" → "/config/ttlSec" + * "filterableFields.0.name" → "/filterableFields/0/name" + * + * @internal + */ + export function toJsonPointer(dotPath: string): string { + return '/' + dotPath.split('.').join('/'); + } + + /** + * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). + * + * - Each key in `add` becomes an "add" operation. + * - Each key in `replace` becomes a "replace" operation. + * - Each entry in `remove` becomes a "remove" operation. + * + * @internal + */ + export function toJsonPatchOperations( + add?: Record, + replace?: Record, + remove?: string[], + ): JsonPatchOperation[] { + const ops: JsonPatchOperation[] = []; + + if (add) { + for (const [dotPath, value] of Object.entries(add)) { + ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); + } + } + + if (replace) { + for (const [dotPath, value] of Object.entries(replace)) { + ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); + } + } + + if (remove) { + for (const dotPath of remove) { + ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); + } + } + + return ops; + } + + // -------------------------------------------------------- + // ------------------- Entity Types ----------------------- + // -------------------------------------------------------- + + /** + * Entity properties for create requests. + * + * Includes `entityClass` since it must be set at creation time and is immutable afterward. + */ + export type CreateEntityProperties = { + /** Entity class this entity belongs to. */ + entityClass: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity properties for update (PUT) requests. + * + * `entityClass` is immutable after creation and therefore excluded from updates. + */ + export type UpdateEntityProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity resource as returned from the server. + */ + export type EntityObject = { + /** Unique identifier (UUID). */ + id: string; + + /** Entity class this entity belongs to. */ + entityClass: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the entity was created (ISO 8601). */ + createdAt: string; + + /** Date and time the entity was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ + expiresAt?: string; + }; + + // ----- Entity Request Parameters ----- + + /** + * Create Entity request parameters. + */ + export type CreateEntityParameters = { + /** + * Entity properties to create. + * + * All entity properties go inside `entity` because they map to the request body envelope. + * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation + * posts to a collection URL with all fields in the body. + */ + entity: CreateEntityProperties & { + /** + * Optional entity ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Get Entity request parameters. + */ + export type GetEntityParameters = { + /** Entity ID. */ + id: string; + }; + + /** + * Get All Entities request parameters. + * + * `entityClass` is required — entities are always listed within the context of their class. + */ + export type GetAllEntitiesParameters = PagedRequestParameters & { + /** Entity class name to filter by (required). */ + entityClass: string; + + /** + * Entity class version. If not provided, the server returns entities for the latest version. + */ + entityClassVersion?: number; + + /** + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. + */ + filterAdvanced?: string; + }; + + /** + * Update Entity request parameters (full replacement via PUT). + * + * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, + * and `payload` can be updated. + */ + export type UpdateEntityParameters = { + /** Entity ID. */ + id: string; + + /** Complete entity properties for replacement (excludes immutable `entityClass`). */ + entity: UpdateEntityProperties; + + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchEntityParameters = { + /** Entity ID. */ + id: string; + + /** + * Fields to add, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "add" operations. + * + * @example + * ```typescript + * add: { + * 'payload.tags.0': 'priority', + * 'payload.profile.displayName': 'Alice', + * } + * ``` + */ + add?: Record; + + /** + * Fields to replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * replace: { + * 'status': 'active', + * 'payload.score': 300, + * } + * ``` + */ + replace?: Record; + + /** + * Array of dot-notation field paths to remove. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['payload.tempFlag', 'payload.legacyField'] + * ``` + */ + remove?: string[]; + + /** + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Remove Entity request parameters. + */ + export type RemoveEntityParameters = { + /** Entity ID. */ + id: string; + + /** + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + // ----- Entity Response Types ----- + + /** Response for creating an entity. */ + export type CreateEntityResponse = DataSyncEntityResponse; + + /** Response for getting a single entity. */ + export type GetEntityResponse = DataSyncEntityResponse; + + /** Response for listing entities. */ + export type GetAllEntitiesResponse = DataSyncPagedResponse; + + /** Response for updating an entity (PUT). */ + export type UpdateEntityResponse = DataSyncEntityResponse; + + /** Response for patching an entity (PATCH). */ + export type PatchEntityResponse = DataSyncEntityResponse; + + /** Response for removing an entity. */ + export type RemoveEntityResponse = { + /** HTTP status code. */ + status: number; + }; + + // -------------------------------------------------------- + // --------------- Relationship Types --------------------- + // -------------------------------------------------------- + + /** + * Relationship properties for create requests. + * + * Both `entityAId` and `entityBId` must be set at creation time. + */ + export type CreateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Relationship class this relationship belongs to. */ + relationshipClass: string; + + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Relationship properties for update (PUT) requests. + * + * PUT is a full replacement — `entityAId` and `entityBId` are required. + */ + export type UpdateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Relationship resource as returned from the server. + */ + export type RelationshipObject = { + /** Unique identifier. */ + id: string; + + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Relationship class this relationship belongs to. */ + relationshipClass: string; + + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the relationship was created (ISO 8601). */ + createdAt: string; + + /** Date and time the relationship was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; + }; + + // ----- Relationship Request Parameters ----- + + /** + * Create Relationship request parameters. + */ + export type CreateRelationshipParameters = { + /** + * Relationship properties to create. + * + * All relationship properties go inside `relationship` because they map to the request body envelope. + */ + relationship: CreateRelationshipProperties & { + /** + * Optional relationship ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Get Relationship request parameters. + */ + export type GetRelationshipParameters = { + /** Relationship ID. */ + id: string; + }; + + /** + * Get All Relationships request parameters. + * + * All parameters are optional — relationships can be listed without any filters. + */ + export type GetAllRelationshipsParameters = PagedRequestParameters & { + /** Filter relationships by first entity ID. */ + entityAId?: string; + + /** Filter relationships by second entity ID. */ + entityBId?: string; + + /** + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. + */ + filterAdvanced?: string; + }; + + /** + * Update Relationship request parameters (full replacement via PUT). + */ + export type UpdateRelationshipParameters = { + /** Relationship ID. */ + id: string; + + /** Complete relationship properties for replacement. */ + relationship: UpdateRelationshipProperties; + + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchRelationshipParameters = { + /** Relationship ID. */ + id: string; + + /** + * Fields to add, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "add" operations. + * + * @example + * ```typescript + * add: { + * 'tags.0': 'mentor', + * } + * ``` + */ + add?: Record; + + /** + * Fields to replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * replace: { + * 'role': 'admin', + * 'permissions.read': true, + * } + * ``` + */ + replace?: Record; + + /** + * Array of dot-notation field paths to remove from `payload`. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['tempFlag', 'legacyField'] + * ``` + */ + remove?: string[]; + + /** + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Remove Relationship request parameters. + */ + export type RemoveRelationshipParameters = { + /** Relationship ID. */ + id: string; + + /** + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + // ----- Relationship Response Types ----- + + /** Response for creating a relationship. */ + export type CreateRelationshipResponse = DataSyncEntityResponse; + + /** Response for getting a single relationship. */ + export type GetRelationshipResponse = DataSyncEntityResponse; + + /** Response for listing relationships. */ + export type GetAllRelationshipsResponse = DataSyncPagedResponse; + + /** Response for updating a relationship (PUT). */ + export type UpdateRelationshipResponse = DataSyncEntityResponse; + + /** Response for patching a relationship (PATCH). */ + export type PatchRelationshipResponse = DataSyncEntityResponse; + + /** Response for removing a relationship. */ + export type RemoveRelationshipResponse = { + /** HTTP status code. */ + status: number; + }; + + // -------------------------------------------------------- + // ------------------ User Types -------------------------- + // -------------------------------------------------------- + + /** + * User properties for create requests. + */ + export type CreateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * User resource as returned from the server. + */ + export type UserObject = { + /** Unique identifier (UUID). */ + id: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the user was created (ISO 8601). */ + createdAt: string; + + /** Date and time the user was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). Users expire at this time. */ + expiresAt?: string; + }; + + // ----- User Request Parameters ----- + + /** + * Create User request parameters. + */ + export type CreateUserParameters = { + /** + * User properties to create. + */ + user: CreateUserProperties & { + /** + * Optional user ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * User properties for update (PUT) requests. + */ + export type UpdateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Get User request parameters. + */ + export type GetUserParameters = { + /** User ID. */ + id: string; + }; + + /** + * Get All Users request parameters. + */ + export type GetAllUsersParameters = PagedRequestParameters & { + /** + * Entity class version. If not provided, the server returns users for the latest version. + */ + entityClassVersion?: number; + + /** + * Advanced filter expression for complex queries. + */ + filterAdvanced?: string; + }; + + /** + * Update User request parameters (full replacement via PUT). + */ + export type UpdateUserParameters = { + /** User ID. */ + id: string; + + /** Complete user properties for replacement. */ + user: UpdateUserProperties; + + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch User request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchUserParameters = { + /** User ID. */ + id: string; + + /** + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; + + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; + + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; + }; + + /** + * Remove User request parameters. + */ + export type RemoveUserParameters = { + /** User ID. */ + id: string; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + }; + + // ----- User Response Types ----- + + /** Response for creating a user. */ + export type CreateUserResponse = DataSyncEntityResponse; + + /** Response for getting a single user. */ + export type GetUserResponse = DataSyncEntityResponse; + + /** Response for listing users. */ + export type GetAllUsersResponse = DataSyncPagedResponse; + + /** Response for updating a user (PUT). */ + export type UpdateUserResponse = DataSyncEntityResponse; + + /** Response for patching a user (PATCH). */ + export type PatchUserResponse = DataSyncEntityResponse; + + /** Response for removing a user. */ + export type RemoveUserResponse = { + /** HTTP status code. */ + status: number; + }; + + // -------------------------------------------------------- + // ----------------- Channel Types ------------------------ + // -------------------------------------------------------- + + /** + * Channel properties for create requests. + */ + export type CreateChannelProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Channel properties for update (PUT) requests. + */ + export type UpdateChannelProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Channel resource as returned from the server. + */ + export type ChannelObject = { + /** Unique identifier (UUID). */ + id: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the channel was created (ISO 8601). */ + createdAt: string; + + /** Date and time the channel was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). Channels expire at this time. */ + expiresAt?: string; + }; + + // ----- Channel Request Parameters ----- + + /** + * Create Channel request parameters. + */ + export type CreateChannelParameters = { + /** + * Channel properties to create. + */ + channel: CreateChannelProperties & { + /** + * Optional channel ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; + }; + + /** + * Get Channel request parameters. + */ + export type GetChannelParameters = { + /** Channel ID. */ + id: string; + }; + + /** + * Get All Channels request parameters. + */ + export type GetAllChannelsParameters = PagedRequestParameters & { + /** + * Entity class version. If not provided, the server returns channels for the latest version. + */ + entityClassVersion?: number; + + /** + * Advanced filter expression for complex queries. + */ + filterAdvanced?: string; + }; + + /** + * Update Channel request parameters (full replacement via PUT). + */ + export type UpdateChannelParameters = { + /** Channel ID. */ + id: string; + + /** Complete channel properties for replacement. */ + channel: UpdateChannelProperties; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Channel request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchChannelParameters = { + /** Channel ID. */ + id: string; + + /** + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; + + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; + + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; + }; + + /** + * Remove Channel request parameters. + */ + export type RemoveChannelParameters = { + /** Channel ID. */ + id: string; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + }; + + // ----- Channel Response Types ----- + + /** Response for creating a channel. */ + export type CreateChannelResponse = DataSyncEntityResponse; + + /** Response for getting a single channel. */ + export type GetChannelResponse = DataSyncEntityResponse; + + /** Response for listing channels. */ + export type GetAllChannelsResponse = DataSyncPagedResponse; + + /** Response for updating a channel (PUT). */ + export type UpdateChannelResponse = DataSyncEntityResponse; + + /** Response for patching a channel (PATCH). */ + export type PatchChannelResponse = DataSyncEntityResponse; + + /** Response for removing a channel. */ + export type RemoveChannelResponse = { + /** HTTP status code. */ + status: number; + }; + + // -------------------------------------------------------- + // ---------------- Membership Types ---------------------- + // -------------------------------------------------------- + + /** + * Membership properties for create requests. + * + * Both `userId` and `channelId` must be set at creation time. + */ + export type CreateMembershipProperties = { + /** User ID reference. */ + userId: string; + + /** Channel ID reference. */ + channelId: string; + + /** Version of the Membership relationship class. */ + relationshipClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Membership properties for update (PUT) requests. + * + * PUT is a full replacement — `userId` and `channelId` are required. + */ + export type UpdateMembershipProperties = { + /** User ID reference. */ + userId: string; + + /** Channel ID reference. */ + channelId: string; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Membership resource as returned from the server. + * + * Note: server responses are shaped like a relationship — `entityAId` corresponds + * to `channelId` and `entityBId` corresponds to `userId`. + */ + export type MembershipObject = { + /** Unique identifier. */ + id: string; + + /** Channel ID (server returns this as `entityAId`). */ + entityAId: string; + + /** User ID (server returns this as `entityBId`). */ + entityBId: string; + + /** Relationship class. */ + relationshipClass: string; + + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the membership was created (ISO 8601). */ + createdAt: string; + + /** Date and time the membership was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; + }; + + // ----- Membership Request Parameters ----- + + /** + * Create Membership request parameters. + */ + export type CreateMembershipParameters = { + /** + * Membership properties to create. + */ + membership: CreateMembershipProperties & { + /** + * Optional membership ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; + }; + + /** + * Get Membership request parameters. + */ + export type GetMembershipParameters = { + /** Membership ID. */ + id: string; + }; + + /** + * Get All Memberships request parameters. + */ + export type GetAllMembershipsParameters = PagedRequestParameters & { + /** Filter memberships by user ID. */ + userId?: string; + + /** Filter memberships by channel ID. */ + channelId?: string; + + /** + * Schema version of the relationship class. + * If not provided, the server uses the latest version. + */ + relationshipClassVersion?: number; + + /** + * Advanced filter expression for complex queries. + */ + filterAdvanced?: string; + }; + + /** + * Update Membership request parameters (full replacement via PUT). + */ + export type UpdateMembershipParameters = { + /** Membership ID. */ + id: string; + + /** Complete membership properties for replacement. */ + membership: UpdateMembershipProperties; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Membership request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchMembershipParameters = { + /** Membership ID. */ + id: string; + + /** + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; + + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; + + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; + }; + + /** + * Remove Membership request parameters. + */ + export type RemoveMembershipParameters = { + /** Membership ID. */ + id: string; + + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; + }; + + // ----- Membership Response Types ----- + + /** Response for creating a membership. */ + export type CreateMembershipResponse = DataSyncEntityResponse; + + /** Response for getting a single membership. */ + export type GetMembershipResponse = DataSyncEntityResponse; + + /** Response for listing memberships. */ + export type GetAllMembershipsResponse = DataSyncPagedResponse; + + /** Response for updating a membership (PUT). */ + export type UpdateMembershipResponse = DataSyncEntityResponse; + + /** Response for patching a membership (PATCH). */ + export type PatchMembershipResponse = DataSyncEntityResponse; + + /** Response for removing a membership. */ + export type RemoveMembershipResponse = { + /** HTTP status code. */ + status: number; + }; From 7a5a27f90ad90455cc2075609e3f957103055486 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:33:29 +0530 Subject: [PATCH 08/19] updated dist/lib and codeowner files. --- .github/CODEOWNERS | 2 +- dist/web/pubnub.js | 1229 +++++++++++++++-- dist/web/pubnub.min.js | 4 +- dist/web/pubnub.worker.js | 4 + dist/web/pubnub.worker.min.js | 2 +- lib/core/components/request.js | 4 +- lib/core/constants/operations.js | 51 + lib/core/endpoints/data_sync/entity/create.js | 52 + .../endpoints/data_sync/entity/get-all.js | 51 + lib/core/endpoints/data_sync/entity/get.js | 38 + lib/core/endpoints/data_sync/entity/patch.js | 68 + lib/core/endpoints/data_sync/entity/remove.js | 60 + lib/core/endpoints/data_sync/entity/update.js | 56 + .../data_sync/relationship/create.js | 52 + .../data_sync/relationship/get-all.js | 47 + .../endpoints/data_sync/relationship/get.js | 38 + .../endpoints/data_sync/relationship/patch.js | 68 + .../data_sync/relationship/remove.js | 60 + .../data_sync/relationship/update.js | 57 + lib/core/pubnub-common.js | 19 +- lib/core/pubnub-data-sync.js | 315 +++++ lib/core/types/api/data-sync.js | 42 + lib/core/types/transport-request.js | 4 + lib/errors/pubnub-api-error.js | 42 + lib/transport/middleware.js | 2 +- lib/types/index.d.ts | 808 +++++++++++ package-lock.json | 4 +- 27 files changed, 3033 insertions(+), 146 deletions(-) create mode 100644 lib/core/endpoints/data_sync/entity/create.js create mode 100644 lib/core/endpoints/data_sync/entity/get-all.js create mode 100644 lib/core/endpoints/data_sync/entity/get.js create mode 100644 lib/core/endpoints/data_sync/entity/patch.js create mode 100644 lib/core/endpoints/data_sync/entity/remove.js create mode 100644 lib/core/endpoints/data_sync/entity/update.js create mode 100644 lib/core/endpoints/data_sync/relationship/create.js create mode 100644 lib/core/endpoints/data_sync/relationship/get-all.js create mode 100644 lib/core/endpoints/data_sync/relationship/get.js create mode 100644 lib/core/endpoints/data_sync/relationship/patch.js create mode 100644 lib/core/endpoints/data_sync/relationship/remove.js create mode 100644 lib/core/endpoints/data_sync/relationship/update.js create mode 100644 lib/core/pubnub-data-sync.js create mode 100644 lib/core/types/api/data-sync.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9271d7728..e42bd3603 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ -* @mohitpubnub @parfeon @seba-aln +* @mohitpubnub @parfeon jguz-pubnub README.md @techwritermat @kazydek @mohitpubnub @parfeon diff --git a/dist/web/pubnub.js b/dist/web/pubnub.js index 56034e841..c1135d19e 100644 --- a/dist/web/pubnub.js +++ b/dist/web/pubnub.js @@ -3155,6 +3155,24 @@ errorData = errorResponse; status = errorResponse.status; } + else if ('errors' in errorResponse && + Array.isArray(errorResponse.errors) && + errorResponse.errors.length > 0) { + // Handle DataSync-style structured error responses: + // { errors: [{ errorCode: "SYN-0008", message: "...", path: "/id" }] } + errorData = errorResponse; + const errors = errorResponse.errors; + message = errors + .map((e) => { + const parts = []; + if (e.errorCode) + parts.push(e.errorCode); + if (e.message) + parts.push(e.message); + return parts.join(': '); + }) + .join('; '); + } else errorData = errorResponse; if ('error' in errorResponse && errorResponse.error instanceof Error) @@ -3235,6 +3253,30 @@ }, }; } + /** + * Format a user-facing error message for this API error. + * + * When the error contains structured details extracted from the service response + * (e.g., DataSync `errors` array), those details are included in the message. + * Otherwise, falls back to a generic description. + * + * @param operation - Request operation during which error happened. + * + * @returns Formatted error message string. + */ + toFormattedMessage(operation) { + const fallback = 'REST API request processing error, check status for details'; + // When errorData contains a structured `errors` array, `this.message` was already + // constructed from it in `createFromServiceResponse` — prefer it over the generic fallback. + if (this.errorData && + typeof this.errorData === 'object' && + !('name' in this.errorData && 'message' in this.errorData && 'stack' in this.errorData) && + 'errors' in this.errorData && + Array.isArray(this.errorData.errors)) { + return `${operation}: ${this.message}`; + } + return fallback; + } /** * Convert API error object to PubNub client error object. * @@ -3439,6 +3481,57 @@ */ RequestOperation["PNSetMembershipsOperation"] = "PNSetMembershipsOperation"; // -------------------------------------------------------- + // ------------------- DataSync API ---------------------- + // -------------------------------------------------------- + /** + * Create entity REST API operation. + */ + RequestOperation["PNCreateEntityOperation"] = "PNCreateEntityOperation"; + /** + * Get entity REST API operation. + */ + RequestOperation["PNGetEntityOperation"] = "PNGetEntityOperation"; + /** + * Get all entities REST API operation. + */ + RequestOperation["PNGetAllEntitiesOperation"] = "PNGetAllEntitiesOperation"; + /** + * Update entity REST API operation. + */ + RequestOperation["PNUpdateEntityOperation"] = "PNUpdateEntityOperation"; + /** + * Patch entity REST API operation. + */ + RequestOperation["PNPatchEntityOperation"] = "PNPatchEntityOperation"; + /** + * Remove entity REST API operation. + */ + RequestOperation["PNRemoveEntityOperation"] = "PNRemoveEntityOperation"; + /** + * Create relationship REST API operation. + */ + RequestOperation["PNCreateRelationshipOperation"] = "PNCreateRelationshipOperation"; + /** + * Get relationship REST API operation. + */ + RequestOperation["PNGetRelationshipOperation"] = "PNGetRelationshipOperation"; + /** + * Get all relationships REST API operation. + */ + RequestOperation["PNGetAllRelationshipsOperation"] = "PNGetAllRelationshipsOperation"; + /** + * Update relationship REST API operation. + */ + RequestOperation["PNUpdateRelationshipOperation"] = "PNUpdateRelationshipOperation"; + /** + * Patch relationship REST API operation. + */ + RequestOperation["PNPatchRelationshipOperation"] = "PNPatchRelationshipOperation"; + /** + * Remove relationship REST API operation. + */ + RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- /** @@ -5656,6 +5749,10 @@ * Request will be sent using `PATCH` method. */ TransportMethod["PATCH"] = "PATCH"; + /** + * Request will be sent using `PUT` method. + */ + TransportMethod["PUT"] = "PUT"; /** * Request will be sent using `DELETE` method. */ @@ -5694,7 +5791,7 @@ signature(req) { const method = req.path.startsWith('/publish') ? TransportMethod.GET : req.method; let signatureInput = `${method}\n${this.publishKey}\n${req.path}\n${this.queryParameters(req.queryParameters)}\n`; - if (method === TransportMethod.POST || method === TransportMethod.PATCH) { + if (method === TransportMethod.POST || method === TransportMethod.PATCH || method === TransportMethod.PUT) { const body = req.body; let payload; if (body && body instanceof ArrayBuffer) { @@ -6339,7 +6436,9 @@ if (headers) request.headers = headers; // Attach body (if required). - if (request.method === TransportMethod.POST || request.method === TransportMethod.PATCH) { + if (request.method === TransportMethod.POST || + request.method === TransportMethod.PATCH || + request.method === TransportMethod.PUT) { const [body, formData] = [this.body, this.formData]; if (formData) request.formData = formData; @@ -15278,184 +15377,1031 @@ } /** - * Time REST API module. + * Create Relationship REST API module. + * + * @internal */ // endregion /** - * Get current PubNub high-precision time request. + * Create Relationship request. * * @internal */ - class TimeRequest extends AbstractRequest { - constructor() { - super(); + class CreateRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; } operation() { - return RequestOperation$1.PNTimeOperation; + return RequestOperation$1.PNCreateRelationshipOperation; } - parse(response) { - return __awaiter(this, void 0, void 0, function* () { - return { timetoken: this.deserializeResponse(response)[0] }; - }); + validate() { + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); } get path() { - return '/time/0'; + const { keySet: { subscribeKey }, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); } } /** - * Download File REST API module. + * Get All Relationships REST API module. * * @internal */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Default number of items per page. + */ + const DEFAULT_LIMIT$1 = 20; // endregion /** - * Download File request. + * Get All Relationships request. * * @internal */ - class DownloadFileRequest extends AbstractRequest { + class GetAllRelationshipsRequest extends AbstractRequest { constructor(parameters) { + var _a; super(); this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$1); } operation() { - return RequestOperation$1.PNDownloadFileOperation; + return RequestOperation$1.PNGetAllRelationshipsOperation; + } + get path() { + return `/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + } + get queryParameters() { + const { entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } + } + + /** + * Update Relationship REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + // endregion + /** + * Update Relationship request. + * + * @internal + */ + class UpdateRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNUpdateRelationshipOperation; } validate() { - const { channel, id, name } = this.parameters; - if (!channel) - return "channel can't be empty"; - if (!id) - return "file id can't be empty"; - if (!name) - return "file name can't be empty"; + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); + } + } + + /** + * Remove Relationship REST API module. + * + * @internal + */ + // endregion + /** + * Remove Relationship request. + * + * @internal + */ + class RemoveRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNRemoveRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; } parse(response) { return __awaiter(this, void 0, void 0, function* () { - const { cipherKey, crypto, cryptography, name, PubNubFile } = this.parameters; - const mimeType = response.headers['content-type']; - let decryptedFile; - let body = response.body; - if (PubNubFile.supportsEncryptFile && (cipherKey || crypto)) { - if (cipherKey && cryptography) - body = yield cryptography.decrypt(cipherKey, body); - else if (!cipherKey && crypto) - decryptedFile = yield crypto.decryptFile(PubNubFile.create({ data: body, name: name, mimeType }), PubNubFile); - } - return (decryptedFile - ? decryptedFile - : PubNubFile.create({ - data: body, - name, - mimeType, - })); + return { status: response.status }; }); } get path() { - const { keySet: { subscribeKey }, channel, id, name, } = this.parameters; - return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; } } /** - * Core PubNub API module. + * PubNub DataSync API type definitions. + * + * Types for Entity Class CRUD operations. */ - // endregion /** - * Platform-agnostic PubNub client core. + * Convert dot-notation path to JSON Pointer (RFC 6901). + * + * "config.ttlSec" → "/config/ttlSec" + * "filterableFields.0.name" → "/filterableFields/0/name" + * + * @internal */ - class PubNubCore { - /** - * Construct notification payload which will trigger push notification. - * - * @param title - Title which will be shown on notification. - * @param body - Payload which will be sent as part of notification. - * - * @returns Pre-formatted message payload which will trigger push notification. - */ - static notificationPayload(title, body) { - { - return new NotificationsPayload(title, body); + function toJsonPointer(dotPath) { + return '/' + dotPath.split('.').join('/'); + } + /** + * Convert `set` and `remove` parameters to JSON Patch operations (wire format). + * + * - Each key in `set` becomes a "replace" operation. + * - Each entry in `remove` becomes a "remove" operation. + * + * @internal + */ + function toJsonPatchOperations(set, remove) { + const ops = []; + if (set) { + for (const [dotPath, value] of Object.entries(set)) { + ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); } } - /** - * Generate unique identifier. - * - * @returns Unique identifier. - */ - static generateUUID() { - return uuidGenerator.createUUID(); + if (remove) { + for (const dotPath of remove) { + ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); + } } - // endregion - /** - * Create and configure PubNub client core. - * - * @param configuration - PubNub client core configuration. - * @returns Configured and ready to use PubNub client. - * - * @internal - */ - constructor(configuration) { - /** - * List of subscribe capable objects with active subscriptions. - * - * Track list of {@link Subscription} and {@link SubscriptionSet} objects with active - * subscription. - * - * @internal - */ - this.eventHandleCapable = {}; - /** - * Created entities. - * - * Map of entities which have been created to access. - * - * @internal - */ - this.entities = {}; - this._configuration = configuration.configuration; - this.cryptography = configuration.cryptography; - this.tokenManager = configuration.tokenManager; - this.transport = configuration.transport; - this.crypto = configuration.crypto; - this.logger.debug('PubNub', () => ({ - messageType: 'object', - message: configuration.configuration, - details: 'Create with configuration:', - ignoredKeys(key, obj) { - return typeof obj[key] === 'function' || key.startsWith('_'); - }, - })); - // API group entry points initialization. - this._objects = new PubNubObjects(this._configuration, this.sendRequest.bind(this)); - this._channelGroups = new PubNubChannelGroups(this._configuration.logger(), this._configuration.keySet, this.sendRequest.bind(this)); - this._push = new PubNubPushNotifications(this._configuration.logger(), this._configuration.keySet, this.sendRequest.bind(this)); - { - // Prepare for a real-time events announcement. - this.eventDispatcher = new EventDispatcher(); - if (this._configuration.enableEventEngine) { - { - this.logger.debug('PubNub', 'Using new subscription loop management.'); - let heartbeatInterval = this._configuration.getHeartbeatInterval(); - this.presenceState = {}; - { - if (heartbeatInterval) { - this.presenceEventEngine = new PresenceEventEngine({ - heartbeat: (parameters, callback) => { - this.logger.trace('PresenceEventEngine', () => ({ - messageType: 'object', - message: Object.assign({}, parameters), - details: 'Heartbeat with parameters:', - })); - return this.heartbeat(parameters, callback); - }, - leave: (parameters) => { - this.logger.trace('PresenceEventEngine', () => ({ - messageType: 'object', - message: Object.assign({}, parameters), - details: 'Leave with parameters:', - })); + return ops; + } + + /** + * Patch Relationship REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) + * and converts them to JSON Patch operations on the wire. + * + * @internal + */ + // endregion + /** + * Patch Relationship request. + * + * @internal + */ + class PatchRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNPatchRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasSet && !hasRemove) + return 'At least one of set or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'role') and the SDK produces '/payload/role' on the wire. + const prefixedSet = this.parameters.set + ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) + : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedSet, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } + } + + /** + * Get Relationship REST API module. + * + * @internal + */ + // endregion + /** + * Get Relationship request. + * + * @internal + */ + class GetRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + } + + /** + * Create Entity REST API module. + * + * @internal + */ + // endregion + /** + * Create Entity request. + * + * @internal + */ + class CreateEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNCreateEntityOperation; + } + validate() { + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (!this.parameters.entity.entityClass) + return 'Entity class cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/subkeys/${subscribeKey}/entities`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } + } + + /** + * Get All Entities REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Default number of items per page. + */ + const DEFAULT_LIMIT = 20; + // endregion + /** + * Get All Entities request. + * + * @internal + */ + class GetAllEntitiesRequest extends AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return RequestOperation$1.PNGetAllEntitiesOperation; + } + validate() { + if (!this.parameters.entityClass) + return 'Entity class cannot be empty'; + } + get path() { + return `/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + } + get queryParameters() { + const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ entity_class: entityClass }, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } + } + + /** + * Update Entity REST API module. + * + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. + * + * @internal + */ + // endregion + /** + * Update Entity request. + * + * @internal + */ + class UpdateEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNUpdateEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } + } + + /** + * Remove Entity REST API module. + * + * @internal + */ + // endregion + /** + * Remove Entity request. + * + * @internal + */ + class RemoveEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNRemoveEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + } + + /** + * Patch Entity REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) + * and converts them to JSON Patch operations on the wire. + * + * @internal + */ + // endregion + /** + * Patch Entity request. + * + * @internal + */ + class PatchEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNPatchEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasSet && !hasRemove) + return 'At least one of set or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. + const prefixedSet = this.parameters.set + ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) + : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedSet, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } + } + + /** + * Get Entity REST API module. + * + * @internal + */ + // endregion + /** + * Get Entity request. + * + * @internal + */ + class GetEntityRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + } + + /** + * PubNub DataSync API module. + */ + /** + * PubNub DataSync API interface. + */ + class PubNubDataSync { + /** + * Create DataSync API access object. + * + * @param configuration - Extended PubNub client configuration object. + * @param sendRequest - Function which should be used to send REST API calls. + * + * @internal + */ + constructor(configuration, + /* eslint-disable @typescript-eslint/no-explicit-any */ + sendRequest) { + this.keySet = configuration.keySet; + this.configuration = configuration; + this.sendRequest = sendRequest; + } + /** + * Get registered loggers' manager. + * + * @returns Registered loggers' manager. + * + * @internal + */ + get logger() { + return this.configuration.logger(); + } + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create entity response or `void` in case if `callback` provided. + */ + createEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Entity with parameters:', + })); + const request = new CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get entity response or `void` in case if `callback` provided. + */ + getEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Entity with parameters:', + })); + const request = new GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all entities response or `void` in case if `callback` provided. + */ + getAllEntities(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Entities with parameters:', + })); + const request = new GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update entity response or `void` in case if `callback` provided. + */ + updateEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Entity with parameters:', + })); + const request = new UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch entity response or `void` in case if `callback` provided. + */ + patchEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Entity with parameters:', + })); + const request = new PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove entity response or `void` in case if `callback` provided. + */ + removeEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Entity with parameters:', + })); + const request = new RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create relationship response or `void` in case if `callback` provided. + */ + createRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Relationship with parameters:', + })); + const request = new CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get relationship response or `void` in case if `callback` provided. + */ + getRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Relationship with parameters:', + })); + const request = new GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Relationships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + */ + getAllRelationships(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Relationships with parameters:', + })); + const request = new GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. + */ + updateRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Relationship with parameters:', + })); + const request = new UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch relationship response or `void` in case if `callback` provided. + */ + patchRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Relationship with parameters:', + })); + const request = new PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove relationship response or `void` in case if `callback` provided. + */ + removeRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Relationship with parameters:', + })); + const request = new RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + } + + /** + * Time REST API module. + */ + // endregion + /** + * Get current PubNub high-precision time request. + * + * @internal + */ + class TimeRequest extends AbstractRequest { + constructor() { + super(); + } + operation() { + return RequestOperation$1.PNTimeOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { timetoken: this.deserializeResponse(response)[0] }; + }); + } + get path() { + return '/time/0'; + } + } + + /** + * Download File REST API module. + * + * @internal + */ + // endregion + /** + * Download File request. + * + * @internal + */ + class DownloadFileRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNDownloadFileOperation; + } + validate() { + const { channel, id, name } = this.parameters; + if (!channel) + return "channel can't be empty"; + if (!id) + return "file id can't be empty"; + if (!name) + return "file name can't be empty"; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + const { cipherKey, crypto, cryptography, name, PubNubFile } = this.parameters; + const mimeType = response.headers['content-type']; + let decryptedFile; + let body = response.body; + if (PubNubFile.supportsEncryptFile && (cipherKey || crypto)) { + if (cipherKey && cryptography) + body = yield cryptography.decrypt(cipherKey, body); + else if (!cipherKey && crypto) + decryptedFile = yield crypto.decryptFile(PubNubFile.create({ data: body, name: name, mimeType }), PubNubFile); + } + return (decryptedFile + ? decryptedFile + : PubNubFile.create({ + data: body, + name, + mimeType, + })); + }); + } + get path() { + const { keySet: { subscribeKey }, channel, id, name, } = this.parameters; + return `/v1/files/${subscribeKey}/channels/${encodeString(channel)}/files/${id}/${name}`; + } + } + + /** + * Core PubNub API module. + */ + // endregion + /** + * Platform-agnostic PubNub client core. + */ + class PubNubCore { + /** + * Construct notification payload which will trigger push notification. + * + * @param title - Title which will be shown on notification. + * @param body - Payload which will be sent as part of notification. + * + * @returns Pre-formatted message payload which will trigger push notification. + */ + static notificationPayload(title, body) { + { + return new NotificationsPayload(title, body); + } + } + /** + * Generate unique identifier. + * + * @returns Unique identifier. + */ + static generateUUID() { + return uuidGenerator.createUUID(); + } + // endregion + /** + * Create and configure PubNub client core. + * + * @param configuration - PubNub client core configuration. + * @returns Configured and ready to use PubNub client. + * + * @internal + */ + constructor(configuration) { + /** + * List of subscribe capable objects with active subscriptions. + * + * Track list of {@link Subscription} and {@link SubscriptionSet} objects with active + * subscription. + * + * @internal + */ + this.eventHandleCapable = {}; + /** + * Created entities. + * + * Map of entities which have been created to access. + * + * @internal + */ + this.entities = {}; + this._configuration = configuration.configuration; + this.cryptography = configuration.cryptography; + this.tokenManager = configuration.tokenManager; + this.transport = configuration.transport; + this.crypto = configuration.crypto; + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: configuration.configuration, + details: 'Create with configuration:', + ignoredKeys(key, obj) { + return typeof obj[key] === 'function' || key.startsWith('_'); + }, + })); + // API group entry points initialization. + this._objects = new PubNubObjects(this._configuration, this.sendRequest.bind(this)); + this._dataSync = new PubNubDataSync(this._configuration, this.sendRequest.bind(this)); + this._channelGroups = new PubNubChannelGroups(this._configuration.logger(), this._configuration.keySet, this.sendRequest.bind(this)); + this._push = new PubNubPushNotifications(this._configuration.logger(), this._configuration.keySet, this.sendRequest.bind(this)); + { + // Prepare for a real-time events announcement. + this.eventDispatcher = new EventDispatcher(); + if (this._configuration.enableEventEngine) { + { + this.logger.debug('PubNub', 'Using new subscription loop management.'); + let heartbeatInterval = this._configuration.getHeartbeatInterval(); + this.presenceState = {}; + { + if (heartbeatInterval) { + this.presenceEventEngine = new PresenceEventEngine({ + heartbeat: (parameters, callback) => { + this.logger.trace('PresenceEventEngine', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Heartbeat with parameters:', + })); + return this.heartbeat(parameters, callback); + }, + leave: (parameters) => { + this.logger.trace('PresenceEventEngine', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Leave with parameters:', + })); this.makeUnsubscribe(parameters, () => { }); }, heartbeatDelay: () => new Promise((resolve, reject) => { @@ -16029,17 +16975,18 @@ }) .catch((error) => { const apiError = !(error instanceof PubNubAPIError) ? PubNubAPIError.create(error) : error; + const errorMessage = apiError.toFormattedMessage(operation); // Notify callback (if possible). if (callback) { if (apiError.category !== StatusCategory$1.PNCancelledCategory) { this.logger.error('PubNub', () => ({ messageType: 'error', - message: apiError.toPubNubError(operation, 'REST API request processing error, check status for details'), + message: apiError.toPubNubError(operation, errorMessage), })); } return callback(apiError.toStatus(operation), null); } - const pubNubError = apiError.toPubNubError(operation, 'REST API request processing error, check status for details'); + const pubNubError = apiError.toPubNubError(operation, errorMessage); if (apiError.category !== StatusCategory$1.PNCancelledCategory) this.logger.error('PubNub', () => ({ messageType: 'error', message: pubNubError })); throw pubNubError; @@ -17344,6 +18291,16 @@ get objects() { return this._objects; } + // -------------------------------------------------------- + // -------------------- DataSync API --------------------- + // -------------------------------------------------------- + // region DataSync API + /** + * PubNub DataSync API group. + */ + get dataSync() { + return this._dataSync; + } /** Fetch a paginated list of User objects. * diff --git a/dist/web/pubnub.min.js b/dist/web/pubnub.min.js index 6010069be..659054193 100644 --- a/dist/web/pubnub.min.js +++ b/dist/web/pubnub.min.js @@ -1,2 +1,2 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var m=function e(){var r,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)y(C,d);else y(C,d);return String.fromCharCode.apply(null,C);case 4:var P;if(d<0)for(P=[];!p();)P.push(e());else for(P=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNServerErrorCategory="PNServerErrorCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory",e.PNSharedWorkerUpdatedCategory="PNSharedWorkerUpdatedCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],y=e[i+8],m=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],j=a[2],P=a[3],c,7,u[0]),P=t(P,C,E,j,o,12,u[1]),j=t(j,P,C,E,l,17,u[2]),E=t(E,j,P,C,h,22,u[3]);C=t(C,E,j,P,d,7,u[4]),P=t(P,C,E,j,p,12,u[5]),j=t(j,P,C,E,g,17,u[6]),E=t(E,j,P,C,b,22,u[7]),C=t(C,E,j,P,y,7,u[8]),P=t(P,C,E,j,m,12,u[9]),j=t(j,P,C,E,f,17,u[10]),E=t(E,j,P,C,v,22,u[11]),C=t(C,E,j,P,S,7,u[12]),P=t(P,C,E,j,w,12,u[13]),j=t(j,P,C,E,O,17,u[14]),C=s(C,E=t(E,j,P,C,k,22,u[15]),j,P,o,5,u[16]),P=s(P,C,E,j,g,9,u[17]),j=s(j,P,C,E,v,14,u[18]),E=s(E,j,P,C,c,20,u[19]),C=s(C,E,j,P,p,5,u[20]),P=s(P,C,E,j,f,9,u[21]),j=s(j,P,C,E,k,14,u[22]),E=s(E,j,P,C,d,20,u[23]),C=s(C,E,j,P,m,5,u[24]),P=s(P,C,E,j,O,9,u[25]),j=s(j,P,C,E,h,14,u[26]),E=s(E,j,P,C,y,20,u[27]),C=s(C,E,j,P,w,5,u[28]),P=s(P,C,E,j,l,9,u[29]),j=s(j,P,C,E,b,14,u[30]),C=n(C,E=s(E,j,P,C,S,20,u[31]),j,P,p,4,u[32]),P=n(P,C,E,j,y,11,u[33]),j=n(j,P,C,E,v,16,u[34]),E=n(E,j,P,C,O,23,u[35]),C=n(C,E,j,P,o,4,u[36]),P=n(P,C,E,j,d,11,u[37]),j=n(j,P,C,E,b,16,u[38]),E=n(E,j,P,C,f,23,u[39]),C=n(C,E,j,P,w,4,u[40]),P=n(P,C,E,j,c,11,u[41]),j=n(j,P,C,E,h,16,u[42]),E=n(E,j,P,C,g,23,u[43]),C=n(C,E,j,P,m,4,u[44]),P=n(P,C,E,j,S,11,u[45]),j=n(j,P,C,E,k,16,u[46]),C=r(C,E=n(E,j,P,C,l,23,u[47]),j,P,c,6,u[48]),P=r(P,C,E,j,b,10,u[49]),j=r(j,P,C,E,O,15,u[50]),E=r(E,j,P,C,p,21,u[51]),C=r(C,E,j,P,S,6,u[52]),P=r(P,C,E,j,h,10,u[53]),j=r(j,P,C,E,f,15,u[54]),E=r(E,j,P,C,o,21,u[55]),C=r(C,E,j,P,y,6,u[56]),P=r(P,C,E,j,k,10,u[57]),j=r(j,P,C,E,g,15,u[58]),E=r(E,j,P,C,w,21,u[59]),C=r(C,E,j,P,d,6,u[60]),P=r(P,C,E,j,v,10,u[61]),j=r(j,P,C,E,l,15,u[62]),E=r(E,j,P,C,m,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+j|0,a[3]=a[3]+P|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,r[m]=b;var f=p[b],v=p[f],w=p[v],O=257*p[m]^16843008*m;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[m]=O<<24|O>>>8,l[m]=O<<16|O>>>16,h[m]=O<<8|O>>>24,d[m]=O,b?(b=f^p[p[p[w^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w,O=t(S);class k{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=O,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:k.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return k.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(k.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=k.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return O.HmacSHA256(e,this.configuration.secretKey).toString(O.enc.Base64)}SHA256(e){return O.SHA256(e).toString(O.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=O.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(O.enc.Base64)}const a=this.getIV(s);return O.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(O.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=C(t.slice(0,16)),n=C(t.slice(16));try{const e=O.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(O.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=O.enc.Base64.parse(e),n=O.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(O.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?O.enc.Base64.parse(e):"hex"===t.keyEncoding?O.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?O.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?O.mode.ECB:O.mode.CBC}getIV(e){return"cbc"===e.mode?O.enc.Utf8.parse(this.iv):null}getRandomIV(){return O.lib.WordArray.random(16)}}class j{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=j.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return j.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(j.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(j.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=j.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return j.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",j.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=j.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}j.IV_LENGTH=16,j.encoder=new TextEncoder,j.decoder=new TextDecoder;class E{constructor(e){this.config=e,this.cryptor=new P(Object.assign({},e)),this.fileCryptor=new j}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:E.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`AesCbcCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}E.encoder=new TextEncoder,E.decoder=new TextDecoder;class N extends a{set logger(e){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===N.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new N({default:new E(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new k({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new N({default:new k({cipherKey:e.cipherKey}),cryptors:[new E(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(N.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===T.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=T.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=T.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===T.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof _)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=T.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}N.LEGACY_IDENTIFIER="";class T{static from(e,t){if(e!==T.LEGACY_IDENTIFIER)return new _(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==T.SENTINEL))return N.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>T.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+T.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new _(this.decoder.decode(n),a)}}T.SENTINEL="PNED",T.LEGACY_IDENTIFIER="",T.IDENTIFIER_LENGTH=4,T.VERSION=1,T.MAX_VERSION=1,T.decoder=new TextDecoder;class _{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return T.VERSION}get length(){return T.SENTINEL.length+1+T.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(T.SENTINEL)),e+=T.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=T.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}_.IDENTIFIER_LENGTH=4,_.SENTINEL="PNED";class I extends Error{static create(e,t){return I.isErrorObject(e)?I.createFromError(e):I.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new I(s,t,0);if(e instanceof I)return e;if(I.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new I(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":404===i?r="Resource not found":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i?(n=h.PNAccessDeniedCategory,r="Access denied"):i>=500&&(n=h.PNServerErrorCategory,r="Internal server error"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new I(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,I.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}!function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(w||(w={}));var M=w;class A{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}set emitStatus(e){this._emitStatus=e}onUserIdChange(e){this.configuration.userId=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onPresenceStateChange(e){this.scheduleEventPost({type:"client-presence-state-update",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel,state:e})}onHeartbeatIntervalChange(e){this.configuration.heartbeatInterval=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onTokenChange(e){const t={type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel};this.parsedAccessToken(e).then((s=>{t.preProcessedToken=s,t.accessToken=e})).then((()=>this.scheduleEventPost(t)))}disconnect(){this.scheduleEventPost({type:"client-disconnect",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e,workerLogLevel:this.configuration.workerLogLevel};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier,workerLogLevel:this.configuration.workerLogLevel};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.preProcessedToken=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogLevel:this.configuration.workerLogLevel},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e),this.shouldAnnounceNewerSharedWorkerVersionAvailability()&&localStorage.setItem("PNSubscriptionSharedWorkerVersion",this.configuration.sdkVersion),window.addEventListener("storage",(e=>{"PNSubscriptionSharedWorkerVersion"===e.key&&e.newValue&&this._emitStatus&&this.isNewerSharedWorkerVersion(e.newValue)&&this._emitStatus({error:!1,category:h.PNSharedWorkerUpdatedCategory})}))}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",(()=>"string"==typeof t.message||"number"==typeof t.message||"boolean"==typeof t.message?{messageType:"text",message:t.message}:t.message));else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t,workerLogLevel:this.configuration.workerLogLevel})}else if("request-process-success"===t.type||"request-process-error"===t.type)if(this.callbacks.has(t.identifier)){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);this.callbacks.delete(t.identifier),"request-process-success"===t.type?e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body}):s(this.errorFromRequestSendingError(t))}else this._emitStatus&&t.url.indexOf("/v2/presence")>=0&&t.url.indexOf("/heartbeat")>=0&&("request-process-success"===t.type&&this.configuration.announceSuccessfulHeartbeats?this._emitStatus({statusCode:t.response.status,error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}):"request-process-error"===t.type&&this.configuration.announceFailedHeartbeats&&this._emitStatus(this.errorFromRequestSendingError(t).toStatus(M.PNHeartbeatOperation)))}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;return this.parsedAccessToken(e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0)}))}parsedAccessToken(e){return i(this,void 0,void 0,(function*(){if(e)return this.accessTokensMap[e]?this.accessTokensMap[e]:this.stringifyAccessToken(e).then((([t,s])=>{if(t&&s)return(this.accessTokensMap={[e]:{token:s,expiration:t.timestamp+60*t.ttl}})[e]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}errorFromRequestSendingError(e){let t=h.PNUnknownCategory,s="Unknown error";if(e.error)"NETWORK_ISSUE"===e.error.type?t=h.PNNetworkIssuesCategory:"TIMEOUT"===e.error.type?t=h.PNTimeoutCategory:"ABORTED"===e.error.type&&(t=h.PNCancelledCategory),s=`${e.error.message} (${e.identifier})`;else if(e.response){const{url:t,response:s}=e;return I.create({url:t,headers:s.headers,body:s.body,status:s.status},s.body)}return new I(s,t,0,new Error(s))}shouldAnnounceNewerSharedWorkerVersionAvailability(){const e=localStorage.getItem("PNSubscriptionSharedWorkerVersion");return!e||!this.isNewerSharedWorkerVersion(e)}isNewerSharedWorkerVersion(e){const[t,s,n]=this.configuration.sdkVersion.split(".").map(Number),[r,i,a]=e.split(".").map(Number);return r>t||i>s||a>n}}function U(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?U(c,t+1):c})),r}const D=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(r=m.fileRequestTimeout)&&void 0!==r||(m.fileRequestTimeout=300),null!==(i=m.restore)&&void 0!==i||(m.restore=!0),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!0),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,w=5,O=!1,k=100,C=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(O=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(C=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(w=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:O,maximumCacheSize:k,useRequestId:C,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:w})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var R;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(R||(R={}));const $=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),F=(e,t)=>{const s=e.map((e=>$(e)));return s.length?s.join(","):null!=t?t:""},x=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},L=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),q=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&"),G=(e,t)=>{if("0"===t||"0"===e)return;const s=H(`${Date.now()}0000`,t,!1);return H(e,s,!0)},K=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=H(e,t,!1);return H(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},H=(e,t,s)=>{t.startsWith("-")&&(t=t.replace("-",""),s=!1),t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0?o>0?(o-=1,c+=1e7):o<0&&(c*=-1):o<0&&c>0&&(o+=1,c=1e7-c),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},B=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class W{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}toString(){return"ConsoleLogger {}"}log(e){const t=R[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==R.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?q(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===R.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(h,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${W.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(W.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}var z;W.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(z||(z={}));class V{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return J(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return J(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry")}}}}const J=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!X(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),X=(e,t)=>!!(t&&t.length>0)&&t.includes(Q(e)),Q=e=>{let t=z.Unknown;return e.path.startsWith("/v2/subscribe")?t=z.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=z.MessageSend:e.path.startsWith("/v2/presence")?t=z.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=z.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=z.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=z.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=z.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=z.Files),t};class Y{constructor(e,t,s){this.previousEntryTimestamp=0,this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(R.Trace,e,t)}debug(e,t){this.log(R.Debug,e,t)}info(e,t){this.log(R.Info,e,t)}warn(e,t){this.log(R.Warn,e,t)}error(e,t){this.log(R.Error,e,t)}log(e,t,s){if(ee[r](i)))}}var Z={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(Z,Z.exports);var ee=t(Z.exports),te={createUUID:()=>ee.uuid?ee.uuid():ee()};const se=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=V.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[z.MessageSend,z.Presence,z.Files,z.MessageStorage,z.ChannelGroups,z.DevicePushNotifications,z.AppContext,z.MessageReactions]}));const a=`pn-${te.createUUID()}`;e.logVerbosity?e.logLevel=R.Debug:void 0===e.logLevel&&(e.logLevel=R.None);const o=new Y(re(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new W]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=ne(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,isSharedWorkerEnabled:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"11.0.0"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},ne=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},re=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class ie{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var ae;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(ae||(ae={}));class oe{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?ae.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===ae.POST||t===ae.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=oe.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${$(e)}`)).join("&"):`${t}=${$(s)}`})).join("&")}}oe.textDecoder=new TextDecoder("utf-8");class ce{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new oe(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=(!s||s.status>=400)&&404!==(null==r?void 0:r.statusCode);let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ue{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ue.originalFetch=ue.getOriginalFetch(),this.isFetchMonkeyPatched()&&e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw I.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:I.create(n).message,failed:!0}))),I.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ue.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(I.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ue.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${q(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ue.encoder=new TextEncoder,ue.decoder=new TextDecoder;class le{constructor(e){this.params=e,this.requestIdentifier=te.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:ae.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===ae.POST||a.method===ae.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=le.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw I.create(e);return n}}le.decoder=new TextDecoder;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends le{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return M.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=le.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message);const s=B(e.d);return t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:{type:he.Files,data:this.fileFromEnvelope(e),pn_mfp:s}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e),pn_mfp:s}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e),pn_mfp:s}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e),pn_mfp:s}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e),pn_mfp:s}:{type:he.Files,data:this.fileFromEnvelope(e),pn_mfp:s}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${F(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i,onDemand:a}=this.parameters,o={};return a&&(o["on-demand"]=1),e&&e.length>0&&(o["channel-group"]=e.sort().join(",")),t&&t.length>0&&(o["filter-expr"]=t),s&&(o.heartbeat=s),n&&Object.keys(n).length>0&&(o.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(o.tt=r):void 0!==r&&r>0&&(o.tt=r),i&&(o.tr=i),o}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ye{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;if(null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size)return;const o=this.lastTimetoken,c=this.currentTimetoken;0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0),!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:c,lastTimetoken:o}))})))}unsubscribeAll(e=!1){this.disconnectedWhileHandledEvent=!0,this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.disconnectedWhileHandledEvent=!1,this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),{onDemand:!this.subscriptionStatusAnnounced||e}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=K(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>({type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:e.pn_mfp})}))),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.disconnectedWhileHandledEvent?this.disconnectedWhileHandledEvent=!1:this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get androidNotification(){var e;return null===(e=this.payload.android)||void 0===e?void 0:e.notification}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this.androidNotification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this.androidNotification.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.androidNotification.notification_count=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.androidNotification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.androidNotification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.androidNotification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={},this.payload.android={notification:{}}}toObject(){var e,t;const s={},n=Object.assign({},this.payload.notification),i=Object.assign({},this.payload.android),a=r(Object.assign({},null!==(e=i.notification)&&void 0!==e?e:{}),["title","body"]);if(this._isSilent){const e={};this._title&&(e.title=this._title),this._body&&(e.body=this._body);for(const[t,s]of Object.entries(a))null!=s&&(e[t]=String(s));this.payload.data&&Object.assign(e,this.payload.data),Object.keys(e).length&&(s.data=e),delete i.notification,Object.keys(i).length&&(s.android=i)}else if(Object.keys(n).length&&(s.notification=n),this.payload.data&&Object.keys(this.payload.data).length&&(s.data=Object.assign({},this.payload.data)),Object.keys(a).length){const e=r(i,["notification"]);s.android=Object.assign(Object.assign({},e),{notification:a})}else{const e=r(i,["notification"]);Object.keys(e).length&&(s.android=e)}const o=r(this.payload,["notification","android","data","pn_exceptions"]);return Object.assign(s,o),(null===(t=this.payload.pn_exceptions)||void 0===t?void 0:t.length)&&(s.pn_exceptions=this.payload.pn_exceptions),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_fcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Oe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ce extends Oe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class Pe{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function je(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends Oe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Ue=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),De=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),Re=Ee("EMIT_STATUS",(e=>e)),$e=Ne("WAIT",(()=>({}))),Fe=je("RECONNECT",(()=>({}))),xe=je("DISCONNECT",((e=!1)=>({isOffline:e}))),Le=je("JOINED",((e,t)=>({channels:e,groups:t}))),qe=je("LEFT",((e,t)=>({channels:e,groups:t}))),Ge=je("LEFT_ALL",((e=!1)=>({isOffline:e}))),Ke=je("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=je("HEARTBEAT_FAILURE",(e=>e)),Be=je("TIMES_UP",(()=>({})));class We extends Pe{constructor(e,t){super(t,t.config.logger()),this.on(Ue.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Ke(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on(De.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on($e.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on(Re.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:M.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const ze=new ke("HEARTBEAT_STOPPED");ze.on(Le.type,((e,t)=>ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),ze.on(qe.type,((e,t)=>ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),ze.on(Fe.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(Ge.type,((e,t)=>Qe.with(void 0)));const Ve=new ke("HEARTBEAT_COOLDOWN");Ve.onEnter((()=>$e())),Ve.onExit((()=>$e.cancel)),Ve.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(Le.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ve.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[De(t.payload.channels,t.payload.groups)]))),Ve.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[De(e.channels,e.groups)]]))),Ve.on(Ge.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[De(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(Le.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[De(t.payload.channels,t.payload.groups)]))),Je.on(Fe.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[De(e.channels,e.groups)]]))),Je.on(Ge.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[De(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Ue(e.channels,e.groups))),Xe.onExit((()=>Ue.cancel)),Xe.on(Ke.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[Re(Object.assign({},t.payload))]))),Xe.on(Le.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(qe.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[De(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[Re(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[De(e.channels,e.groups)]]))),Xe.on(Ge.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[De(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(Le.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ce(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(Le(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){e&&(this.channels=this.channels.filter((t=>!e.includes(t)))),t&&(this.groups=this.groups.filter((e=>!t.includes(e)))),this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(qe(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.dependencies.presenceState&&(this.channels.forEach((e=>delete this.dependencies.presenceState[e])),this.groups.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=[],this.groups=[],this.engine.transition(Ge(e))}reconnect(){this.engine.transition(Fe())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t,s)=>({channels:e,groups:t,onDemand:s}))),et=Ne("RECEIVE_MESSAGES",((e,t,s,n)=>({channels:e,groups:t,cursor:s,onDemand:n}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=je("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),rt=je("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),it=je("HANDSHAKE_SUCCESS",(e=>e)),at=je("HANDSHAKE_FAILURE",(e=>e)),ot=je("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=je("RECEIVE_FAILURE",(e=>e)),ut=je("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=je("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=je("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,onDemand:!0}))),dt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region},onDemand:!0})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),pt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),gt.on(rt.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0},onDemand:!0})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>{var t;return Ze(e.channels,e.groups,null!==(t=e.onDemand)&&void 0!==t&&t)})),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),bt.on(it.type,((e,{payload:t})=>{var s,n,r,i,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:K(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),operation:M.PNSubscribeOperation,currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(rt.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0},onDemand:!0})})),bt.on(ht.type,(e=>dt.with()));const yt=new ke("RECEIVE_STOPPED");yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),yt.on(ht.type,(()=>dt.with(void 0)));const mt=new ke("RECEIVE_FAILED");mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),mt.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},onDemand:!0}))),mt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>{var t;return et(e.channels,e.groups,e.cursor,null!==(t=e.onDemand)&&void 0!==t&&t)})),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:K(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory,operation:M.PNUnsubscribeOperation},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken,onDemand:!0},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(rt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:K(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken),onDemand:!0},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation);return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,operation:M.PNSubscribeOperation,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return yt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory,operation:M.PNSubscribeOperation})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory,operation:M.PNUnsubscribeOperation})])));class vt extends Pe{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}),{onDemand:t.onDemand}));return e.transition(it(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression,onDemand:t.onDemand});e.transition(ot(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ce(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return G(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){var r;const i=null==e?void 0:e.some((e=>!this.channels.includes(e))),a=null==t?void 0:t.some((e=>!this.groups.includes(e))),o=i||a;if(this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s)this.engine.transition(rt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s));else if(o)this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]]))));else{this.dependencies.config.logger().debug("EventEngine","Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.");const e=this.engine.currentState,t=this.engine.currentContext;let s="0";if((null==e?void 0:e.label)===ft.label&&t){s=null===(r=t.cursor)||void 0===r?void 0:r.timetoken}this.dependencies.emitStatus({category:h.PNSubscriptionChangedCategory,affectedChannels:Array.from(new Set(this.channels)),affectedChannelGroups:Array.from(new Set(this.groups)),currentTimetoken:s})}this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=x(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=x(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=L(this.channels,e),i=L(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannelGroups(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends le{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?ae.POST:ae.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return M.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${$(t)}/0${this.parameters.sendByPost?"":`/${$(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ot extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${$(s)}/0/${$(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return M.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${F(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n,onDemand:r}=this.parameters,i={ee:""};return r&&(i["on-demand"]=1),e&&e.length>0&&(i["channel-group"]=e.sort().join(",")),t&&t.length>0&&(i["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(i.tt=s):s&&s>0&&(i.tt=s),n&&(i.tr=n),i}}class Ct extends de{operation(){return M.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${F(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s,onDemand:n}=this.parameters,r={ee:""};return n&&(r["on-demand"]=1),e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),s&&Object.keys(s).length>0&&(r.state=JSON.stringify(s)),r}}var Pt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Pt||(Pt={}));class jt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new jt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new jt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Et{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=te.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Nt{constructor(e,t="Subscription"){this.subscriptionType=t,this.id=te.createUUID(),this.eventDispatcher=new ge,this._state=e}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Tt extends Et{constructor(e){const t=new jt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class _t extends Nt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Tt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t,"SubscriptionSet"),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new _t({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>e?{messageType:"object",message:{subscription:this,subscriptions:e},details:"Unregister subscriptions of subscription set from real-time events:"}:{messageType:"text",message:`Unregister subscription from real-time events: ${this}`})),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class It extends Et{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new jt({[e.entity.subscriptionType==Pt.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Mt extends Nt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new It(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s,n;if(this.state.isSubscribed&&this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)){if(this.parentSetsCount>0){const e=B(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Event (${e}) already handled by ${this.id}. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(n=t.data.subscription)&&void 0!==n?n:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new jt({}):this.state.subscriptionInput}cloneEmpty(){return new Mt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new _t({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class At extends le{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return M.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=s?s:[],",")}/uuid/${$(null!=t?t:"")}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Ut extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?void 0===t?"Missing State":0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=s?s:[],",")}/uuid/${$(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class Dt extends le{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return M.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),void 0!==t&&(n.state=JSON.stringify(t)),n}}class Rt extends le{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return M.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${F(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class $t extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${$(t)}`}}class Ft extends le{constructor(e){var t,s,n,r,i,a,o,c;super(),this.parameters=e,null!==(t=(i=this.parameters).queryParameters)&&void 0!==t||(i.queryParameters={}),null!==(s=(a=this.parameters).includeUUIDs)&&void 0!==s||(a.includeUUIDs=true),null!==(n=(o=this.parameters).includeState)&&void 0!==n||(o.includeState=false),null!==(r=(c=this.parameters).limit)&&void 0!==r||(c.limit=1e3)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?M.PNGlobalHereNowOperation:M.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};const c=this.parameters.limit;let u=!1;if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy},u||t.occupancy!==c||(u=!0)})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${F(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,limit:n,offset:r,queryParameters:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},this.operation()===M.PNHereNowOperation?{limit:n}:{}),this.operation()===M.PNHereNowOperation&&null!=r&&r?{offset:r}:{}),t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),i)}}class xt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Lt extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${F(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class qt extends le{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return M.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${$(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(qt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Gt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Gt||(Gt={}));class Kt extends le{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return M.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Gt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${F(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Kt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Gt.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Ht extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Bt extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Wt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${$(t)}/message/${n}/action/${s}`}}class zt extends le{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return M.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${$(t)}/0/${$(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Vt extends le{constructor(e){super({method:ae.LOCAL}),this.parameters=e}operation(){return M.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${$(e)}/files/${t}/${s}`}}class Jt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(s)}/files/${t}/${n}`}}class Xt extends le{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return M.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Qt extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Yt extends le{constructor(e){super({method:ae.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return M.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Yt.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Zt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:M.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof I?e:I.create(e);throw new d("File upload error.",t.toStatus(M.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Qt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Yt({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return Pt.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Mt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return Pt.ChannelGroup}}class ns extends es{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends es{get entityType(){return"Channel"}get name(){return this._nameOrId}}class is extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}`}}class cs extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${$(t)}/remove`}}class us extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.debug("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new is(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends le{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: fcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return M.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return M.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return M.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return M.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ys{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ms extends le{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return M.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class fs extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}}class vs extends le{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends le{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends le{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return M.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends le{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return M.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends le{constructor(e){var t,s,n;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return M.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Cs extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}}class Ps extends le{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return M.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class js extends le{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return M.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${$(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends le{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends le{constructor(e){var t,s,n;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${$(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Cs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ms(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new js(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends le{constructor(){super()}operation(){return M.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Is extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${$(t)}/files/${s}/${n}`}}class Ms{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return te.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ys(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?B(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new me(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e,this.onUserIdChange&&this.onUserIdChange(this._configuration.userId)}getUserId(){return this._configuration.userId}setUserId(e){this.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){var t;this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e),this.onHeartbeatIntervalChange&&this.onHeartbeatIntervalChange(null!==(t=this._configuration.getHeartbeatInterval())&&void 0!==t?t:0)}setHeartbeatInterval(e){this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new rs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new _t({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===M.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===M.PNSubscribeOperation||i===M.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Ms.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof I?e:I.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new jt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"})));let n,r=!t||0===t.length;if(!r&&e instanceof _t&&e.subscriptions.length===(null==t?void 0:t.length)&&(r=e.subscriptions.every((e=>t.includes(e)))),r&&delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new jt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof _t?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===Pt.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof _t?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof Mt&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new jt({channels:t,channelGroups:e})),n.isEmpty))return}const i={};i.channels=n.channels,i.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(i):this.eventEngine&&this.eventEngine.unsubscribe(i)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:M.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Rt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub",`Disconnect (while offline? ${e?"yes":"no"})`),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Ft(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new $t({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new At(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state))),this.onPresenceStateChange&&this.onPresenceStateChange(this.presenceState)}o="withHeartbeat"in e&&e.withHeartbeat?new Dt(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Ut(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof Dt?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&(this.subscriptionManager.setState(e),this.onPresenceStateChange&&this.onPresenceStateChange(this.subscriptionManager.presenceState)),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new Dt(Object.assign(Object.assign({},e),{channels:[...new Set(n)],channelGroups:[...new Set(r)],keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:M.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof I&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${$(t)}`)).join("&"):`${e}=${$(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new _s,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s!==this._globalSubscriptionSet&&s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Ms.decoder=new TextDecoder,Ms.OPERATIONS=M,Ms.CATEGORIES=h,Ms.Endpoint=z,Ms.ExponentialRetryPolicy=V.ExponentialRetryPolicy,Ms.LinearRetryPolicy=V.LinearRetryPolicy,Ms.NoneRetryPolicy=V.None,Ms.LogLevel=R;class As{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Us extends Ms{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=D(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=se(i,(e=>{if(e.cipherKey){return new N({default:new E(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new k({cipherKey:e.cipherKey})]})}}));let u,l;e.subscriptionWorkerLogVerbosity?e.subscriptionWorkerLogLevel=R.Debug:void 0===e.subscriptionWorkerLogLevel&&(e.subscriptionWorkerLogLevel=R.None),void 0!==e.subscriptionWorkerLogVerbosity&&a.logger().warn("Configuration","'subscriptionWorkerLogVerbosity' is deprecated. Use 'subscriptionWorkerLogLevel' instead."),a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new ie(new As((e=>U(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new P({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()}));let h,d=()=>{},p=()=>{},g=()=>{},b=()=>{};h=new j;let y=new ue(a.logger(),i.transport);if(r.subscriptionWorkerUrl)try{const e=new A({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),announceSuccessfulHeartbeats:a.announceSuccessfulHeartbeats,announceFailedHeartbeats:a.announceFailedHeartbeats,workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogLevel:i.subscriptionWorkerLogLevel,tokenManager:u,transport:y,logger:a.logger()});p=t=>e.onPresenceStateChange(t),d=t=>e.onHeartbeatIntervalChange(t),g=t=>e.onTokenChange(t),b=t=>e.onUserIdChange(t),y=e,r.subscriptionWorkerUnsubscribeOfflineClients&&window.addEventListener("pagehide",(t=>{t.persisted||e.terminate()}),{once:!0})}catch(e){a.logger().error("PubNub",(()=>({messageType:"error",message:e})))}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const m=new ce({clientConfiguration:a,tokenManager:u,transport:y});if(super({configuration:a,transport:m,cryptography:h,tokenManager:u,crypto:l}),this.File=o,this.onHeartbeatIntervalChange=d,this.onAuthenticationChange=g,this.onPresenceStateChange=p,this.onUserIdChange=b,y instanceof A){y.emitStatus=this.emitStatus.bind(this);const e=this.disconnect.bind(this);this.disconnect=t=>{y.disconnect(),e()}}(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Us.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Us.CryptoModule=N,Us})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),i=Math.pow(2,32),r=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,i=o+e;s>2,u=0;u>6),i.push(128|63&a)):a<55296?(i.push(224|a>>12),i.push(128|a>>6&63),i.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,i.push(240|a>>18),i.push(128|a>>12&63),i.push(128|a>>6&63),i.push(128|63&a))}return d(3,i.length),h(i);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof r&&(r=function(){return s});var m=function e(){var i,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),i=32768&s,r=31744&s,a=1023&s;if(31744===r)r=261120;else if(0!==r)r+=114688;else if(0!==a)return a*n;return t.setUint32(0,i<<16|r<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)O+=d,S.push(u(d));var w=new Uint8Array(O),k=0;for(i=0;i=0;)y(j,d);else y(j,d);return String.fromCharCode.apply(null,j);case 4:var C;if(d<0)for(C=[];!p();)C.push(e());else for(C=new Array(d),i=0;ie.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,i;if(e instanceof File)i=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const r=e.data;s=e.mimeType,n=e.name,i=new File([r],n,{type:s}),t=i.size}if(void 0===i)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=i,this.name=n}toBuffer(){return r(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return r(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return r(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return r(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return r(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return r(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return r(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),i=new Uint8Array(n);let r=0;function a(){const e=t.charAt(r++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${r}: ${t.charAt(r-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|r;i[e]=o,64!=n&&(i[e+1]=c),64!=r&&(i[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),i=n.byteLength,r=i%3,a=i-r;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==r?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==r&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNServerErrorCategory="PNServerErrorCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory",e.PNSharedWorkerUpdatedCategory="PNSharedWorkerUpdatedCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},i=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},r=s.WordArray=i.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var i=0;i>>2]|=(s[i>>>2]>>>24-i%4*8&255)<<24-(n+i)%4*8;else if(65535>>2]=s[i>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=i.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((i>>>4).toString(16)),s.push((15&i).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new r.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new r.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=i.extend({reset:function(){this._data=new r.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,i=s.sigBytes,a=this.blockSize,o=i/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,i=e.min(4*t,i),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(r[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];i=i.SHA256=n.extend({_doReset:function(){this._hash=new s.init(r.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],i=s[1],r=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&i^n&r^i&r),h=l,l=u,u=c,c=o+g|0,o=r,r=i,i=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+i|0,s[2]=s[2]+r|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,i=8*t.sigBytes;return s[i>>>5]|=128<<24-i%32,s[14+(i+64>>>9<<4)]=e.floor(n/4294967296),s[15+(i+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(i),t.HmacSHA256=n._createHmacHelper(i)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var i=this._oKey=t.clone(),r=this._iKey=t.clone(),a=i.words,o=r.words,c=0;c>>2]>>>24-i%4*8&255)<<16|(t[i+1>>>2]>>>24-(i+1)%4*8&255)<<8|t[i+2>>>2]>>>24-(i+2)%4*8&255,a=0;4>a&&i+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],i=0,r=0;r>>6-r%4*2;n[i>>>2]|=(a|o)<<24-i%4*8,i++}return f.create(n,i)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,i,r,a){return((e=e+(t&s|~t&n)+i+a)<>>32-r)+t}function s(e,t,s,n,i,r,a){return((e=e+(t&n|s&~n)+i+a)<>>32-r)+t}function n(e,t,s,n,i,r,a){return((e=e+(t^s^n)+i+a)<>>32-r)+t}function i(e,t,s,n,i,r,a){return((e=e+(s^(t|~n))+i+a)<>>32-r)+t}for(var r=S,a=(c=r.lib).WordArray,o=c.Hasher,c=r.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,r){for(var a=0;16>a;a++){var o=e[c=r+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[r+0],l=(o=e[r+1],e[r+2]),h=e[r+3],d=e[r+4],p=e[r+5],g=e[r+6],b=e[r+7],y=e[r+8],m=e[r+9],f=e[r+10],v=e[r+11],S=e[r+12],O=e[r+13],w=e[r+14],k=e[r+15],j=t(j=a[0],E=a[1],P=a[2],C=a[3],c,7,u[0]),C=t(C,j,E,P,o,12,u[1]),P=t(P,C,j,E,l,17,u[2]),E=t(E,P,C,j,h,22,u[3]);j=t(j,E,P,C,d,7,u[4]),C=t(C,j,E,P,p,12,u[5]),P=t(P,C,j,E,g,17,u[6]),E=t(E,P,C,j,b,22,u[7]),j=t(j,E,P,C,y,7,u[8]),C=t(C,j,E,P,m,12,u[9]),P=t(P,C,j,E,f,17,u[10]),E=t(E,P,C,j,v,22,u[11]),j=t(j,E,P,C,S,7,u[12]),C=t(C,j,E,P,O,12,u[13]),P=t(P,C,j,E,w,17,u[14]),j=s(j,E=t(E,P,C,j,k,22,u[15]),P,C,o,5,u[16]),C=s(C,j,E,P,g,9,u[17]),P=s(P,C,j,E,v,14,u[18]),E=s(E,P,C,j,c,20,u[19]),j=s(j,E,P,C,p,5,u[20]),C=s(C,j,E,P,f,9,u[21]),P=s(P,C,j,E,k,14,u[22]),E=s(E,P,C,j,d,20,u[23]),j=s(j,E,P,C,m,5,u[24]),C=s(C,j,E,P,w,9,u[25]),P=s(P,C,j,E,h,14,u[26]),E=s(E,P,C,j,y,20,u[27]),j=s(j,E,P,C,O,5,u[28]),C=s(C,j,E,P,l,9,u[29]),P=s(P,C,j,E,b,14,u[30]),j=n(j,E=s(E,P,C,j,S,20,u[31]),P,C,p,4,u[32]),C=n(C,j,E,P,y,11,u[33]),P=n(P,C,j,E,v,16,u[34]),E=n(E,P,C,j,w,23,u[35]),j=n(j,E,P,C,o,4,u[36]),C=n(C,j,E,P,d,11,u[37]),P=n(P,C,j,E,b,16,u[38]),E=n(E,P,C,j,f,23,u[39]),j=n(j,E,P,C,O,4,u[40]),C=n(C,j,E,P,c,11,u[41]),P=n(P,C,j,E,h,16,u[42]),E=n(E,P,C,j,g,23,u[43]),j=n(j,E,P,C,m,4,u[44]),C=n(C,j,E,P,S,11,u[45]),P=n(P,C,j,E,k,16,u[46]),j=i(j,E=n(E,P,C,j,l,23,u[47]),P,C,c,6,u[48]),C=i(C,j,E,P,b,10,u[49]),P=i(P,C,j,E,w,15,u[50]),E=i(E,P,C,j,p,21,u[51]),j=i(j,E,P,C,S,6,u[52]),C=i(C,j,E,P,h,10,u[53]),P=i(P,C,j,E,f,15,u[54]),E=i(E,P,C,j,o,21,u[55]),j=i(j,E,P,C,y,6,u[56]),C=i(C,j,E,P,k,10,u[57]),P=i(P,C,j,E,g,15,u[58]),E=i(E,P,C,j,O,21,u[59]),j=i(j,E,P,C,d,6,u[60]),C=i(C,j,E,P,v,10,u[61]),P=i(P,C,j,E,l,15,u[62]),E=i(E,P,C,j,m,21,u[63]);a[0]=a[0]+j|0,a[1]=a[1]+E|0,a[2]=a[2]+P|0,a[3]=a[3]+C|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,i=8*t.sigBytes;s[i>>>5]|=128<<24-i%32;var r=e.floor(n/4294967296);for(s[15+(i+64>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),s[14+(i+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)i=s[n],s[n]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),r.MD5=o._createHelper(c),r.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,i=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),i=n.create(),r=i.words,a=o.keySize,o=o.iterations;r.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(i)},parse:function(e){var t=(e=i.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var i=e.createEncryptor(s,n);return t=i.finalize(t),i=i.cfg,l.create({ciphertext:t,key:s,iv:i.iv,algorithm:e,mode:i.mode,padding:i.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,i){return i||(i=s.random(8)),e=r.create({keySize:t+n}).compute(e,i),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:i})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],i=[],r=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,i[m]=b;var f=p[b],v=p[f],O=p[v],w=257*p[m]^16843008*m;r[b]=w<<24|w>>>8,a[b]=w<<16|w>>>16,o[b]=w<<8|w>>>24,c[b]=w,w=16843009*O^65537*v^257*f^16843008*b,u[m]=w<<24|w>>>8,l[m]=w<<16|w>>>16,h[m]=w<<8|w>>>24,d[m]=w,b?(b=f^p[p[p[O^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),i=this._keySchedule=[],r=0;r>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[r/t|0]<<24),i[r]=i[r-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=r?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,r,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,i),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,i,r,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^i[l>>>16&255]^r[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^i[h>>>16&255]^r[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^i[d>>>16&255]^r[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^i[u>>>16&255]^r[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var O,w=t(S);class k{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:k.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return r(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return k.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return r(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(k.BLOCK_SIZE))}getKey(){return r(this,void 0,void 0,(function*(){const e=k.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Encrypt with parameters:"}))),s=this.parseOptions(s);const i=this.getMode(s),r=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,r,{iv:t,mode:i}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,r,{iv:a,mode:i}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e,cipherKey:n},null!=s?s:{}),details:"Decrypt with parameters:"}))),s=this.parseOptions(s);const i=this.getMode(s),r=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=j(t.slice(0,16)),n=j(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},r,{iv:s,mode:i}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},r,{iv:t,mode:i}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,i;if(!e)return this.defaultOptions;const r={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(i=e.mode)&&void 0!==i?i:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(r.keyEncoding.toLowerCase())&&(r.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(r.keyLength)&&(r.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(r.mode.toLowerCase())&&(r.mode=this.defaultOptions.mode),r}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class P{encrypt(e,t){return r(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return r(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return r(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=P.encoder.encode(t).buffer,i=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),r=this.concatArrayBuffer(s.buffer,i);return P.decoder.decode(r)}))}encryptFile(e,t,s){return r(this,void 0,void 0,(function*(){var n,i;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const r=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(r,a);return s.create({name:t.name,mimeType:null!==(i=t.mimeType)&&void 0!==i?i:"application/octet-stream",data:o})}))}decrypt(e,t){return r(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return r(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(P.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(P.IV_LENGTH))}))}decryptString(e,t){return r(this,void 0,void 0,(function*(){const s=P.encoder.encode(t).buffer,n=s.slice(0,16),i=s.slice(16),r=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,i);return P.decoder.decode(r)}))}decryptFile(e,t,s){return r(this,void 0,void 0,(function*(){const n=yield this.getKey(e),i=yield t.toArrayBuffer(),r=yield this.decryptArrayBuffer(n,i);return s.create({name:t.name,mimeType:t.mimeType,data:r})}))}getKey(e){return r(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",P.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=P.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}P.IV_LENGTH=16,P.encoder=new TextEncoder,P.decoder=new TextDecoder;class E{constructor(e){this.config=e,this.cryptor=new C(Object.assign({},e)),this.fileCryptor=new P}set logger(e){this.cryptor.logger=e}encrypt(e){const t="string"==typeof e?e:E.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return r(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return r(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`AesCbcCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}E.encoder=new TextEncoder,E.decoder=new TextDecoder;class N extends a{set logger(e){if(this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER)this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===N.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new N({default:new E(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new k({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new N({default:new k({cipherKey:e.cipherKey}),cryptors:[new E(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===N.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(N.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return r(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===T.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=T.tryParse(t),n=this.getCryptor(s),i=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:i})}decryptFile(e,t){return r(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=T.tryParse(s),i=this.getCryptor(n);if((null==i?void 0:i.identifier)===T.LEGACY_IDENTIFIER)return i.decryptFile(e,t);const r=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:r})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof _)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=T.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return r(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}N.LEGACY_IDENTIFIER="";class T{static from(e,t){if(e!==T.LEGACY_IDENTIFIER)return new _(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,i=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==T.SENTINEL))return N.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(i=t[4],i>T.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let r=5+T.IDENTIFIER_LENGTH;if(!(t.byteLength>=r))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,r);let a=null;if(!(t.byteLength>=r+1))throw new Error("Decryption error: invalid metadata length");return a=t[r],r+=1,255===a&&t.byteLength>=r+2&&(a=new Uint16Array(t.slice(r,r+2)).reduce(((e,t)=>(e<<8)+t),0)),new _(this.decoder.decode(n),a)}}T.SENTINEL="PNED",T.LEGACY_IDENTIFIER="",T.IDENTIFIER_LENGTH=4,T.VERSION=1,T.MAX_VERSION=1,T.decoder=new TextDecoder;class _{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return T.VERSION}get length(){return T.SENTINEL.length+1+T.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(T.SENTINEL)),e+=T.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=T.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}_.IDENTIFIER_LENGTH=4,_.SENTINEL="PNED";class I extends Error{static create(e,t){return I.isErrorObject(e)?I.createFromError(e):I.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new I(s,t,0);if(e instanceof I)return e;if(I.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new I(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,i="Unknown error",{status:r}=e;if(null!=t||(t=e.body),402===r?i="Not available for used key set. Contact support@pubnub.com":404===r?i="Resource not found":400===r?(n=h.PNBadRequestCategory,i="Bad request"):403===r?(n=h.PNAccessDeniedCategory,i="Access denied"):r>=500&&(n=h.PNServerErrorCategory,i="Internal server error"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,i="Malformed response (network issues)",r=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);if("object"==typeof e)if(Array.isArray(e))"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]);else{if("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e)s=e,r=e.status;else if("errors"in e&&Array.isArray(e.errors)&&e.errors.length>0){s=e;i=e.errors.map((e=>{const t=[];return e.errorCode&&t.push(e.errorCode),e.message&&t.push(e.message),t.join(": ")})).join("; ")}else s=e;"error"in e&&e.error instanceof Error&&(s=e.error)}}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);i=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new I(i,n,r,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,I.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=i(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toFormattedMessage(e){return this.errorData&&"object"==typeof this.errorData&&!("name"in this.errorData&&"message"in this.errorData&&"stack"in this.errorData)&&"errors"in this.errorData&&Array.isArray(this.errorData.errors)?`${e}: ${this.message}`:"REST API request processing error, check status for details"}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}!function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNCreateEntityOperation="PNCreateEntityOperation",e.PNGetEntityOperation="PNGetEntityOperation",e.PNGetAllEntitiesOperation="PNGetAllEntitiesOperation",e.PNUpdateEntityOperation="PNUpdateEntityOperation",e.PNPatchEntityOperation="PNPatchEntityOperation",e.PNRemoveEntityOperation="PNRemoveEntityOperation",e.PNCreateRelationshipOperation="PNCreateRelationshipOperation",e.PNGetRelationshipOperation="PNGetRelationshipOperation",e.PNGetAllRelationshipsOperation="PNGetAllRelationshipsOperation",e.PNUpdateRelationshipOperation="PNUpdateRelationshipOperation",e.PNPatchRelationshipOperation="PNPatchRelationshipOperation",e.PNRemoveRelationshipOperation="PNRemoveRelationshipOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(O||(O={}));var M=O;class A{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}set emitStatus(e){this._emitStatus=e}onUserIdChange(e){this.configuration.userId=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onPresenceStateChange(e){this.scheduleEventPost({type:"client-presence-state-update",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel,state:e})}onHeartbeatIntervalChange(e){this.configuration.heartbeatInterval=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onTokenChange(e){const t={type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel};this.parsedAccessToken(e).then((s=>{t.preProcessedToken=s,t.accessToken=e})).then((()=>this.scheduleEventPost(t)))}disconnect(){this.scheduleEventPost({type:"client-disconnect",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e,workerLogLevel:this.configuration.workerLogLevel};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier,workerLogLevel:this.configuration.workerLogLevel};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.preProcessedToken=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogLevel:this.configuration.workerLogLevel},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e),this.shouldAnnounceNewerSharedWorkerVersionAvailability()&&localStorage.setItem("PNSubscriptionSharedWorkerVersion",this.configuration.sdkVersion),window.addEventListener("storage",(e=>{"PNSubscriptionSharedWorkerVersion"===e.key&&e.newValue&&this._emitStatus&&this.isNewerSharedWorkerVersion(e.newValue)&&this._emitStatus({error:!1,category:h.PNSharedWorkerUpdatedCategory})}))}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",(()=>"string"==typeof t.message||"number"==typeof t.message||"boolean"==typeof t.message?{messageType:"text",message:t.message}:t.message));else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t,workerLogLevel:this.configuration.workerLogLevel})}else if("request-process-success"===t.type||"request-process-error"===t.type)if(this.callbacks.has(t.identifier)){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);this.callbacks.delete(t.identifier),"request-process-success"===t.type?e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body}):s(this.errorFromRequestSendingError(t))}else this._emitStatus&&t.url.indexOf("/v2/presence")>=0&&t.url.indexOf("/heartbeat")>=0&&("request-process-success"===t.type&&this.configuration.announceSuccessfulHeartbeats?this._emitStatus({statusCode:t.response.status,error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}):"request-process-error"===t.type&&this.configuration.announceFailedHeartbeats&&this._emitStatus(this.errorFromRequestSendingError(t).toStatus(M.PNHeartbeatOperation)))}parsedAccessTokenForRequest(e){return r(this,void 0,void 0,(function*(){var t;return this.parsedAccessToken(e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0)}))}parsedAccessToken(e){return r(this,void 0,void 0,(function*(){if(e)return this.accessTokensMap[e]?this.accessTokensMap[e]:this.stringifyAccessToken(e).then((([t,s])=>{if(t&&s)return(this.accessTokensMap={[e]:{token:s,expiration:t.timestamp+60*t.ttl}})[e]}))}))}stringifyAccessToken(e){return r(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}errorFromRequestSendingError(e){let t=h.PNUnknownCategory,s="Unknown error";if(e.error)"NETWORK_ISSUE"===e.error.type?t=h.PNNetworkIssuesCategory:"TIMEOUT"===e.error.type?t=h.PNTimeoutCategory:"ABORTED"===e.error.type&&(t=h.PNCancelledCategory),s=`${e.error.message} (${e.identifier})`;else if(e.response){const{url:t,response:s}=e;return I.create({url:t,headers:s.headers,body:s.body,status:s.status},s.body)}return new I(s,t,0,new Error(s))}shouldAnnounceNewerSharedWorkerVersionAvailability(){const e=localStorage.getItem("PNSubscriptionSharedWorkerVersion");return!e||!this.isNewerSharedWorkerVersion(e)}isNewerSharedWorkerVersion(e){const[t,s,n]=this.configuration.sdkVersion.split(".").map(Number),[i,r,a]=e.split(".").map(Number);return i>t||r>s||a>n}}function R(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const i={};return Object.keys(e).forEach((r=>{const a=(e=>"string"==typeof e||e instanceof String)(r);let o=r;const c=e[r];if(t<2)if(a&&r.indexOf(",")>=0){o=r.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(r)||a&&!isNaN(Number(r)))&&(o=String.fromCharCode(n(r)?r:parseInt(r,10)));i[o]=s(c)?R(c,t+1):c})),i}const U=e=>{var t,s,n,i,r,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,i,r,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(i=m.fileRequestTimeout)&&void 0!==i||(m.fileRequestTimeout=300),null!==(r=m.restore)&&void 0!==r||(m.restore=!0),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!0),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,O=5,w=!1,k=100,j=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(w=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(j=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(O=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:w,maximumCacheSize:k,useRequestId:j,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:O})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(i=e.subscriptionWorkerLogVerbosity)&&void 0!==i&&i,transport:null!==(r=e.transport)&&void 0!==r?r:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var $;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}($||($={}));const D=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),F=(e,t)=>{const s=e.map((e=>D(e)));return s.length?s.join(","):null!=t?t:""},x=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},q=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),G=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${D(e)}`)).join("&"):`${t}=${D(s)}`})).join("&"),L=(e,t)=>{if("0"===t||"0"===e)return;const s=H(`${Date.now()}0000`,t,!1);return H(e,s,!0)},K=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=H(e,t,!1);return H(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},H=(e,t,s)=>{t.startsWith("-")&&(t=t.replace("-",""),s=!1),t=t.padStart(17,"0");const n=e.slice(0,10),i=e.slice(10,17),r=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(i);return o+=Number(r)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0?o>0?(o-=1,c+=1e7):o<0&&(c*=-1):o<0&&c>0&&(o+=1,c=1e7-c),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},B=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,i=t.length;for(;i-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};class W{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}toString(){return"ConsoleLogger {}"}log(e){const t=$[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==$.Trace||t?void 0:this.formattedHeaders(e),n=e.message,i=n.queryParameters&&Object.keys(n.queryParameters).length>0?G(n.queryParameters):void 0,r=`${n.origin}${n.path}${i?`?${i}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${r}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===$.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,i=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${i.url}\n ${this.paddedString("Status",n)}: ${i.status}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,i=!1)=>{const r=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=i?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const i=Array.isArray(e),a=r?"...":t(e,n+1,!i);o.push(`${s}-${i&&!r?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);i=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=i?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,i=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=r?"...":s?"[]":i?"{}":t(h,n+1,a);o.push(`${u}${d}:${r||a||s||i?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);i=!1}}else o.push(`${i?"":a}${s.toString()}`),i=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const i=e.message.headers,r=null!==(t=i["content-type"])&&void 0!==t?t:i["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!r||-1===r.indexOf("javascript")&&-1===r.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${W.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(W.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}var V;W.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(V||(V={}));class z{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return J(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return J(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry")}}}}const J=(e,t,s,n,i,r)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!X(e,r)&&(!(n>i)&&(!t||(429===t.status||t.status>=500)))),X=(e,t)=>!!(t&&t.length>0)&&t.includes(Q(e)),Q=e=>{let t=V.Unknown;return e.path.startsWith("/v2/subscribe")?t=V.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=V.MessageSend:e.path.startsWith("/v2/presence")?t=V.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=V.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=V.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=V.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=V.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=V.Files),t};class Y{constructor(e,t,s){this.previousEntryTimestamp=0,this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log($.Trace,e,t)}debug(e,t){this.log($.Debug,e,t)}info(e,t){this.log($.Info,e,t)}warn(e,t){this.log($.Warn,e,t)}error(e,t){this.log($.Error,e,t)}log(e,t,s){if(ee[i](r)))}}var Z={exports:{}}; +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function i(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=i,n.VERSION=t,e.uuid=n,e.isUUID=i}(t),null!==e&&(e.exports=t.uuid)}(Z,Z.exports);var ee=t(Z.exports),te={createUUID:()=>ee.uuid?ee.uuid():ee()};const se=(e,t)=>{var s,n,i,r;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=z.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[V.MessageSend,V.Presence,V.Files,V.MessageStorage,V.ChannelGroups,V.DevicePushNotifications,V.AppContext,V.MessageReactions]}));const a=`pn-${te.createUUID()}`;e.logVerbosity?e.logLevel=$.Debug:void 0===e.logLevel&&(e.logLevel=$.None);const o=new Y(ie(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new W]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate(),null!==(i=e.useRandomIVs)&&void 0!==i||(e.useRandomIVs=true),e.useRandomIVs&&o.warn("Configuration","'useRandomIVs' is deprecated. Use 'cryptoModule' instead."),e.origin=ne(null!==(r=e.ssl)&&void 0!==r&&r,e.origin);const c=e.cryptoModule;c&&delete e.cryptoModule;const u=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,isSharedWorkerEnabled:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"11.0.0"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),u.setCipherKey(e.cipherKey)):c&&(u._cryptoModule=c),u},ne=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},ie=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class re{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),i=t.pat.uuid?Object.keys(t.pat.uuid):[],r=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=i.length>0,d=r.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var ae;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.PUT="PUT",e.DELETE="DELETE",e.LOCAL="LOCAL"}(ae||(ae={}));class oe{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?ae.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===ae.POST||t===ae.PATCH||t===ae.PUT){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=oe.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${D(e)}`)).join("&"):`${t}=${D(s)}`})).join("&")}}oe.textDecoder=new TextDecoder("utf-8");class ce{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new oe(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,i,r=!1,a=0;const o={abort:e=>{r=!0,n&&clearTimeout(n),i&&i.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(r)return;const[l,d]=s.makeSendable(this.request(e));i=d;const p=(s,i)=>{const r=!i||i.category!==h.PNCancelledCategory,l=(!s||s.status>=400)&&404!==(null==i?void 0:i.statusCode);let d=-1;r&&l&&t.shouldRetry(e,s,null==i?void 0:i.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):i&&c(i)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),i?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,i=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;i&&(e.queryParameters.auth=i)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class ue{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"!==t||window&&window.fetch||(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(ue.originalFetch=ue.getOriginalFetch(),this.isFetchMonkeyPatched()&&e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:i}=e[0],r={};i.forEach(((e,t)=>r[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:r,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw I.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:I.create(n).message,failed:!0}))),I.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return r(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return r(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,i)=>{s=setTimeout((()=>{clearTimeout(s),i(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),i=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([ue.originalFetch(i,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return r(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var i;const r=new XMLHttpRequest;r.open(e.method,e.url,!0);let a=!1;r.responseType="arraybuffer",r.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{r.readyState!=XMLHttpRequest.DONE&&r.readyState!=XMLHttpRequest.UNSENT&&(a=!0,r.abort())},Object.entries(null!==(i=e.headers)&&void 0!==i?i:{}).forEach((([e,t])=>r.setRequestHeader(e,t))),r.onabort=()=>{n(new Error("Aborted"))},r.ontimeout=()=>{n(new Error("Request timeout"))},r.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,r);n(new Error(I.create(t).message))}},r.onload=()=>{const e=new Headers;r.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(r.response,{status:r.status,headers:e,statusText:r.statusText}))},r.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return r(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?ue.encoder.encode(e.body):e.body,n=s.byteLength,i=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(i.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${G(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}ue.encoder=new TextEncoder,ue.decoder=new TextDecoder;class le{constructor(e){this.params=e,this.requestIdentifier=te.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return r(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,i,r;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:ae.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(r=null===(i=this.params)||void 0===i?void 0:i.compressible)&&void 0!==r&&r,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===ae.POST||a.method===ae.PATCH||a.method===ae.PUT){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=le.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw I.create(e);return n}}le.decoder=new TextDecoder;var he;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(he||(he={}));class de extends le{constructor(e){var t,s,n,i,r,a;super({cancellable:!0}),this.parameters=e,null!==(t=(i=this.parameters).withPresence)&&void 0!==t||(i.withPresence=false),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return M.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){let t,s;try{s=le.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;null!=t||(t=e.c.endsWith("-pnpres")?he.Presence:he.Message);const s=B(e.d);return t!=he.Signal&&"string"==typeof e.d?t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:{type:he.Files,data:this.fileFromEnvelope(e),pn_mfp:s}:t==he.Message?{type:he.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:t===he.Presence?{type:he.Presence,data:this.presenceEventFromEnvelope(e),pn_mfp:s}:t==he.Signal?{type:he.Signal,data:this.signalFromEnvelope(e),pn_mfp:s}:t===he.AppContext?{type:he.AppContext,data:this.appContextFromEnvelope(e),pn_mfp:s}:t===he.MessageAction?{type:he.MessageAction,data:this.messageActionFromEnvelope(e),pn_mfp:s}:{type:he.Files,data:this.fileFromEnvelope(e),pn_mfp:s}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,i]=this.subscriptionChannelFromEnvelope(e),r=n.replace("-pnpres",""),a=null!==i?r:null,o=null!==i?i:r;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:r,subscription:i,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,i]=this.decryptedData(e.d),r={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(r.userMetadata=e.u),e.cmt&&(r.customMessageType=e.cmt),i&&(r.error=i),r}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,i]=this.decryptedData(e.d);let r=i;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=r||(r="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=r||(r="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),r&&(a.error=r),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(pe.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class pe extends de{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${F(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:i,region:r,onDemand:a}=this.parameters,o={};return a&&(o["on-demand"]=1),e&&e.length>0&&(o["channel-group"]=e.sort().join(",")),t&&t.length>0&&(o["filter-expr"]=t),s&&(o.heartbeat=s),n&&Object.keys(n).length>0&&(o.state=JSON.stringify(n)),void 0!==i&&"string"==typeof i?i.length>0&&"0"!==i&&(o.tt=i):void 0!==i&&i>0&&(o.tt=i),r&&(o.tr=r),o}}class ge{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===he.Message)this.announce("message",e.data);else if(e.type===he.Signal)this.announce("signal",e.data);else if(e.type===he.Presence)this.announce("presence",e.data);else if(e.type===he.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,r=i(t,["message","channel"]),{event:a,type:o}=s,c=i(s,["event","type"]),u=Object.assign(Object.assign({},r),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,r=i(t,["message","channel"]),{event:a,type:o}=s,c=i(s,["event","type"]),u=Object.assign(Object.assign({},r),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,r=i(t,["message","channel"]),{event:a,data:o}=s,c=i(s,["event","data"]),{uuid:u,channel:l}=o,h=i(o,["uuid","channel"]),d=Object.assign(Object.assign({},r),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===he.MessageAction?this.announce("messageAction",e.data):e.type===he.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class be{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ye{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},i&&(this.presenceChannels[e]={}),(r||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},i&&(this.presenceChannelGroups[e]={}),(r||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const r=new Set,a=new Set;if(null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],r.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],r.add(e))})),0===a.size&&0===r.size)return;const o=this.lastTimetoken,c=this.currentTimetoken;0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0),!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(r),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,r=i(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},r),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:c,lastTimetoken:o}))})))}unsubscribeAll(e=!1){this.disconnectedWhileHandledEvent=!0,this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.disconnectedWhileHandledEvent=!1,this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),{onDemand:!this.subscriptionStatusAnnounced||e}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=K(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:i}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>({type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:e.pn_mfp})}))),details:"Received events:"}))),s.forEach((t=>{if(i&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.disconnectedWhileHandledEvent?this.disconnectedWhileHandledEvent=!1:this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class fe{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class ve extends fe{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,i={topic:t,environment:s};return n.length&&(i.excluded_devices=n),i}}class Se extends fe{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get androidNotification(){var e;return null===(e=this.payload.android)||void 0===e?void 0:e.notification}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this.androidNotification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this.androidNotification.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.androidNotification.notification_count=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.androidNotification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.androidNotification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.androidNotification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={},this.payload.android={notification:{}}}toObject(){var e,t;const s={},n=Object.assign({},this.payload.notification),r=Object.assign({},this.payload.android),a=i(Object.assign({},null!==(e=r.notification)&&void 0!==e?e:{}),["title","body"]);if(this._isSilent){const e={};this._title&&(e.title=this._title),this._body&&(e.body=this._body);for(const[t,s]of Object.entries(a))null!=s&&(e[t]=String(s));this.payload.data&&Object.assign(e,this.payload.data),Object.keys(e).length&&(s.data=e),delete r.notification,Object.keys(r).length&&(s.android=r)}else if(Object.keys(n).length&&(s.notification=n),this.payload.data&&Object.keys(this.payload.data).length&&(s.data=Object.assign({},this.payload.data)),Object.keys(a).length){const e=i(r,["notification"]);s.android=Object.assign(Object.assign({},e),{notification:a})}else{const e=i(r,["notification"]);Object.keys(e).length&&(s.android=e)}const o=i(this.payload,["notification","android","data","pn_exceptions"]);return Object.assign(s,o),(null===(t=this.payload.pn_exceptions)||void 0===t?void 0:t.length)&&(s.pn_exceptions=this.payload.pn_exceptions),Object.keys(s).length?s:null}}class Oe{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ve(this._payload.apns,e,t),this.fcm=new Se(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_fcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class we{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class ke{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class je extends we{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new ke(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,i]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const r=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:r,fromContext:a,toState:s,toContext:n,event:e});for(const e of i)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class Ce{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Pe(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ee(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Ne(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Te extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class _e extends we{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Te}abort(){this._aborted=!0,this.notify(new Te)}}class Ie{constructor(e,t){this.payload=e,this.dependencies=t}}class Me extends Ie{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new _e}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const Ae=e=>(t,s)=>new Me(t,s,e),Re=Ne("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),Ue=Ee("LEAVE",((e,t)=>({channels:e,groups:t}))),$e=Ee("EMIT_STATUS",(e=>e)),De=Ne("WAIT",(()=>({}))),Fe=Pe("RECONNECT",(()=>({}))),xe=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),qe=Pe("JOINED",((e,t)=>({channels:e,groups:t}))),Ge=Pe("LEFT",((e,t)=>({channels:e,groups:t}))),Le=Pe("LEFT_ALL",((e=!1)=>({isOffline:e}))),Ke=Pe("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),He=Pe("HEARTBEAT_FAILURE",(e=>e)),Be=Pe("TIMES_UP",(()=>({})));class We extends Ce{constructor(e,t){super(t,t.config.logger()),this.on(Re.type,Ae(((t,s,n)=>r(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:i,config:r}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},r.maintainPresenceState&&{state:i}),{heartbeat:r.presenceTimeout}));e.transition(Ke(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(He(t))}}}))))),this.on(Ue.type,Ae(((e,t,s)=>r(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(De.type,Ae(((t,s,n)=>r(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Be())}))))),this.on($e.type,Ae(((e,t,s)=>r(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:M.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const Ve=new ke("HEARTBEAT_STOPPED");Ve.on(qe.type,((e,t)=>Ve.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ve.on(Ge.type,((e,t)=>Ve.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),Ve.on(Fe.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Ve.on(Le.type,((e,t)=>Qe.with(void 0)));const ze=new ke("HEARTBEAT_COOLDOWN");ze.onEnter((()=>De())),ze.onExit((()=>De.cancel)),ze.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),ze.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),ze.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Ue(t.payload.channels,t.payload.groups)]))),ze.on(xe.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]]))),ze.on(Le.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]])));const Je=new ke("HEARTBEAT_FAILED");Je.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Ue(t.payload.channels,t.payload.groups)]))),Je.on(Fe.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups}))),Je.on(xe.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]]))),Je.on(Le.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]])));const Xe=new ke("HEARTBEATING");Xe.onEnter((e=>Re(e.channels,e.groups))),Xe.onExit((()=>Re.cancel)),Xe.on(Ke.type,((e,t)=>ze.with({channels:e.channels,groups:e.groups},[$e(Object.assign({},t.payload))]))),Xe.on(qe.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(Ge.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Ue(t.payload.channels,t.payload.groups)]))),Xe.on(He.type,((e,t)=>Je.with(Object.assign({},e),[...t.payload.status?[$e(Object.assign({},t.payload.status))]:[]]))),Xe.on(xe.type,((e,t)=>Ve.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]]))),Xe.on(Le.type,((e,t)=>Qe.with(void 0,[...t.payload.isOffline?[]:[Ue(e.channels,e.groups)]])));const Qe=new ke("HEARTBEAT_INACTIVE");Qe.on(qe.type,((e,t)=>Xe.with({channels:t.payload.channels,groups:t.payload.groups})));class Ye{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new je(e.config.logger()),this.dispatcher=new We(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Qe,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(qe(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){e&&(this.channels=this.channels.filter((t=>!e.includes(t)))),t&&(this.groups=this.groups.filter((e=>!t.includes(e)))),this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(Ge(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.dependencies.presenceState&&(this.channels.forEach((e=>delete this.dependencies.presenceState[e])),this.groups.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=[],this.groups=[],this.engine.transition(Le(e))}reconnect(){this.engine.transition(Fe())}disconnect(e=!1){this.engine.transition(xe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const Ze=Ne("HANDSHAKE",((e,t,s)=>({channels:e,groups:t,onDemand:s}))),et=Ne("RECEIVE_MESSAGES",((e,t,s,n)=>({channels:e,groups:t,cursor:s,onDemand:n}))),tt=Ee("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),st=Ee("EMIT_STATUS",(e=>e)),nt=Pe("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),it=Pe("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),rt=Pe("HANDSHAKE_SUCCESS",(e=>e)),at=Pe("HANDSHAKE_FAILURE",(e=>e)),ot=Pe("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),ct=Pe("RECEIVE_FAILURE",(e=>e)),ut=Pe("DISCONNECT",((e=!1)=>({isOffline:e}))),lt=Pe("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),ht=Pe("UNSUBSCRIBE_ALL",(()=>({}))),dt=new ke("UNSUBSCRIBED");dt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,onDemand:!0}))),dt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region},onDemand:!0})));const pt=new ke("HANDSHAKE_STOPPED");pt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),pt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),pt.on(it.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):pt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),pt.on(ht.type,(e=>dt.with()));const gt=new ke("HANDSHAKE_FAILED");gt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),gt.on(lt.type,((e,{payload:t})=>bt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),gt.on(it.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0},onDemand:!0})})),gt.on(ht.type,(e=>dt.with()));const bt=new ke("HANDSHAKING");bt.onEnter((e=>{var t;return Ze(e.channels,e.groups,null!==(t=e.onDemand)&&void 0!==t&&t)})),bt.onExit((()=>Ze.cancel)),bt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),bt.on(rt.type,((e,{payload:t})=>{var s,n,i,r,a;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:K(t.timetoken,null===(i=e.cursor)||void 0===i?void 0:i.timetoken)},[st({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),operation:M.PNSubscribeOperation,currentTimetoken:(null===(r=e.cursor)||void 0===r?void 0:r.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),bt.on(at.type,((e,t)=>{var s;return gt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),bt.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation);return gt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return pt.with(Object.assign({},e))})),bt.on(it.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0},onDemand:!0})})),bt.on(ht.type,(e=>dt.with()));const yt=new ke("RECEIVE_STOPPED");yt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),yt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):yt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),yt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),yt.on(ht.type,(()=>dt.with(void 0)));const mt=new ke("RECEIVE_FAILED");mt.on(lt.type,((e,{payload:t})=>{var s;return bt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),mt.on(nt.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),mt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},onDemand:!0}))),mt.on(ht.type,(e=>dt.with(void 0)));const ft=new ke("RECEIVING");ft.onEnter((e=>{var t;return et(e.channels,e.groups,e.cursor,null!==(t=e.onDemand)&&void 0!==t&&t)})),ft.onExit((()=>et.cancel)),ft.on(ot.type,((e,{payload:t})=>ft.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:K(t.cursor.timetoken)},[tt(e.cursor,t.events)]))),ft.on(nt.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation).status)||void 0===s?void 0:s.category),dt.with(void 0,[st(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory,operation:M.PNUnsubscribeOperation},e?{error:e}:{}))])}return ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken,onDemand:!0},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),ft.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?dt.with(void 0,[st({category:h.PNDisconnectedCategory})]):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:K(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken),onDemand:!0},[st({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),ft.on(ct.type,((e,{payload:t})=>{var s;return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),ft.on(ut.type,((e,t)=>{var s;if(t.payload.isOffline){const t=I.create(new Error("Network connection error")).toPubNubError(M.PNSubscribeOperation);return mt.with(Object.assign(Object.assign({},e),{reason:t}),[st({category:h.PNDisconnectedUnexpectedlyCategory,operation:M.PNSubscribeOperation,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return yt.with(Object.assign({},e),[st({category:h.PNDisconnectedCategory,operation:M.PNSubscribeOperation})])})),ft.on(ht.type,(e=>dt.with(void 0,[st({category:h.PNDisconnectedCategory,operation:M.PNUnsubscribeOperation})])));class vt extends Ce{constructor(e,t){super(t,t.config.logger()),this.on(Ze.type,Ae(((t,s,n)=>r(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:i,config:r}){s.throwIfAborted();try{const a=yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:r.filterExpression},r.maintainPresenceState&&{state:i}),{onDemand:t.onDemand}));return e.transition(rt(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(at(t))}}}))))),this.on(et.type,Ae(((t,s,n)=>r(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:i}){s.throwIfAborted();try{const r=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:i.filterExpression,onDemand:t.onDemand});e.transition(ot(r.cursor,r.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(ct(t))}}}))))),this.on(tt.type,Ae(((e,t,s)=>r(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(st.type,Ae(((e,t,s)=>r(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class St{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new je(e.config.logger()),this.dispatcher=new vt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(dt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===ft.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return L(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){var i;const r=null==e?void 0:e.some((e=>!this.channels.includes(e))),a=null==t?void 0:t.some((e=>!this.groups.includes(e))),o=r||a;if(this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s)this.engine.transition(it(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s));else if(o)this.engine.transition(nt(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]]))));else{this.dependencies.config.logger().debug("EventEngine","Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.");const e=this.engine.currentState,t=this.engine.currentContext;let s="0";if((null==e?void 0:e.label)===ft.label&&t){s=null===(i=t.cursor)||void 0===i?void 0:i.timetoken}this.dependencies.emitStatus({category:h.PNSubscriptionChangedCategory,affectedChannels:Array.from(new Set(this.channels)),affectedChannelGroups:Array.from(new Set(this.groups)),currentTimetoken:s})}this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=x(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=x(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const i=q(this.channels,e),r=q(this.groups,t);this.dependencies.presenceState&&(null==i||i.forEach((e=>delete this.dependencies.presenceState[e])),null==r||r.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(nt(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:i.slice(0),groups:r.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannelGroups(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(nt(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(lt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ut(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class Ot extends le{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?ae.POST:ae.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return M.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return r(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${D(t)}/0${this.parameters.sendByPost?"":`/${D(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:i}=this.parameters,r={};return e&&(r.custom_message_type=e),void 0!==n&&(r.store=n?"1":"0"),void 0!==i&&(r.ttl=i),void 0===s||s||(r.norep="true"),t&&"object"==typeof t&&(r.meta=JSON.stringify(t)),r}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class wt extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return r(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,i=JSON.stringify(n);return`/signal/${e}/${t}/0/${D(s)}/0/${D(i)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class kt extends de{operation(){return M.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${F(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n,onDemand:i}=this.parameters,r={ee:""};return i&&(r["on-demand"]=1),e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(r.tt=s):s&&s>0&&(r.tt=s),n&&(r.tr=n),r}}class jt extends de{operation(){return M.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${F(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s,onDemand:n}=this.parameters,i={ee:""};return n&&(i["on-demand"]=1),e&&e.length>0&&(i["channel-group"]=e.sort().join(",")),t&&t.length>0&&(i["filter-expr"]=t),s&&Object.keys(s).length>0&&(i.state=JSON.stringify(s)),i}}var Ct;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Ct||(Ct={}));class Pt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Pt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Pt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Et{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=te.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Nt{constructor(e,t="Subscription"){this.subscriptionType=t,this.id=te.createUUID(),this.eventDispatcher=new ge,this._state=e}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Tt extends Et{constructor(e){const t=new Pt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class _t extends Nt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Tt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t,"SubscriptionSet"),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new _t({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>e?{messageType:"object",message:{subscription:this,subscriptions:e},details:"Unregister subscriptions of subscription set from real-time events:"}:{messageType:"text",message:`Unregister subscription from real-time events: ${this}`})),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class It extends Et{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),i=new Pt({[e.entity.subscriptionType==Ct.Channel?"channels":"channelGroups"]:n});super(e.client,i,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Mt extends Nt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new It(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s,n;if(this.state.isSubscribed&&this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)){if(this.parentSetsCount>0){const e=B(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Event (${e}) already handled by ${this.id}. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(n=t.data.subscription)&&void 0!==n?n:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Pt({}):this.state.subscriptionInput}cloneEmpty(){return new Mt({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new _t({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class At extends le{constructor(e){var t,s,n,i;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[])}operation(){return M.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,i={channels:{}};return 1===s.length&&0===n.length?i.channels[s[0]]=t.payload:i.channels=t.payload,i}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=s?s:[],",")}/uuid/${D(null!=t?t:"")}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Rt extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?void 0===t?"Missing State":0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=s?s:[],",")}/uuid/${D(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class Ut extends le{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return M.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${F(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),void 0!==t&&(n.state=JSON.stringify(t)),n}}class $t extends le{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return M.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${F(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class Dt extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${D(t)}`}}class Ft extends le{constructor(e){var t,s,n,i,r,a,o,c;super(),this.parameters=e,null!==(t=(r=this.parameters).queryParameters)&&void 0!==t||(r.queryParameters={}),null!==(s=(a=this.parameters).includeUUIDs)&&void 0!==s||(a.includeUUIDs=true),null!==(n=(o=this.parameters).includeState)&&void 0!==n||(o.includeState=false),null!==(i=(c=this.parameters).limit)&&void 0!==i||(c.limit=1e3)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?M.PNGlobalHereNowOperation:M.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),i="occupancy"in n?1:n.payload.total_channels,r="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};const c=this.parameters.limit;let u=!1;if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:r}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy},u||t.occupancy!==c||(u=!0)})),{totalChannels:i,totalOccupancy:r,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${F(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,limit:n,offset:i,queryParameters:r}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},this.operation()===M.PNHereNowOperation?{limit:n}:{}),this.operation()===M.PNHereNowOperation&&null!=i&&i?{offset:i}:{}),t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),r)}}class xt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${D(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class qt extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${F(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class Gt extends le{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return M.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],i=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:i}:{messages:[],startTimeToken:n,endTimeToken:i}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${D(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:i,includeMeta:r}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),i?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),r?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,i;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(Gt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,i=`Error while decrypting message content: ${t.message}`}return{payload:n,error:i}}}var Lt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Lt||(Lt={}));class Kt extends le{constructor(e){var t,s,n,i,r;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(i=e.includeMessageType)&&void 0!==i||(e.includeMessageType=true),null!==(r=e.logVerbosity)&&void 0!==r||(e.logVerbosity=false)}operation(){return M.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},i={};return Object.keys(n).forEach((e=>{i[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Lt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:i,more:s.more}:{channels:i}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${F(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:i,includeMeta:r,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==r&&r?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),i?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let i,r;try{const e=s.decrypt(t.message);i=e instanceof ArrayBuffer?JSON.parse(Kt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),i=t.message,r=`Error while decrypting message content: ${e.message}`}if(!r&&i&&t.message_type==Lt.Files&&"object"==typeof i&&this.isFileMessage(i)){const t=i;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:r}}return{payload:i,error:r}}isFileMessage(e){return void 0!==e.file}}class Ht extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${D(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Bt extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${D(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Wt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${D(t)}/message/${n}/action/${s}`}}class Vt extends le{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return M.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return r(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:i,fileName:r}=this.parameters,a=Object.assign({file:{name:r,id:i}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${D(t)}/0/${D(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class zt extends le{constructor(e){super({method:ae.LOCAL}),this.parameters=e}operation(){return M.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return r(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${D(e)}/files/${t}/${s}`}}class Jt extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${D(s)}/files/${t}/${n}`}}class Xt extends le{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return M.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${D(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Qt extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${D(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class Yt extends le{constructor(e){super({method:ae.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return M.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return r(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?Yt.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class Zt{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return r(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:M.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof I?e:I.create(e);throw new d("File upload error.",t.toStatus(M.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return r(this,void 0,void 0,(function*(){const e=new Qt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return r(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:i}=this.parameters,{id:r,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&i&&(this.file=yield i.encryptFile(t,this.file,s))),this.parameters.sendRequest(new Yt({fileId:r,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return r(this,void 0,void 0,(function*(){var s,n,i,r;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(r=null===(i=a.status)||void 0===i?void 0:i.statusCode)&&void 0!==r?r:0,channel:this.parameters.channel,id:e,name:t})}))}}class es{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return Ct.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Mt({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ts extends es{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class ss extends es{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return Ct.ChannelGroup}}class ns extends es{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class is extends es{get entityType(){return"Channel"}get name(){return this._nameOrId}}class rs extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${D(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class as extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${D(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class os extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${D(t)}`}}class cs extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${D(t)}/remove`}}class us extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return r(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ls{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new us({keySet:this.keySet}),s=e=>{e&&this.logger.debug("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new as(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new rs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class hs extends le{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: fcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let i="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(i=`${i}/remove`),i}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class ds extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return M.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ps extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return M.PNPushNotificationEnabledChannelsOperation}parse(e){return r(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class gs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return M.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends hs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return M.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ys{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new ds(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ms extends le{constructor(e){var t,s,n,i,r,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(i=e.limit)&&void 0!==i||(e.limit=100)}operation(){return M.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";return r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}}class fs extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${D(t)}`}}class vs extends le{constructor(e){var t,s,n,i,r,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(i=(p=e.include).statusField)&&void 0!==i||(p.statusField=false),null!==(r=(g=e.include).typeField)&&void 0!==r||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${D(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}}class Ss extends le{constructor(e){var t,s,n,i,r,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(i=(p=e.include).statusField)&&void 0!==i||(p.statusField=false),null!==(r=(g=e.include).typeField)&&void 0!==r||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${D(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Os extends le{constructor(e){var t,s,n,i;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return M.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";return r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}}class ws extends le{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return M.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${D(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class ks extends le{constructor(e){var t,s,n;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return M.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${D(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class js extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${D(t)}`}}class Cs extends le{constructor(e){var t,s,n,i,r,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(i=(p=e.include).statusField)&&void 0!==i||(p.statusField=false),null!==(r=(g=e.include).typeField)&&void 0!==r||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return M.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${D(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}}class Ps extends le{constructor(e){var t,s,n,i,r,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(i=(p=e.include).statusField)&&void 0!==i||(p.statusField=false),null!==(r=(g=e.include).typeField)&&void 0!==r||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return M.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${D(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:i}=this.parameters;let r="";r="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),i?{limit:i}:{}),r.length?{sort:r}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Es extends le{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${D(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ns extends le{constructor(e){var t,s,n;super({method:ae.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return M.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${D(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ts{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new Os(Object.assign(Object.assign({},s),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}))}getUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const i=new Es(Object.assign(Object.assign({},n),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(i,((e,s)=>{r(s),t(e,s)})):this.sendRequest(i).then((e=>(r(e),e)))}))}setUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ns(Object.assign(Object.assign({},e),{keySet:this.keySet})),i=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}))}removeUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return r(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const i=new js(Object.assign(Object.assign({},n),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(i,((e,s)=>{r(s),t(e,s)})):this.sendRequest(i).then((e=>(r(e),e)))}))}getAllChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ms(Object.assign(Object.assign({},s),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}))}getChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){const s=new ws(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){const s=new ks(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return r(this,void 0,void 0,(function*(){const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new Cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ps(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return r(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const i=new vs(Object.assign(Object.assign({},n),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(i,((e,s)=>{r(s),t(e,s)})):this.sendRequest(i).then((e=>(r(e),e)))}))}setMemberships(e,t){return r(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}))}removeMemberships(e,t){return r(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Ss(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}))}fetchMemberships(e,t){return r(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,i={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},r=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(i,((e,s)=>{t(e,s?r(s):s)})):this.getChannelMembers(i).then(r)}const i=e,r={uuid:null!==(n=i.userId)&&void 0!==n?n:i.uuid,filter:i.filter,limit:i.limit,page:i.page,include:Object.assign({},i.include),sort:i.sort?Object.fromEntries(Object.entries(i.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(r,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(r).then(a)}))}addMemberships(e,t){return r(this,void 0,void 0,(function*(){var s,n,i,r,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const r=e,a={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(i=null===(n=r.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==i?i:r.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(r=c.userId)&&void 0!==r?r:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class _s extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNCreateRelationshipOperation}validate(){return this.parameters.relationship?this.parameters.relationship.entityAId?this.parameters.relationship.entityBId?void 0:"Entity B id cannot be empty":"Entity A id cannot be empty":"Relationship cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.idempotencyKey&&(t=Object.assign(Object.assign({},t),{"Idempotency-Key":this.parameters.idempotencyKey})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.relationship+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/subkeys/${e}/relationships`}get body(){return JSON.stringify({data:this.parameters.relationship})}}class Is extends le{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return M.PNGetAllRelationshipsOperation}get path(){return`/subkeys/${this.parameters.keySet.subscribeKey}/relationships`}get queryParameters(){const{entityAId:e,entityBId:t,cursor:s,limit:n,filter:i,sort:r,filterAdvanced:a}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},e?{entity_a_id:e}:{}),t?{entity_b_id:t}:{}),s?{cursor:s}:{}),n?{limit:`${n}`}:{}),i?{filter:i}:{}),r?{sort:r}:{}),a?{filter_advanced:a}:{})}}class Ms extends le{constructor(e){super({method:ae.PUT}),this.parameters=e}operation(){return M.PNUpdateRelationshipOperation}validate(){return this.parameters.id?this.parameters.relationship?this.parameters.relationship.entityAId?this.parameters.relationship.entityBId?void 0:"Entity B id cannot be empty":"Entity A id cannot be empty":"Relationship cannot be empty":"Relationship id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.relationship+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/relationships/${D(t)}`}get body(){return JSON.stringify({data:this.parameters.relationship})}}class As extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveRelationshipOperation}validate(){if(!this.parameters.id)return"Relationship id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return r(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/relationships/${D(t)}`}}function Rs(e){return"/"+e.split(".").join("/")}function Us(e,t){const s=[];if(e)for(const[t,n]of Object.entries(e))s.push({op:"add",path:Rs(t),value:n});if(t)for(const e of t)s.push({op:"remove",path:Rs(e)});return s}class $s extends le{constructor(e){super({method:ae.PATCH}),this.parameters=e}operation(){return M.PNPatchRelationshipOperation}validate(){if(!this.parameters.id)return"Relationship id cannot be empty";const e=this.parameters.set&&Object.keys(this.parameters.set).length>0,t=this.parameters.remove&&this.parameters.remove.length>0;return e||t?void 0:"At least one of set or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),this.parameters.idempotencyKey&&(t=Object.assign(Object.assign({},t),{"Idempotency-Key":this.parameters.idempotencyKey})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/relationships/${D(t)}`}get body(){const e=Us(this.parameters.set?Object.fromEntries(Object.entries(this.parameters.set).map((([e,t])=>[`payload.${e}`,t]))):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(e)}}class Ds extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNGetRelationshipOperation}validate(){if(!this.parameters.id)return"Relationship id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/relationships/${D(t)}`}}class Fs extends le{constructor(e){super({method:ae.POST}),this.parameters=e}operation(){return M.PNCreateEntityOperation}validate(){return this.parameters.entity?this.parameters.entity.entityClass?void 0===this.parameters.entity.entityClassVersion||null===this.parameters.entity.entityClassVersion?"Entity class version cannot be empty":void 0:"Entity class cannot be empty":"Entity cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.idempotencyKey&&(t=Object.assign(Object.assign({},t),{"Idempotency-Key":this.parameters.idempotencyKey})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.entity+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/subkeys/${e}/entities`}get body(){return JSON.stringify({data:this.parameters.entity})}}class xs extends le{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return M.PNGetAllEntitiesOperation}validate(){if(!this.parameters.entityClass)return"Entity class cannot be empty"}get path(){return`/subkeys/${this.parameters.keySet.subscribeKey}/entities`}get queryParameters(){const{entityClass:e,entityClassVersion:t,cursor:s,limit:n,filter:i,sort:r,filterAdvanced:a}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({entity_class:e},void 0!==t?{entity_class_version:`${t}`}:{}),s?{cursor:s}:{}),n?{limit:`${n}`}:{}),i?{filter:i}:{}),r?{sort:r}:{}),a?{filter_advanced:a}:{})}}class qs extends le{constructor(e){super({method:ae.PUT}),this.parameters=e}operation(){return M.PNUpdateEntityOperation}validate(){return this.parameters.id?this.parameters.entity?void 0===this.parameters.entity.entityClassVersion||null===this.parameters.entity.entityClassVersion?"Entity class version cannot be empty":void 0:"Entity cannot be empty":"Entity id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.entity+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/entities/${D(t)}`}get body(){return JSON.stringify({data:this.parameters.entity})}}class Gs extends le{constructor(e){super({method:ae.DELETE}),this.parameters=e}operation(){return M.PNRemoveEntityOperation}validate(){if(!this.parameters.id)return"Entity id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return r(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/entities/${D(t)}`}}class Ls extends le{constructor(e){super({method:ae.PATCH}),this.parameters=e}operation(){return M.PNPatchEntityOperation}validate(){if(!this.parameters.id)return"Entity id cannot be empty";const e=this.parameters.set&&Object.keys(this.parameters.set).length>0,t=this.parameters.remove&&this.parameters.remove.length>0;return e||t?void 0:"At least one of set or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),this.parameters.idempotencyKey&&(t=Object.assign(Object.assign({},t),{"Idempotency-Key":this.parameters.idempotencyKey})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/entities/${D(t)}`}get body(){const e=Us(this.parameters.set?Object.fromEntries(Object.entries(this.parameters.set).map((([e,t])=>[`payload.${e}`,t]))):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(e)}}class Ks extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNGetEntityOperation}validate(){if(!this.parameters.id)return"Entity id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/subkeys/${e}/entities/${D(t)}`}}class Hs{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}createEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Entity with parameters:"})));const s=new Fs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Entity with parameters:"})));const s=new Ks(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllEntities(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get all Entities with parameters:"})));const s=new xs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Entity with parameters:"})));const s=new qs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Entity with parameters:"})));const s=new Ls(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Entity with parameters:"})));const s=new Gs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Relationship with parameters:"})));const s=new _s(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Relationship with parameters:"})));const s=new Ds(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllRelationships(e,t){return r(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},s),details:"Get all Relationships with parameters:"})));const n=new Is(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}updateRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Relationship with parameters:"})));const s=new Ms(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Relationship with parameters:"})));const s=new $s(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Relationship with parameters:"})));const s=new As(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}}class Bs extends le{constructor(){super()}operation(){return M.PNTimeOperation}parse(e){return r(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class Ws extends le{constructor(e){super(),this.parameters=e}operation(){return M.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return r(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:i,PubNubFile:r}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return r.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(r.create({data:c,name:i,mimeType:a}),r))),o||r.create({data:c,name:i,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${D(t)}/files/${s}/${n}`}}class Vs{static notificationPayload(e,t){return new Oe(e,t)}static generateUUID(){return te.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")}))),this._objects=new Ts(this._configuration,this.sendRequest.bind(this)),this._dataSync=new Hs(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ls(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new ys(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ge,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new Ye({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new St({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===he.Message||e.type===he.Signal?B(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new me(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub",`Set auth key: ${e}`),this._configuration.setAuthKey(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e,this.onUserIdChange&&this.onUserIdChange(this._configuration.userId)}getUserId(){return this._configuration.userId}setUserId(e){this.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub",`Set cipher key: ${e}`),this.cipherKey=e}set heartbeatInterval(e){var t;this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e),this.onHeartbeatIntervalChange&&this.onHeartbeatIntervalChange(null!==(t=this._configuration.getHeartbeatInterval())&&void 0!==t?t:0)}setHeartbeatInterval(e){this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new is(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new ss(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ts(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new ns(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new _t({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return r(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const i=e.request(),r=e.operation();i.formData&&i.formData.length>0||r===M.PNDownloadFileOperation?i.timeout=this._configuration.getFileTimeout():r===M.PNSubscribeOperation||r===M.PNReceiveMessagesOperation?i.timeout=this._configuration.getSubscribeTimeout():i.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:r,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(i);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Vs.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof I?e:I.create(e),n=s.toFormattedMessage(r);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(r,n)}))),t(s.toStatus(r),null);const i=s.toPubNubError(r,n);throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:i}))),i}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new Ot(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),i=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}}))}signal(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return r(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Pt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const i={};i.channels=n.channels,i.channelGroups=n.channelGroups,t&&(i.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(i):this.eventEngine&&this.eventEngine.subscribe(i)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"})));let n,i=!t||0===t.length;if(!i&&e instanceof _t&&e.subscriptions.length===(null==t?void 0:t.length)&&(i=e.subscriptions.every((e=>t.includes(e)))),i&&delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Pt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof _t?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const i=s.subscriptionInput(!1),r=i.channelGroups,a=i.channels;e.push(...n.channelGroups.filter((e=>r.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],i=n=>{const i=n.subscriptionNames(!0),r=n.subscriptionType===Ct.Channel?t:e;i.some((e=>r.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof _t?e.subscriptions.forEach((e=>{i(e.state.entity)})):e instanceof Mt&&i(e.state.entity)}));let r="Some entities still in use:";return t.length+e.length===n.length&&(r="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:r}})),n.remove(new Pt({channels:t,channelGroups:e})),n.isEmpty))return}const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(r):this.eventEngine&&this.eventEngine.unsubscribe(r)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const s=new pe(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var i;this.subscriptionManager&&(null===(i=this.subscriptionManager.abort)||void 0===i?void 0:i.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const i=t.subscriptionInput(!1);if(i.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(i.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(i.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:M.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new $t({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub",`Disconnect (while offline? ${e?"yes":"no"})`),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return r(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return r(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Ft(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return r(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new Dt({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),i=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}}))}getState(e,t){return r(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new At(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{i(s),t(e,s)})):this.sendRequest(n).then((e=>(i(e),e)))}}))}setState(e,t){return r(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:i,userId:r}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state))),this.onPresenceStateChange&&this.onPresenceStateChange(this.presenceState)}o="withHeartbeat"in e&&e.withHeartbeat?new Ut(Object.assign(Object.assign({},e),{keySet:i,heartbeat:a})):new Rt(Object.assign(Object.assign({},e),{keySet:i,uuid:r}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof Ut?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&(this.subscriptionManager.setState(e),this.onPresenceStateChange&&this.onPresenceStateChange(this.subscriptionManager.presenceState)),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return r(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:i}=e;if(i&&(i=i.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),0===(null!=i?i:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:M.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const r=new Ut(Object.assign(Object.assign({},e),{channels:[...new Set(n)],channelGroups:[...new Set(i)],keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{r.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(r,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(r).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return r(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return r(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}setToken(e){this.token=e}parseToken(e){return this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return r(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return r(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}get dataSync(){return this._dataSync}fetchUsers(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return r(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return r(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return r(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return r(this,void 0,void 0,(function*(){var s,n,i;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const i=e,r={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(n=i.userIds)&&void 0!==n?n:i.uuids,limit:0};return t?this.objects.removeChannelMembers(r,t):this.objects.removeChannelMembers(r)}const r=e,a={uuid:r.userId,channels:null!==(i=r.spaceIds)&&void 0!==i?i:r.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return r(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:M.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},i=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,i(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof I&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return r(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},i=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${D(t)}`)).join("&"):`${e}=${D(t)}`})).join("&");return`${s.origin}${s.path}?${i}`}}downloadFile(e,t){return r(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new Ws(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return r(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new Bs,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s!==this._globalSubscriptionSet&&s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return r(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return r(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Vs.decoder=new TextDecoder,Vs.OPERATIONS=M,Vs.CATEGORIES=h,Vs.Endpoint=V,Vs.ExponentialRetryPolicy=z.ExponentialRetryPolicy,Vs.LinearRetryPolicy=z.LinearRetryPolicy,Vs.NoneRetryPolicy=z.None,Vs.LogLevel=$;class zs{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Js extends Vs{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,i=U(e),r=Object.assign(Object.assign({},i),{sdkFamily:"Web"});r.PubNubFile=o;const a=se(r,(e=>{if(e.cipherKey){return new N({default:new E(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new k({cipherKey:e.cipherKey})]})}}));let u,l;e.subscriptionWorkerLogVerbosity?e.subscriptionWorkerLogLevel=$.Debug:void 0===e.subscriptionWorkerLogLevel&&(e.subscriptionWorkerLogLevel=$.None),void 0!==e.subscriptionWorkerLogVerbosity&&a.logger().warn("Configuration","'subscriptionWorkerLogVerbosity' is deprecated. Use 'subscriptionWorkerLogLevel' instead."),a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new re(new zs((e=>R(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new C({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()}));let h,d=()=>{},p=()=>{},g=()=>{},b=()=>{};h=new P;let y=new ue(a.logger(),r.transport);if(i.subscriptionWorkerUrl)try{const e=new A({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:i.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),announceSuccessfulHeartbeats:a.announceSuccessfulHeartbeats,announceFailedHeartbeats:a.announceFailedHeartbeats,workerOfflineClientsCheckInterval:r.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:r.subscriptionWorkerUnsubscribeOfflineClients,workerLogLevel:r.subscriptionWorkerLogLevel,tokenManager:u,transport:y,logger:a.logger()});p=t=>e.onPresenceStateChange(t),d=t=>e.onHeartbeatIntervalChange(t),g=t=>e.onTokenChange(t),b=t=>e.onUserIdChange(t),y=e,i.subscriptionWorkerUnsubscribeOfflineClients&&window.addEventListener("pagehide",(t=>{t.persisted||e.terminate()}),{once:!0})}catch(e){a.logger().error("PubNub",(()=>({messageType:"error",message:e})))}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const m=new ce({clientConfiguration:a,tokenManager:u,transport:y});if(super({configuration:a,transport:m,cryptography:h,tokenManager:u,crypto:l}),this.File=o,this.onHeartbeatIntervalChange=d,this.onAuthenticationChange=g,this.onPresenceStateChange=p,this.onUserIdChange=b,y instanceof A){y.emitStatus=this.emitStatus.bind(this);const e=this.disconnect.bind(this);this.disconnect=t=>{y.disconnect(),e()}}(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Js.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Js.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Js.CryptoModule=N,Js})); diff --git a/dist/web/pubnub.worker.js b/dist/web/pubnub.worker.js index a7cd212a8..e27a55aa9 100644 --- a/dist/web/pubnub.worker.js +++ b/dist/web/pubnub.worker.js @@ -1861,6 +1861,10 @@ * Request will be sent using `PATCH` method. */ TransportMethod["PATCH"] = "PATCH"; + /** + * Request will be sent using `PUT` method. + */ + TransportMethod["PUT"] = "PUT"; /** * Request will be sent using `DELETE` method. */ diff --git a/dist/web/pubnub.worker.min.js b/dist/web/pubnub.worker.min.js index df2c4c5b7..a53941cb3 100644 --- a/dist/web/pubnub.worker.min.js +++ b/dist/web/pubnub.worker.min.js @@ -1,2 +1,2 @@ !function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";var e,t,s,n;!function(e){e.Unregister="unregister",e.Disconnect="disconnect",e.IdentityChange="identityChange",e.AuthChange="authChange",e.HeartbeatIntervalChange="heartbeatIntervalChange",e.PresenceStateChange="presenceStateChange",e.SendSubscribeRequest="sendSubscribeRequest",e.CancelSubscribeRequest="cancelSubscribeRequest",e.SendHeartbeatRequest="sendHeartbeatRequest",e.SendLeaveRequest="sendLeaveRequest"}(e||(e={}));class i extends CustomEvent{get client(){return this.detail.client}}class r extends i{constructor(t){super(e.Unregister,{detail:{client:t}})}clone(){return new r(this.client)}}class a extends i{constructor(t){super(e.Disconnect,{detail:{client:t}})}clone(){return new a(this.client)}}class o extends i{constructor(t,s,n){super(e.IdentityChange,{detail:{client:t,oldUserId:s,newUserId:n}})}get oldUserId(){return this.detail.oldUserId}get newUserId(){return this.detail.newUserId}clone(){return new o(this.client,this.oldUserId,this.newUserId)}}class c extends i{constructor(t,s,n){super(e.AuthChange,{detail:{client:t,oldAuth:n,newAuth:s}})}get oldAuth(){return this.detail.oldAuth}get newAuth(){return this.detail.newAuth}clone(){return new c(this.client,this.newAuth,this.oldAuth)}}class l extends i{constructor(t,s,n){super(e.HeartbeatIntervalChange,{detail:{client:t,oldInterval:n,newInterval:s}})}get oldInterval(){return this.detail.oldInterval}get newInterval(){return this.detail.newInterval}clone(){return new l(this.client,this.newInterval,this.oldInterval)}}class h extends i{constructor(t,s){super(e.PresenceStateChange,{detail:{client:t,state:s}})}get state(){return this.detail.state}clone(){return new h(this.client,this.state)}}class u extends i{constructor(t,s){super(e.SendSubscribeRequest,{detail:{client:t,request:s}})}get request(){return this.detail.request}clone(){return new u(this.client,this.request)}}class d extends i{constructor(t,s){super(e.CancelSubscribeRequest,{detail:{client:t,request:s}})}get request(){return this.detail.request}clone(){return new d(this.client,this.request)}}class g extends i{constructor(t,s){super(e.SendHeartbeatRequest,{detail:{client:t,request:s}})}get request(){return this.detail.request}clone(){return new g(this.client,this.request)}}class p extends i{constructor(t,s){super(e.SendLeaveRequest,{detail:{client:t,request:s}})}get request(){return this.detail.request}clone(){return new p(this.client,this.request)}}!function(e){e.Registered="Registered",e.Unregistered="Unregistered"}(t||(t={}));class f extends CustomEvent{constructor(e){super(t.Registered,{detail:e})}get client(){return this.detail}clone(){return new f(this.client)}}class q extends CustomEvent{constructor(e,s=!1){super(t.Unregistered,{detail:{client:e,withLeave:s}})}get client(){return this.detail.client}get withLeave(){return this.detail.withLeave}clone(){return new q(this.client,this.withLeave)}}!function(e){e.Changed="changed",e.Invalidated="invalidated"}(s||(s={}));class v extends CustomEvent{constructor(e,t,n,i){super(s.Changed,{detail:{withInitialResponse:e,newRequests:t,canceledRequests:n,leaveRequest:i}})}get requestsWithInitialResponse(){return this.detail.withInitialResponse}get newRequests(){return this.detail.newRequests}get leaveRequest(){return this.detail.leaveRequest}get canceledRequests(){return this.detail.canceledRequests}clone(){return new v(this.requestsWithInitialResponse,this.newRequests,this.canceledRequests,this.leaveRequest)}}class m extends CustomEvent{constructor(){super(s.Invalidated)}clone(){return new m}}!function(e){e.Started="started",e.Canceled="canceled",e.Success="success",e.Error="error"}(n||(n={}));class b extends CustomEvent{get request(){return this.detail.request}}class S extends b{constructor(e){super(n.Started,{detail:{request:e}})}clone(e){return new S(null!=e?e:this.request)}}class C extends b{constructor(e,t,s){super(n.Success,{detail:{request:e,fetchRequest:t,response:s}})}get fetchRequest(){return this.detail.fetchRequest}get response(){return this.detail.response}clone(e){return new C(null!=e?e:this.request,e?e.asFetchRequest:this.fetchRequest,this.response)}}class R extends b{constructor(e,t,s){super(n.Error,{detail:{request:e,fetchRequest:t,error:s}})}get fetchRequest(){return this.detail.fetchRequest}get error(){return this.detail.error}clone(e){return new R(null!=e?e:this.request,e?e.asFetchRequest:this.fetchRequest,this.error)}}class E extends b{constructor(e){super(n.Canceled,{detail:{request:e}})}clone(e){return new E(null!=e?e:this.request)}}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function y(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var T,w,k={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */T=k,function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function i(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=i,n.VERSION=t,e.uuid=n,e.isUUID=i}(w=k.exports),null!==T&&(T.exports=w.uuid);var I,A=y(k.exports),O={createUUID:()=>A.uuid?A.uuid():A()};class P extends EventTarget{constructor(e,t,s,n,i,r){super(),this.request=e,this.subscribeKey=t,this.channels=n,this.channelGroups=i,this.dependents={},this._completed=!1,this._canceled=!1,this.queryStringFromObject=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${this.encodeString(e)}`)).join("&"):`${t}=${this.encodeString(s)}`})).join("&"),this._accessToken=r,this._userId=s}get identifier(){return this.request.identifier}get origin(){return this.request.origin}get userId(){return this._userId}set userId(e){this._userId=e,this.request.queryParameters.uuid=e}get accessToken(){return this._accessToken}set accessToken(e){this._accessToken=e,e?this.request.queryParameters.auth=e.toString():delete this.request.queryParameters.auth}get client(){return this._client}set client(e){this._client=e}get completed(){return this._completed}get cancellable(){return this.request.cancellable}get canceled(){return this._canceled}set fetchAbortController(e){this.completed||this.canceled||(this.isServiceRequest?this._fetchAbortController?console.error("Only one abort controller can be set for service-provided requests."):this._fetchAbortController=e:console.error("Unexpected attempt to set fetch abort controller on client-provided request."))}get fetchAbortController(){return this._fetchAbortController}get asFetchRequest(){const e=this.request.queryParameters,t={};let s="";if(this.request.headers)for(const[e,s]of Object.entries(this.request.headers))t[e]=s;return e&&0!==Object.keys(e).length&&(s=`?${this.queryStringFromObject(e)}`),new Request(`${this.origin}${this.request.path}${s}`,{method:this.request.method,headers:Object.keys(t).length?t:void 0,redirect:"follow"})}get serviceRequest(){return this._serviceRequest}set serviceRequest(e){if(this.isServiceRequest)return void console.error("Unexpected attempt to set service-provided request on service-provided request.");const t=this.serviceRequest;this._serviceRequest=e,!t||e&&t.identifier===e.identifier||t.detachRequest(this),this.completed||this.canceled||e&&(e.completed||e.canceled)?this._serviceRequest=void 0:t&&e&&t.identifier===e.identifier||e&&e.attachRequest(this)}get isServiceRequest(){return!this.client}dependentRequests(){return this.isServiceRequest?Object.values(this.dependents):[]}attachRequest(e){this.isServiceRequest&&!this.dependents[e.identifier]?(this.dependents[e.identifier]=e,this.addEventListenersForRequest(e)):this.isServiceRequest||console.error("Unexpected attempt to attach requests using client-provided request.")}detachRequest(e){this.isServiceRequest&&this.dependents[e.identifier]?(delete this.dependents[e.identifier],e.removeEventListenersFromRequest(),0===Object.keys(this.dependents).length&&this.cancel("Cancel request")):this.isServiceRequest||console.error("Unexpected attempt to detach requests using client-provided request.")}cancel(e,t=!1){if(this.completed||this.canceled)return[];const s=this.dependentRequests();return this.isServiceRequest?(t||s.forEach((e=>e.serviceRequest=void 0)),this._fetchAbortController&&(this._fetchAbortController.abort(e),this._fetchAbortController=void 0)):this.serviceRequest=void 0,this._canceled=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new E(this)),s}requestTimeoutTimer(){return new Promise(((e,t)=>{this._fetchTimeoutTimer=setTimeout((()=>{t(new Error("Request timeout")),this.cancel("Cancel because of timeout",!0)}),1e3*this.request.timeout)}))}stopRequestTimeoutTimer(){this._fetchTimeoutTimer&&(clearTimeout(this._fetchTimeoutTimer),this._fetchTimeoutTimer=void 0)}handleProcessingStarted(){this.logRequestStart(this),this.dispatchEvent(new S(this))}handleProcessingSuccess(e,t){this.addRequestInformationForResult(this,e,t),this.logRequestSuccess(this,t),this._completed=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new C(this,e,t))}handleProcessingError(e,t){this.addRequestInformationForResult(this,e,t),this.logRequestError(this,t),this._completed=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new R(this,e,t))}addEventListenersForRequest(e){this.isServiceRequest?(e.abortController=new AbortController,this.addEventListener(n.Started,(t=>{t instanceof S&&(e.logRequestStart(t.request),e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0}),this.addEventListener(n.Success,(t=>{t instanceof C&&(e.removeEventListenersFromRequest(),e.addRequestInformationForResult(t.request,t.fetchRequest,t.response),e.logRequestSuccess(t.request,t.response),e._completed=!0,e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0}),this.addEventListener(n.Error,(t=>{t instanceof R&&(e.removeEventListenersFromRequest(),e.addRequestInformationForResult(t.request,t.fetchRequest,t.error),e.logRequestError(t.request,t.error),e._completed=!0,e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0})):console.error("Unexpected attempt to add listeners using a client-provided request.")}removeEventListenersFromRequest(){!this.isServiceRequest&&this.abortController?(this.abortController.abort(),this.abortController=void 0):this.isServiceRequest&&console.error("Unexpected attempt to remove listeners using a client-provided request.")}hasAnyChannelsOrGroups(e,t){return this.channels.some((t=>e.includes(t)))||this.channelGroups.some((e=>t.includes(e)))}addRequestInformationForResult(e,t,s){this.isServiceRequest||(s.clientIdentifier=this.client.identifier,s.identifier=this.identifier,s.url=t.url)}logRequestStart(e){this.isServiceRequest||this.client.logger.debug((()=>({messageType:"network-request",message:e.request})))}logRequestSuccess(e,t){this.isServiceRequest||this.client.logger.debug((()=>{const{status:s,headers:n,body:i}=t.response,r=e.asFetchRequest;return Object.entries(n).forEach((([e,t])=>t)),{messageType:"network-response",message:{status:s,url:r.url,headers:n,body:i}}}))}logRequestError(e,t){this.isServiceRequest||((t.error?t.error.message:"Unknown").toLowerCase().includes("timeout")?this.client.logger.debug((()=>({messageType:"network-request",message:e.request,details:"Timeout",canceled:!0}))):this.client.logger.warn((()=>{const{details:s,canceled:n}=this.errorDetailsFromSendingError(t);let i=s;return n?i="Aborted":s.toLowerCase().includes("network")&&(i="Network error"),{messageType:"network-request",message:e.request,details:i,canceled:n,failed:!n}})))}errorDetailsFromSendingError(e){const t=!!e.error&&("TIMEOUT"===e.error.type||"ABORTED"===e.error.type);let s=e.error?e.error.message:"Unknown";if(e.response){const t=e.response.headers["content-type"];if(e.response.body&&t&&(-1!==t.indexOf("javascript")||-1!==t.indexOf("json")))try{const t=JSON.parse((new TextDecoder).decode(e.response.body));"message"in t?s=t.message:"error"in t&&("string"==typeof t.error?s=t.error:"object"==typeof t.error&&"message"in t.error&&(s=t.error.message))}catch(e){}"Unknown"===s&&(s=e.response.status>=500?"Internal Server Error":400==e.response.status?"Bad request":403==e.response.status?"Access denied":`${e.response.status}`)}return{details:s,canceled:t}}encodeString(e){return encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))}}class F extends P{static fromTransportRequest(e,t,s){return new F(e,t,s)}static fromCachedState(e,t,s,n,i,r){return new F(e,t,r,s,n,i)}static fromRequests(e,t,s,n,i){var r;const a=e[Math.floor(Math.random()*e.length)],o="0"===(null!==(r=a.request.queryParameters.tt)&&void 0!==r?r:"0"),c=o&&null!=i?i:{},l=Object.assign({},a.request),h=new Set,u=new Set;for(const t of e)o&&!i&&t.state&&Object.assign(c,t.state),t.channelGroups.forEach(h.add,h),t.channels.forEach(u.add,u);if(u.size||h.size){const e=l.path.split("/");e[4]=u.size?[...u].sort().join(","):",",l.path=e.join("/")}h.size&&(l.queryParameters["channel-group"]=[...h].sort().join(",")),Object.keys(c).length?l.queryParameters.state=JSON.stringify(c):delete l.queryParameters.state,t&&(l.queryParameters.auth=t.toString()),l.identifier=O.createUUID();const d=new F(l,a.subscribeKey,t,[...h],[...u],c);for(const t of e)t.serviceRequest=d;return d.isInitialSubscribe&&s&&"0"!==s&&(d.timetokenOverride=s,n&&(d.timetokenRegionOverride=n)),d}constructor(e,t,s,n,i,r){var a;const o=!!e.queryParameters&&"on-demand"in e.queryParameters;if(delete e.queryParameters["on-demand"],super(e,t,e.queryParameters.uuid,null!=i?i:F.channelsFromRequest(e),null!=n?n:F.channelGroupsFromRequest(e),s),this._creationDate=Date.now(),this.timetokenRegionOverride="0",this._creationDate<=F.lastCreationDate?(F.lastCreationDate++,this._creationDate=F.lastCreationDate):F.lastCreationDate=this._creationDate,this._requireCachedStateReset=o,e.queryParameters["filter-expr"]&&(this.filterExpression=e.queryParameters["filter-expr"]),this._timetoken=null!==(a=e.queryParameters.tt)&&void 0!==a?a:"0","0"===this._timetoken&&(delete e.queryParameters.tt,delete e.queryParameters.tr),e.queryParameters.tr&&(this._region=e.queryParameters.tr),r&&(this.state=r),this.state||!e.queryParameters.state||e.queryParameters.state.length<=2||"0"!==this._timetoken)return;const c=JSON.parse(e.queryParameters.state);for(const e of Object.keys(c))this.channels.includes(e)||this.channelGroups.includes(e)||delete c[e];this.state=c}get creationDate(){return this._creationDate}get asIdentifier(){const e=this.accessToken?this.accessToken.asIdentifier:void 0,t=`${this.userId}-${this.subscribeKey}${e?`-${e}`:""}`;return this.filterExpression?`${t}-${this.filterExpression}`:t}get isInitialSubscribe(){return"0"===this._timetoken}get timetoken(){return this._timetoken}set timetoken(e){this._timetoken=e,this.request.queryParameters.tt=e}get region(){return this._region}set region(e){this._region=e,e?this.request.queryParameters.tr=e:delete this.request.queryParameters.tr}get requireCachedStateReset(){return this._requireCachedStateReset}static useCachedState(e){return!!e.queryParameters&&!("on-demand"in e.queryParameters)}resetToInitialRequest(){this._requireCachedStateReset=!0,this._timetoken="0",this._region=void 0,delete this.request.queryParameters.tt}isSubsetOf(e){return!(e.channelGroups.length&&!this.includesStrings(e.channelGroups,this.channelGroups))&&(!(e.channels.length&&!this.includesStrings(e.channels,this.channels))&&("0"===this.timetoken||this.timetoken===e.timetoken||"0"===e.timetoken))}toString(){return`SubscribeRequest { clientIdentifier: ${this.client?this.client.identifier:"service request"}, requestIdentifier: ${this.identifier}, serviceRequestIdentified: ${this.client?this.serviceRequest?this.serviceRequest.identifier:"'not set'":"'is service request"}, channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}], timetoken: ${this.timetoken}, region: ${this.region}, reset: ${this._requireCachedStateReset?"'reset'":"'do not reset'"} }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[4];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}includesStrings(e,t){const s=new Set(e);return t.every(s.has,s)}}F.lastCreationDate=0;class L{static compare(e,t){var s,n;return(null!==(s=e.expiration)&&void 0!==s?s:0)-(null!==(n=t.expiration)&&void 0!==n?n:0)}constructor(e,t,s){this.token=e,this.simplifiedToken=t,this.expiration=s}get asIdentifier(){var e;return null!==(e=this.simplifiedToken)&&void 0!==e?e:this.token}equalTo(e,t=!1){return this.asIdentifier===e.asIdentifier&&(!t||this.expiration===e.expiration)}isNewerThan(e){return!!this.simplifiedToken&&this.expiration>e.expiration}toString(){return this.token}}!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(I||(I={}));class j extends P{static fromTransportRequest(e,t,s){return new j(e,t,s)}constructor(e,t,s){const n=j.channelGroupsFromRequest(e),i=j.channelsFromRequest(e),r=n.filter((e=>!e.endsWith("-pnpres"))),a=i.filter((e=>!e.endsWith("-pnpres")));super(e,t,e.queryParameters.uuid,a,r,s),this.allChannelGroups=n,this.allChannels=i}toString(){return`LeaveRequest { channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}] }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[6];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}}const _=(e,t,s)=>{if(t=t.filter((e=>!e.endsWith("-pnpres"))).map((e=>x(e))).sort(),s=s.filter((e=>!e.endsWith("-pnpres"))).map((e=>x(e))).sort(),0===t.length&&0===s.length)return;const n=s.length>0?s.join(","):void 0,i=0===t.length?",":t.join(","),r=Object.assign(Object.assign({instanceid:e.identifier,uuid:e.userId,requestid:O.createUUID()},e.accessToken?{auth:e.accessToken.toString()}:{}),n?{"channel-group":n}:{}),a={origin:e.origin,path:`/v2/presence/sub-key/${e.subKey}/channel/${i}/leave`,queryParameters:r,method:I.GET,headers:{},timeout:10,cancellable:!1,compressible:!1,identifier:r.requestid};return j.fromTransportRequest(a,e.subKey,e.accessToken)},x=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`));class U{static squashedChanges(e){if(!e.length||1===e.length)return e;const t=e.sort(((e,t)=>e.timestamp-t.timestamp)),s=t.filter((e=>!e.remove));s.forEach((e=>{for(let n=0;n{if(n[e.clientIdentifier]){const s=t.indexOf(e);s>=0&&t.splice(s,1)}n[e.clientIdentifier]=e})),t}constructor(e,t,s,n,i=!1){this.clientIdentifier=e,this.request=t,this.remove=s,this.sendLeave=n,this.clientInvalidate=i,this._timestamp=this.timestampForChange()}get timestamp(){return this._timestamp}toString(){return`SubscriptionStateChange { timestamp: ${this.timestamp}, client: ${this.clientIdentifier}, request: ${this.request.toString()}, remove: ${this.remove?"'remove'":"'do not remove'"}, sendLeave: ${this.sendLeave?"'send'":"'do not send'"} }`}toJSON(){return this.toString()}timestampForChange(){const e=Date.now();return e<=U.previousChangeTimestamp?U.previousChangeTimestamp++:U.previousChangeTimestamp=e,U.previousChangeTimestamp}}U.previousChangeTimestamp=0;class G extends EventTarget{constructor(e){super(),this.identifier=e,this.requestListenersAbort={},this.clientsState={},this.clientsPresenceState={},this.lastCompletedRequest={},this.clientsForInvalidation=[],this.requests={},this.serviceRequests=[],this.channelGroups=new Set,this.channels=new Set}hasStateForClient(e){return!!this.clientsState[e.identifier]}uniqueStateForClient(e,t,s){let n=[...s],i=[...t];return Object.entries(this.clientsState).forEach((([t,s])=>{t!==e.identifier&&(n=n.filter((e=>!s.channelGroups.has(e))),i=i.filter((e=>!s.channels.has(e))))})),{channels:i,channelGroups:n}}requestForClient(e,t=!1){var s;return null!==(s=this.requests[e.identifier])&&void 0!==s?s:t?this.lastCompletedRequest[e.identifier]:void 0}updateClientAccessToken(e){this.accessToken&&!e.isNewerThan(this.accessToken)||(this.accessToken=e)}updateClientPresenceState(e,t){const s=this.clientsPresenceState[e.identifier];null!=t||(t={}),s?(Object.assign(s.state,t),s.update=Date.now()):this.clientsPresenceState[e.identifier]={update:Date.now(),state:t}}invalidateClient(e){this.clientsForInvalidation.includes(e.identifier)||this.clientsForInvalidation.push(e.identifier)}processChanges(e){if(e.length&&(e=U.squashedChanges(e)),!e.length)return;let t=0===this.channelGroups.size&&0===this.channels.size;t||(t=e.some((e=>e.remove||e.request.requireCachedStateReset)));const s=this.applyChanges(e);let n;t&&(n=this.refreshInternalState()),this.handleSubscriptionStateChange(e,n,s.initial,s.continuation,s.removed),Object.keys(this.clientsState).length||this.dispatchEvent(new m)}applyChanges(e){const t=[],s=[],n=[];return e.forEach((e=>{const{remove:i,request:r,clientIdentifier:a,clientInvalidate:o}=e;i||(r.isInitialSubscribe?s.push(r):t.push(r),this.requests[a]=r,this.addListenersForRequestEvents(r)),i&&(this.requests[a]||this.lastCompletedRequest[a])&&(o&&(delete this.clientsPresenceState[a],delete this.lastCompletedRequest[a],delete this.clientsState[a]),delete this.requests[a],n.push(r))})),{initial:s,continuation:t,removed:n}}handleSubscriptionStateChange(e,t,s,n,i){var r,a,o,c;const l=this.serviceRequests.filter((e=>!e.completed&&!e.canceled)),h=[],u=[],d=[],g=[];let p,f,q,m;const b=e=>{g.push(e);const t=e.dependentRequests().filter((e=>!i.includes(e)));0!==t.length&&(t.forEach((e=>e.serviceRequest=void 0)),(e.isInitialSubscribe?s:n).push(...t))};if(t)if(t.channels.added||t.channelGroups.added){for(const e of l)b(e);l.length=0}else if(t.channels.removed||t.channelGroups.removed){const e=null!==(r=t.channelGroups.removed)&&void 0!==r?r:[],s=null!==(a=t.channels.removed)&&void 0!==a?a:[];for(let t=l.length-1;t>=0;t--){const n=l[t];n.hasAnyChannelsOrGroups(s,e)&&(b(n),l.splice(t,1))}}n=this.squashSameClientRequests(n),((s=this.squashSameClientRequests(s)).length?n:[]).forEach((e=>{let t=!m;t||"0"===e.timetoken||("0"===m?t=!0:e.timetokenf)),t&&(f=e.creationDate,m=e.timetoken,q=e.region)}));const S={};n.forEach((e=>{S[e.timetoken]?S[e.timetoken].push(e):S[e.timetoken]=[e]})),this.attachToServiceRequest(l,s);for(let e=s.length-1;e>=0;e--){const t=s[e];l.forEach((n=>{if(!t.isSubsetOf(n)||n.isInitialSubscribe)return;const{region:i,timetoken:r}=n;h.push({request:t,timetoken:r,region:i}),s.splice(e,1)}))}if(s.length){let e;if(n.length){m=Object.keys(S).sort().pop();const t=S[m];q=t[0].region,delete S[m],t.forEach((e=>e.resetToInitialRequest())),e=[...s,...t]}else e=s;this.createAggregatedRequest(e,d,m,q)}Object.values(S).forEach((e=>{this.attachToServiceRequest(d,e),this.attachToServiceRequest(l,e),this.createAggregatedRequest(e,u)}));const C=new Set,R=new Set;if(t&&i.length&&(t.channels.removed||t.channelGroups.removed)){const s=null!==(o=t.channelGroups.removed)&&void 0!==o?o:[],n=null!==(c=t.channels.removed)&&void 0!==c?c:[],r=i[0].client;e.filter((e=>e.remove&&e.sendLeave)).forEach((e=>{const{channels:t,channelGroups:i}=e.request;s.forEach((e=>i.includes(e)&&C.add(e))),n.forEach((e=>t.includes(e)&&R.add(e)))})),p=_(r,[...R],[...C])}(h.length||d.length||u.length||g.length||p)&&this.dispatchEvent(new v(h,[...d,...u],g,p))}refreshInternalState(){const e=new Set,t=new Set;Object.entries(this.requests).forEach((([s,n])=>{var i,r;const a=this.clientsPresenceState[s],o=a?Object.keys(a.state):[],c=null!==(i=(r=this.clientsState)[s])&&void 0!==i?i:r[s]={channels:new Set,channelGroups:new Set};n.channelGroups.forEach((t=>{c.channelGroups.add(t),e.add(t)})),n.channels.forEach((e=>{c.channels.add(e),t.add(e)})),a&&o.length&&(o.forEach((e=>{n.channels.includes(e)||n.channelGroups.includes(e)||delete a.state[e]})),0===Object.keys(a.state).length&&delete this.clientsPresenceState[s])}));const s=this.subscriptionStateChanges(t,e);this.channelGroups=e,this.channels=t;const n=Object.values(this.requests).flat().filter((e=>!!e.accessToken)).map((e=>e.accessToken)).sort(L.compare);if(n&&n.length>0){const e=n.pop();(!this.accessToken||e&&e.isNewerThan(this.accessToken))&&(this.accessToken=e)}return s}addListenersForRequestEvents(e){const t=this.requestListenersAbort[e.identifier]=new AbortController,s=()=>{if(this.removeListenersFromRequestEvents(e),!e.isServiceRequest){if(this.requests[e.client.identifier]){this.lastCompletedRequest[e.client.identifier]=e,delete this.requests[e.client.identifier];const t=this.clientsForInvalidation.indexOf(e.client.identifier);t>0&&(this.clientsForInvalidation.splice(t,1),delete this.clientsPresenceState[e.client.identifier],delete this.lastCompletedRequest[e.client.identifier],delete this.clientsState[e.client.identifier],Object.keys(this.clientsState).length||this.dispatchEvent(new m))}return}const t=this.serviceRequests.indexOf(e);t>=0&&this.serviceRequests.splice(t,1)};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}removeListenersFromRequestEvents(e){this.requestListenersAbort[e.request.identifier]&&(this.requestListenersAbort[e.request.identifier].abort(),delete this.requestListenersAbort[e.request.identifier])}subscriptionStateChanges(e,t){const s=0===this.channelGroups.size&&0===this.channels.size,n={channelGroups:{},channels:{}},i=[],r=[],a=[],o=[];for(const e of t)this.channelGroups.has(e)||r.push(e);for(const t of e)this.channels.has(t)||o.push(t);if(!s){for(const e of this.channelGroups)t.has(e)||i.push(e);for(const t of this.channels)e.has(t)||a.push(t)}return(o.length||a.length)&&(n.channels=Object.assign(Object.assign({},o.length?{added:o}:{}),a.length?{removed:a}:{})),(r.length||i.length)&&(n.channelGroups=Object.assign(Object.assign({},r.length?{added:r}:{}),i.length?{removed:i}:{})),0===Object.keys(n.channelGroups).length&&0===Object.keys(n.channels).length?void 0:n}squashSameClientRequests(e){if(!e.length||1===e.length)return e;const t=e.sort(((e,t)=>e.creationDate-t.creationDate));return Object.values(t.reduce(((e,t)=>(e[t.client.identifier]=t,e)),{}))}attachToServiceRequest(e,t){e.length&&t.length&&[...t].forEach((s=>{for(const n of e){if(s.serviceRequest||!s.isSubsetOf(n)||s.isInitialSubscribe&&!n.isInitialSubscribe)continue;s.serviceRequest=n;const e=t.indexOf(s);t.splice(e,1);break}}))}createAggregatedRequest(e,t,s,n){var i;if(0===e.length)return;let r;"0"===(null!==(i=e[0].request.queryParameters.tt)&&void 0!==i?i:"0")&&Object.keys(this.clientsPresenceState).length&&(r={},e.forEach((e=>{var t;return Object.keys(null!==(t=e.state)&&void 0!==t?t:{}).length&&Object.assign(r,e.state)})),Object.values(this.clientsPresenceState).sort(((e,t)=>e.update-t.update)).forEach((({state:e})=>Object.assign(r,e))));const a=F.fromRequests(e,this.accessToken,s,n,r);this.addListenersForRequestEvents(a),e.forEach((e=>e.serviceRequest=a)),this.serviceRequests.push(a),t.push(a)}}function $(e,t,s,n){return new(s||(s=Promise))((function(i,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function o(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class D extends EventTarget{sendRequest(e,t,s,n){e.handleProcessingStarted(),e.cancellable&&(e.fetchAbortController=new AbortController);const i=e.asFetchRequest;(()=>{$(this,void 0,void 0,(function*(){Promise.race([fetch(i,Object.assign(Object.assign({},e.fetchAbortController?{signal:e.fetchAbortController.signal}:{}),{keepalive:!0})),e.requestTimeoutTimer()]).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>n?n(e):e)).then((e=>{e[0].status>=400?s(i,this.requestProcessingError(void 0,e)):t(i,this.requestProcessingSuccess(e))})).catch((t=>{let n=t;if("string"==typeof t){const e=t.toLowerCase();n=new Error(t),!e.includes("timeout")&&e.includes("cancel")&&(n.name="AbortError")}e.stopRequestTimeoutTimer(),s(i,this.requestProcessingError(n))}))}))})()}requestProcessingSuccess(e){var t;const[s,n]=e,i=n.byteLength>0?n:void 0,r=parseInt(null!==(t=s.headers.get("Content-Length"))&&void 0!==t?t:"0",10),a=s.headers.get("Content-Type"),o={};return s.headers.forEach(((e,t)=>o[t.toLowerCase()]=e.toLowerCase())),{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentLength:r,contentType:a,headers:o,status:s.status,body:i}}}requestProcessingError(e,t){if(t)return Object.assign(Object.assign({},this.requestProcessingSuccess(t)),{type:"request-process-error"});let s="NETWORK_ISSUE",n="Unknown error",i="Error";e&&e instanceof Error&&(n=e.message,i=e.name);const r=n.toLowerCase();return r.includes("timeout")?s="TIMEOUT":("AbortError"===i||r.includes("aborted")||r.includes("cancel"))&&(n="Request aborted",s="ABORTED"),{type:"request-process-error",clientIdentifier:"",identifier:"",url:"",error:{name:i,type:s,message:n}}}encodeString(e){return encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))}}class K extends D{constructor(e){super(),this.clientsManager=e,this.requestsChangeAggregationQueue={},this.clientAbortControllers={},this.subscriptionStates={},this.addEventListenersForClientsManager(e)}requestsChangeAggregationQueueForClient(e){for(const t of Object.keys(this.requestsChangeAggregationQueue)){const{changes:s}=this.requestsChangeAggregationQueue[t];if(Array.from(s).some((t=>t.clientIdentifier===e.identifier)))return[t,s]}return[void 0,new Set]}moveClient(e){const[t,s]=this.requestsChangeAggregationQueueForClient(e);let n=this.subscriptionStateForClient(e);const i=null==n?void 0:n.requestForClient(e);if(!n&&!s.size)return;n&&n.invalidateClient(e);let r=null==i?void 0:i.asIdentifier;if(!r&&s.size){const[e]=s;r=e.request.asIdentifier}if(!r)return;if(i&&(i.serviceRequest=void 0,n.processChanges([new U(e.identifier,i,!0,!1,!0)]),n=this.subscriptionStateForIdentifier(r),i.resetToInitialRequest(),n.processChanges([new U(e.identifier,i,!1,!1)])),!s.size||!this.requestsChangeAggregationQueue[t])return;this.startAggregationTimer(r);const a=this.requestsChangeAggregationQueue[t].changes;U.squashedChanges([...s]).filter((t=>t.clientIdentifier!==e.identifier||t.remove)).forEach(a.delete,a);const{changes:o}=this.requestsChangeAggregationQueue[r];U.squashedChanges([...s]).filter((t=>t.clientIdentifier===e.identifier&&!t.request.completed&&t.request.canceled&&!t.remove)).forEach(o.add,o)}removeClient(e,t,s,n=!1){var i;const[r,a]=this.requestsChangeAggregationQueueForClient(e),o=this.subscriptionStateForClient(e),c=null==o?void 0:o.requestForClient(e,n);if(!o&&!a.size)return;const l=null!==(i=o&&o.identifier)&&void 0!==i?i:r;if(a.size&&this.requestsChangeAggregationQueue[l]){const{changes:e}=this.requestsChangeAggregationQueue[l];a.forEach(e.delete,e),this.stopAggregationTimerIfEmptyQueue(l)}c&&(c.serviceRequest=void 0,t?(this.startAggregationTimer(l),this.enqueueForAggregation(e,c,!0,s,n)):o&&o.processChanges([new U(e.identifier,c,!0,s,n)]))}enqueueForAggregation(e,t,s,n,i=!1){const r=t.asIdentifier;this.startAggregationTimer(r);const{changes:a}=this.requestsChangeAggregationQueue[r];a.add(new U(e.identifier,t,s,n,i))}startAggregationTimer(e){this.requestsChangeAggregationQueue[e]||(this.requestsChangeAggregationQueue[e]={timeout:setTimeout((()=>this.handleDelayedAggregation(e)),50),changes:new Set})}stopAggregationTimerIfEmptyQueue(e){const t=this.requestsChangeAggregationQueue[e];t&&0===t.changes.size&&(t.timeout&&clearTimeout(t.timeout),delete this.requestsChangeAggregationQueue[e])}handleDelayedAggregation(e){if(!this.requestsChangeAggregationQueue[e])return;const t=this.subscriptionStateForIdentifier(e),s=[...this.requestsChangeAggregationQueue[e].changes];delete this.requestsChangeAggregationQueue[e],t.processChanges(s)}subscriptionStateForIdentifier(e){let t=this.subscriptionStates[e];return t||(t=this.subscriptionStates[e]=new G(e),this.addListenerForSubscriptionStateEvents(t)),t}addEventListenersForClientsManager(s){s.addEventListener(t.Registered,(t=>{const{client:s}=t,n=new AbortController;this.clientAbortControllers[s.identifier]=n,s.addEventListener(e.IdentityChange,(e=>{e instanceof o&&(!!e.oldUserId!=!!e.newUserId||e.oldUserId&&e.newUserId&&e.newUserId!==e.oldUserId)&&this.moveClient(s)}),{signal:n.signal}),s.addEventListener(e.AuthChange,(e=>{var t;e instanceof c&&(!!e.oldAuth!=!!e.newAuth||e.oldAuth&&e.newAuth&&!e.oldAuth.equalTo(e.newAuth)?this.moveClient(s):e.oldAuth&&e.newAuth&&e.oldAuth.equalTo(e.newAuth)&&(null===(t=this.subscriptionStateForClient(s))||void 0===t||t.updateClientAccessToken(e.newAuth)))}),{signal:n.signal}),s.addEventListener(e.PresenceStateChange,(e=>{var t;e instanceof h&&(null===(t=this.subscriptionStateForClient(e.client))||void 0===t||t.updateClientPresenceState(e.client,e.state))}),{signal:n.signal}),s.addEventListener(e.SendSubscribeRequest,(e=>{e instanceof u&&this.enqueueForAggregation(e.client,e.request,!1,!1)}),{signal:n.signal}),s.addEventListener(e.CancelSubscribeRequest,(e=>{e instanceof d&&this.enqueueForAggregation(e.client,e.request,!0,!1)}),{signal:n.signal}),s.addEventListener(e.SendLeaveRequest,(e=>{if(!(e instanceof p))return;const t=this.patchedLeaveRequest(e.request);t&&this.sendRequest(t,((e,s)=>t.handleProcessingSuccess(e,s)),((e,s)=>t.handleProcessingError(e,s)))}),{signal:n.signal})})),s.addEventListener(t.Unregistered,(e=>{const{client:t,withLeave:s}=e,n=this.clientAbortControllers[t.identifier];delete this.clientAbortControllers[t.identifier],n&&n.abort(),this.removeClient(t,!1,s,!0)}))}addListenerForSubscriptionStateEvents(e){const t=new AbortController;e.addEventListener(s.Changed,(e=>{const{requestsWithInitialResponse:t,canceledRequests:s,newRequests:n,leaveRequest:i}=e;s.forEach((e=>e.cancel("Cancel request"))),n.forEach((e=>{this.sendRequest(e,((t,s)=>e.handleProcessingSuccess(t,s)),((t,s)=>e.handleProcessingError(t,s)),e.isInitialSubscribe&&"0"!==e.timetokenOverride?t=>this.patchInitialSubscribeResponse(t,e.timetokenOverride,e.timetokenRegionOverride):void 0)})),t.forEach((e=>{const{request:t,timetoken:s,region:n}=e;t.handleProcessingStarted(),this.makeResponseOnHandshakeRequest(t,s,n)})),i&&this.sendRequest(i,((e,t)=>i.handleProcessingSuccess(e,t)),((e,t)=>i.handleProcessingError(e,t)))}),{signal:t.signal}),e.addEventListener(s.Invalidated,(()=>{delete this.subscriptionStates[e.identifier],t.abort()}),{signal:t.signal,once:!0})}subscriptionStateForClient(e){return Object.values(this.subscriptionStates).find((t=>t.hasStateForClient(e)))}patchedLeaveRequest(e){const t=this.subscriptionStateForClient(e.client);if(!t)return void e.cancel();const s=t.uniqueStateForClient(e.client,e.channels,e.channelGroups),n=_(e.client,s.channels,s.channelGroups);return n&&(e.serviceRequest=n),n}makeResponseOnHandshakeRequest(e,t,s){const n=(new TextEncoder).encode(`{"t":{"t":"${t}","r":${null!=s?s:"0"}},"m":[]}`);e.handleProcessingSuccess(e.asFetchRequest,{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentType:'text/javascript; charset="UTF-8"',contentLength:n.length,headers:{"content-type":'text/javascript; charset="UTF-8"',"content-length":`${n.length}`},status:200,body:n}})}patchInitialSubscribeResponse(e,t,s){if(void 0===t||"0"===t||e[0].status>=400)return e;let n;const i=e[0];let r=i,a=e[1];try{n=JSON.parse(K.textDecoder.decode(a))}catch(t){return console.error(`Subscribe response parse error: ${t}`),e}n.t.t=t,s&&(n.t.r=parseInt(s,10));try{if(a=K.textEncoder.encode(JSON.stringify(n)).buffer,a.byteLength){const e=new Headers(i.headers);e.set("Content-Length",`${a.byteLength}`),r=new Response(a,{status:i.status,statusText:i.statusText,headers:e})}}catch(t){return console.error(`Subscribe serialization error: ${t}`),e}return a.byteLength>0?[r,a]:e}}var H,N;K.textDecoder=new TextDecoder,K.textEncoder=new TextEncoder,function(e){e.Heartbeat="heartbeat",e.Invalidated="invalidated"}(H||(H={}));class B extends CustomEvent{constructor(e){super(H.Heartbeat,{detail:e})}get request(){return this.detail}clone(){return new B(this.request)}}class Q extends CustomEvent{constructor(){super(H.Invalidated)}clone(){return new Q}}class W extends P{static fromTransportRequest(e,t,s){return new W(e,t,s)}static fromCachedState(e,t,s,n,i,r){if(n.length||s.length){const t=e.path.split("/");t[6]=n.length?[...n].sort().join(","):",",e.path=t.join("/")}return s.length&&(e.queryParameters["channel-group"]=[...s].sort().join(",")),i&&Object.keys(i).length?e.queryParameters.state=JSON.stringify(i):delete e.queryParameters.state,r&&(e.queryParameters.auth=r.toString()),e.identifier=O.createUUID(),new W(e,t,r)}constructor(e,t,s){const n=W.channelGroupsFromRequest(e).filter((e=>!e.endsWith("-pnpres"))),i=W.channelsFromRequest(e).filter((e=>!e.endsWith("-pnpres")));if(super(e,t,e.queryParameters.uuid,i,n,s),!e.queryParameters.state||0===e.queryParameters.state.length)return;const r=JSON.parse(e.queryParameters.state);for(const e of Object.keys(r))this.channels.includes(e)||this.channelGroups.includes(e)||delete r[e];this.state=r}get asIdentifier(){const e=this.accessToken?this.accessToken.asIdentifier:void 0;return`${this.userId}-${this.subscribeKey}${e?`-${e}`:""}`}toString(){return`HeartbeatRequest { channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}] }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[6];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}}class M extends EventTarget{constructor(e){super(),this.identifier=e,this.clientsState={},this.clientsPresenceState={},this.requests={},this.lastHeartbeatTimestamp=0,this.canSendBackupHeartbeat=!0,this.isAccessDeniedError=!1,this._interval=0}set interval(e){const t=this._interval!==e;this._interval=e,t&&(0===e?this.stopTimer():this.startTimer())}set accessToken(e){if(!e)return void(this._accessToken=e);const t=Object.values(this.requests).filter((e=>!!e.accessToken)).map((e=>e.accessToken));t.push(e);const s=t.sort(L.compare).pop();(!this._accessToken||s&&s.isNewerThan(this._accessToken))&&(this._accessToken=s),this.isAccessDeniedError&&(this.canSendBackupHeartbeat=!0,this.startTimer(this.presenceTimerTimeout()))}stateForClient(e){if(!this.clientsState[e.identifier])return;const t=this.clientsState[e.identifier];return t?{channels:[...t.channels],channelGroups:[...t.channelGroups],state:t.state}:{channels:[],channelGroups:[]}}requestForClient(e){return this.requests[e.identifier]}addClientRequest(e,t){this.requests[e.identifier]=t,this.clientsState[e.identifier]={channels:t.channels,channelGroups:t.channelGroups},t.state&&(this.clientsState[e.identifier].state=Object.assign({},t.state));const s=this.clientsPresenceState[e.identifier],n=s?Object.keys(s.state):[];s&&n.length&&(n.forEach((e=>{t.channels.includes(e)||t.channelGroups.includes(e)||delete s.state[e]})),0===Object.keys(s.state).length&&delete this.clientsPresenceState[e.identifier]);const i=Object.values(this.requests).filter((e=>!!e.accessToken)).map((e=>e.accessToken)).sort(L.compare);if(i&&i.length>0){const e=i.pop();(!this._accessToken||e&&e.isNewerThan(this._accessToken))&&(this._accessToken=e)}this.sendAggregatedHeartbeat(t)}removeClient(e){delete this.clientsPresenceState[e.identifier],delete this.clientsState[e.identifier],delete this.requests[e.identifier],Object.keys(this.clientsState).length||(this.stopTimer(),this.dispatchEvent(new Q))}removeFromClientState(e,t,s){const n=this.clientsPresenceState[e.identifier],i=this.clientsState[e.identifier];i&&(i.channelGroups=i.channelGroups.filter((e=>!s.includes(e))),i.channels=i.channels.filter((e=>!t.includes(e))),n&&Object.keys(n.state).length&&(s.forEach((e=>delete n.state[e])),t.forEach((e=>delete n.state[e])),0===Object.keys(n.state).length&&delete this.clientsPresenceState[e.identifier]),0!==i.channels.length||0!==i.channelGroups.length?i.state&&Object.keys(i.state).forEach((e=>{i.channels.includes(e)||i.channelGroups.includes(e)||delete i.state[e]})):this.removeClient(e))}updateClientPresenceState(e,t){const s=this.clientsPresenceState[e.identifier];null!=t||(t={}),s?(Object.assign(s.state,t),s.update=Date.now()):this.clientsPresenceState[e.identifier]={update:Date.now(),state:t}}startTimer(e){this.stopTimer(),0!==Object.keys(this.clientsState).length&&(this.timeout=setTimeout((()=>this.handlePresenceTimer()),1e3*(null!=e?e:this._interval)))}stopTimer(){this.timeout&&clearTimeout(this.timeout),this.timeout=void 0}sendAggregatedHeartbeat(e){if(0!==this.lastHeartbeatTimestamp){const t=this.lastHeartbeatTimestamp+1e3*this._interval;let s=.05*this._interval;this._interval-s<3&&(s=0);if(t-Date.now()>1e3*s){if(e&&this.previousRequestResult){const t=e.asFetchRequest,s=Object.assign(Object.assign({},this.previousRequestResult),{clientIdentifier:e.client.identifier,identifier:e.identifier,url:t.url});return e.handleProcessingStarted(),void e.handleProcessingSuccess(t,s)}if(!e)return}}const t=Object.values(this.requests),s=t[Math.floor(Math.random()*t.length)],n=Object.assign({},s.request),i={},r=new Set,a=new Set;Object.entries(this.clientsState).forEach((([e,t])=>{t.state&&Object.assign(i,t.state),t.channelGroups.forEach(r.add,r),t.channels.forEach(a.add,a)})),Object.keys(this.clientsPresenceState).length&&Object.values(this.clientsPresenceState).sort(((e,t)=>e.update-t.update)).forEach((({state:e})=>Object.assign(i,e))),this.lastHeartbeatTimestamp=Date.now();const o=W.fromCachedState(n,t[0].subscribeKey,[...r],[...a],Object.keys(i).length>0?i:void 0,this._accessToken);Object.values(this.requests).forEach((e=>!e.serviceRequest&&(e.serviceRequest=o))),this.addListenersForRequest(o),this.dispatchEvent(new B(o)),e&&this.startTimer()}addListenersForRequest(e){const t=new AbortController,s=e=>{if(t.abort(),e instanceof C){const{response:t}=e;this.previousRequestResult=t}else if(e instanceof R){const{error:t}=e;this.canSendBackupHeartbeat=!0,this.isAccessDeniedError=!1,t.response&&t.response.status>=400&&t.response.status<500&&(this.isAccessDeniedError=403===t.response.status,this.canSendBackupHeartbeat=!1)}};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}handlePresenceTimer(){if(0===Object.keys(this.clientsState).length||!this.canSendBackupHeartbeat)return;const e=this.presenceTimerTimeout();this.sendAggregatedHeartbeat(),this.startTimer(e)}presenceTimerTimeout(){const e=(Date.now()-this.lastHeartbeatTimestamp)/1e3;let t=this._interval;return e0&&e.heartbeatInterval>0&&e.heartbeatInterval{const{client:s}=t,n=new AbortController;this.clientAbortControllers[s.identifier]=n,s.addEventListener(e.Disconnect,(()=>this.removeClient(s)),{signal:n.signal}),s.addEventListener(e.IdentityChange,(e=>{if(e instanceof o&&(!!e.oldUserId!=!!e.newUserId||e.oldUserId&&e.newUserId&&e.newUserId!==e.oldUserId)){const t=this.heartbeatStateForClient(s),n=t?t.requestForClient(s):void 0;n&&(n.userId=e.newUserId),this.moveClient(s)}}),{signal:n.signal}),s.addEventListener(e.AuthChange,(e=>{if(!(e instanceof c))return;const t=this.heartbeatStateForClient(s),n=t?t.requestForClient(s):void 0;n&&(n.accessToken=e.newAuth),!!e.oldAuth!=!!e.newAuth||e.oldAuth&&e.newAuth&&!e.newAuth.equalTo(e.oldAuth)?this.moveClient(s):t&&e.oldAuth&&e.newAuth&&e.oldAuth.equalTo(e.newAuth)&&(t.accessToken=e.newAuth)}),{signal:n.signal}),s.addEventListener(e.HeartbeatIntervalChange,(e=>{var t;const n=e,i=this.heartbeatStateForClient(s);i&&(i.interval=null!==(t=n.newInterval)&&void 0!==t?t:0)}),{signal:n.signal}),s.addEventListener(e.PresenceStateChange,(e=>{var t;e instanceof h&&(null===(t=this.heartbeatStateForClient(e.client))||void 0===t||t.updateClientPresenceState(e.client,e.state))}),{signal:n.signal}),s.addEventListener(e.SendHeartbeatRequest,(e=>this.addClient(s,e.request)),{signal:n.signal}),s.addEventListener(e.SendLeaveRequest,(e=>{const{request:t}=e,n=this.heartbeatStateForClient(s);n&&n.removeFromClientState(s,t.channels,t.channelGroups)}),{signal:n.signal})})),s.addEventListener(t.Unregistered,(e=>{const{client:t}=e,s=this.clientAbortControllers[t.identifier];delete this.clientAbortControllers[t.identifier],s&&s.abort(),this.removeClient(t)}))}addListenerForHeartbeatStateEvents(e){const t=new AbortController;e.addEventListener(H.Heartbeat,(e=>{const{request:t}=e;this.sendRequest(t,((e,s)=>t.handleProcessingSuccess(e,s)),((e,s)=>t.handleProcessingError(e,s)))}),{signal:t.signal}),e.addEventListener(H.Invalidated,(()=>{delete this.heartbeatStates[e.identifier],t.abort()}),{signal:t.signal,once:!0})}}z.textDecoder=new TextDecoder,function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(N||(N={}));class J{constructor(e,t){this.minLogLevel=e,this.port=t}debug(e){this.log(e,N.Debug)}error(e){this.log(e,N.Error)}info(e){this.log(e,N.Info)}trace(e){this.log(e,N.Trace)}warn(e){this.log(e,N.Warn)}log(e,t){if(t{"client-unregister"===e.data.type?this.handleUnregisterEvent():"client-update"===e.data.type?this.handleConfigurationUpdateEvent(e.data):"client-presence-state-update"===e.data.type?this.handlePresenceStateUpdateEvent(e.data):"send-request"===e.data.type?this.handleSendRequestEvent(e.data):"cancel-request"===e.data.type?this.handleCancelRequestEvent(e.data):"client-disconnect"===e.data.type?this.handleDisconnectEvent():"client-pong"===e.data.type&&this.handlePongEvent()}),{signal:this.listenerAbortController.signal})}handleUnregisterEvent(){this.invalidate(),this.dispatchEvent(new r(this))}handleConfigurationUpdateEvent(e){const{userId:t,accessToken:s,preProcessedToken:n,heartbeatInterval:i,workerLogLevel:r}=e;if(this.logger.minLogLevel=r,this.logger.debug((()=>({messageType:"object",message:{userId:t,authKey:s,token:n,heartbeatInterval:i,workerLogLevel:r},details:"Update client configuration with parameters:"}))),s||this.accessToken){const e=s?new L(s,(null!=n?n:{}).token,(null!=n?n:{}).expiration):void 0;if(!!e!=!!this.accessToken||e&&this.accessToken&&!e.equalTo(this.accessToken,!0)){const t=this._accessToken;this._accessToken=e,Object.values(this.requests).filter((e=>!e.completed&&e instanceof F||e instanceof W)).forEach((t=>t.accessToken=e)),this.dispatchEvent(new c(this,e,t))}}if(this.userId!==t){const e=this.userId;this.userId=t,Object.values(this.requests).filter((e=>!e.completed&&e instanceof F||e instanceof W)).forEach((e=>e.userId=t)),this.dispatchEvent(new o(this,e,t))}if(this._heartbeatInterval!==i){const e=this._heartbeatInterval;this._heartbeatInterval=i,this.dispatchEvent(new l(this,i,e))}}handlePresenceStateUpdateEvent(e){this.dispatchEvent(new h(this,e.state))}handleSendRequestEvent(e){var t;let s;if(!this._accessToken&&(null===(t=e.request.queryParameters)||void 0===t?void 0:t.auth)&&e.preProcessedToken){const t=e.request.queryParameters.auth;this._accessToken=new L(t,e.preProcessedToken.token,e.preProcessedToken.expiration)}e.request.path.startsWith("/v2/subscribe")?F.useCachedState(e.request)&&(this.cachedSubscriptionChannelGroups.length||this.cachedSubscriptionChannels.length)?s=F.fromCachedState(e.request,this.subKey,this.cachedSubscriptionChannelGroups,this.cachedSubscriptionChannels,this.cachedSubscriptionState,this.accessToken):(s=F.fromTransportRequest(e.request,this.subKey,this.accessToken),this.cachedSubscriptionChannelGroups=[...s.channelGroups],this.cachedSubscriptionChannels=[...s.channels],s.state?this.cachedSubscriptionState=Object.assign({},s.state):this.cachedSubscriptionState=void 0):s=e.request.path.endsWith("/heartbeat")?W.fromTransportRequest(e.request,this.subKey,this.accessToken):j.fromTransportRequest(e.request,this.subKey,this.accessToken),s.client=this,this.requests[s.request.identifier]=s,this._origin||(this._origin=s.origin),this.listenRequestCompletion(s),this.dispatchEvent(this.eventWithRequest(s))}handleCancelRequestEvent(e){if(!this.requests[e.identifier])return;this.requests[e.identifier].cancel("Cancel request")}handleDisconnectEvent(){this.dispatchEvent(new a(this))}handlePongEvent(){this._lastPongEvent=Date.now()/1e3}listenRequestCompletion(e){const t=new AbortController,s=s=>{delete this.requests[e.identifier],t.abort(),s instanceof C?this.postEvent(s.response):s instanceof R?this.postEvent(s.error):s instanceof E&&(this.postEvent(this.requestCancelError(e)),!this._invalidated&&e instanceof F&&this.dispatchEvent(new d(e.client,e)))};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}cancelRequests(){Object.values(this.requests).forEach((e=>e.cancel()))}eventWithRequest(e){let t;return t=e instanceof F?new u(this,e):e instanceof W?new g(this,e):new p(this,e),t}requestCancelError(e){return{type:"request-process-error",clientIdentifier:this.identifier,identifier:e.request.identifier,url:e.asFetchRequest.url,error:{name:"AbortError",type:"ABORTED",message:"Request aborted"}}}}class X extends EventTarget{constructor(e){super(),this.sharedWorkerIdentifier=e,this.timeouts={},this.clients={},this.clientBySubscribeKey={}}createClient(e,t){var s;if(this.clients[e.clientIdentifier])return this.clients[e.clientIdentifier];const n=new V(e.clientIdentifier,e.subscriptionKey,e.userId,t,e.workerLogLevel,e.heartbeatInterval);return this.registerClient(n),e.workerOfflineClientsCheckInterval&&this.startClientTimeoutCheck(e.subscriptionKey,e.workerOfflineClientsCheckInterval,null!==(s=e.workerUnsubscribeOfflineClients)&&void 0!==s&&s),n}registerClient(e){this.clients[e.identifier]={client:e,abortController:new AbortController},this.clientBySubscribeKey[e.subKey]?this.clientBySubscribeKey[e.subKey].push(e):this.clientBySubscribeKey[e.subKey]=[e],this.forEachClient(e.subKey,(t=>t.logger.debug(`'${e.identifier}' client registered with '${this.sharedWorkerIdentifier}' shared worker (${this.clientBySubscribeKey[e.subKey].length} active clients).`))),this.subscribeOnClientEvents(e),this.dispatchEvent(new f(e))}unregisterClient(e,t=!1,s=!1){if(!this.clients[e.identifier])return;this.clients[e.identifier].abortController&&this.clients[e.identifier].abortController.abort(),delete this.clients[e.identifier];const n=this.clientBySubscribeKey[e.subKey];if(n){const t=n.indexOf(e);n.splice(t,1),0===n.length&&(delete this.clientBySubscribeKey[e.subKey],this.stopClientTimeoutCheck(e))}this.forEachClient(e.subKey,(t=>t.logger.debug(`'${this.sharedWorkerIdentifier}' shared worker unregistered '${e.identifier}' client (${this.clientBySubscribeKey[e.subKey].length} active clients).`))),s||e.invalidate(),this.dispatchEvent(new q(e,t))}startClientTimeoutCheck(e,t,s){this.timeouts[e]||(this.forEachClient(e,(e=>e.logger.debug(`Setup PubNub client ping for every ${t} seconds.`))),this.timeouts[e]={interval:t,unsubscribeOffline:s,timeout:setTimeout((()=>this.handleTimeoutCheck(e)),500*t-1)})}stopClientTimeoutCheck(e){this.timeouts[e.subKey]&&(this.timeouts[e.subKey].timeout&&clearTimeout(this.timeouts[e.subKey].timeout),delete this.timeouts[e.subKey])}handleTimeoutCheck(e){if(!this.timeouts[e])return;const t=this.timeouts[e].interval;[...this.clientBySubscribeKey[e]].forEach((s=>{s.lastPingRequest&&Date.now()/1e3-s.lastPingRequest-.2>.5*t&&(s.logger.warn("PubNub clients timeout timer fired after throttling past due time."),s.lastPingRequest=void 0),s.lastPingRequest&&(!s.lastPongEvent||Math.abs(s.lastPongEvent-s.lastPingRequest)>t)&&(this.unregisterClient(s,this.timeouts[e].unsubscribeOffline),this.forEachClient(e,(e=>{e.identifier!==s.identifier&&e.logger.debug(`'${s.identifier}' client is inactive. Invalidating...`)}))),this.clients[s.identifier]&&(s.lastPingRequest=Date.now()/1e3,s.postEvent({type:"shared-worker-ping"}))})),this.timeouts[e]&&(this.timeouts[e].timeout=setTimeout((()=>this.handleTimeoutCheck(e)),500*t))}subscribeOnClientEvents(t){t.addEventListener(e.Unregister,(()=>this.unregisterClient(t,!!this.timeouts[t.subKey]&&this.timeouts[t.subKey].unsubscribeOffline,!0)),{signal:this.clients[t.identifier].abortController.signal,once:!0})}forEachClient(e,t){this.clientBySubscribeKey[e]&&this.clientBySubscribeKey[e].forEach(t)}}const Y=new X(O.createUUID());new K(Y),new z(Y),self.onconnect=e=>{e.ports.forEach((e=>{e.start(),e.onmessage=t=>{const s=t.data;"client-register"===s.type&&Y.createClient(s,e)},e.postMessage({type:"shared-worker-connected"})}))}})); +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */T=k,function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function i(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=i,n.VERSION=t,e.uuid=n,e.isUUID=i}(w=k.exports),null!==T&&(T.exports=w.uuid);var I,A=y(k.exports),P={createUUID:()=>A.uuid?A.uuid():A()};class O extends EventTarget{constructor(e,t,s,n,i,r){super(),this.request=e,this.subscribeKey=t,this.channels=n,this.channelGroups=i,this.dependents={},this._completed=!1,this._canceled=!1,this.queryStringFromObject=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${this.encodeString(e)}`)).join("&"):`${t}=${this.encodeString(s)}`})).join("&"),this._accessToken=r,this._userId=s}get identifier(){return this.request.identifier}get origin(){return this.request.origin}get userId(){return this._userId}set userId(e){this._userId=e,this.request.queryParameters.uuid=e}get accessToken(){return this._accessToken}set accessToken(e){this._accessToken=e,e?this.request.queryParameters.auth=e.toString():delete this.request.queryParameters.auth}get client(){return this._client}set client(e){this._client=e}get completed(){return this._completed}get cancellable(){return this.request.cancellable}get canceled(){return this._canceled}set fetchAbortController(e){this.completed||this.canceled||(this.isServiceRequest?this._fetchAbortController?console.error("Only one abort controller can be set for service-provided requests."):this._fetchAbortController=e:console.error("Unexpected attempt to set fetch abort controller on client-provided request."))}get fetchAbortController(){return this._fetchAbortController}get asFetchRequest(){const e=this.request.queryParameters,t={};let s="";if(this.request.headers)for(const[e,s]of Object.entries(this.request.headers))t[e]=s;return e&&0!==Object.keys(e).length&&(s=`?${this.queryStringFromObject(e)}`),new Request(`${this.origin}${this.request.path}${s}`,{method:this.request.method,headers:Object.keys(t).length?t:void 0,redirect:"follow"})}get serviceRequest(){return this._serviceRequest}set serviceRequest(e){if(this.isServiceRequest)return void console.error("Unexpected attempt to set service-provided request on service-provided request.");const t=this.serviceRequest;this._serviceRequest=e,!t||e&&t.identifier===e.identifier||t.detachRequest(this),this.completed||this.canceled||e&&(e.completed||e.canceled)?this._serviceRequest=void 0:t&&e&&t.identifier===e.identifier||e&&e.attachRequest(this)}get isServiceRequest(){return!this.client}dependentRequests(){return this.isServiceRequest?Object.values(this.dependents):[]}attachRequest(e){this.isServiceRequest&&!this.dependents[e.identifier]?(this.dependents[e.identifier]=e,this.addEventListenersForRequest(e)):this.isServiceRequest||console.error("Unexpected attempt to attach requests using client-provided request.")}detachRequest(e){this.isServiceRequest&&this.dependents[e.identifier]?(delete this.dependents[e.identifier],e.removeEventListenersFromRequest(),0===Object.keys(this.dependents).length&&this.cancel("Cancel request")):this.isServiceRequest||console.error("Unexpected attempt to detach requests using client-provided request.")}cancel(e,t=!1){if(this.completed||this.canceled)return[];const s=this.dependentRequests();return this.isServiceRequest?(t||s.forEach((e=>e.serviceRequest=void 0)),this._fetchAbortController&&(this._fetchAbortController.abort(e),this._fetchAbortController=void 0)):this.serviceRequest=void 0,this._canceled=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new E(this)),s}requestTimeoutTimer(){return new Promise(((e,t)=>{this._fetchTimeoutTimer=setTimeout((()=>{t(new Error("Request timeout")),this.cancel("Cancel because of timeout",!0)}),1e3*this.request.timeout)}))}stopRequestTimeoutTimer(){this._fetchTimeoutTimer&&(clearTimeout(this._fetchTimeoutTimer),this._fetchTimeoutTimer=void 0)}handleProcessingStarted(){this.logRequestStart(this),this.dispatchEvent(new S(this))}handleProcessingSuccess(e,t){this.addRequestInformationForResult(this,e,t),this.logRequestSuccess(this,t),this._completed=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new C(this,e,t))}handleProcessingError(e,t){this.addRequestInformationForResult(this,e,t),this.logRequestError(this,t),this._completed=!0,this.stopRequestTimeoutTimer(),this.dispatchEvent(new R(this,e,t))}addEventListenersForRequest(e){this.isServiceRequest?(e.abortController=new AbortController,this.addEventListener(n.Started,(t=>{t instanceof S&&(e.logRequestStart(t.request),e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0}),this.addEventListener(n.Success,(t=>{t instanceof C&&(e.removeEventListenersFromRequest(),e.addRequestInformationForResult(t.request,t.fetchRequest,t.response),e.logRequestSuccess(t.request,t.response),e._completed=!0,e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0}),this.addEventListener(n.Error,(t=>{t instanceof R&&(e.removeEventListenersFromRequest(),e.addRequestInformationForResult(t.request,t.fetchRequest,t.error),e.logRequestError(t.request,t.error),e._completed=!0,e.dispatchEvent(t.clone(e)))}),{signal:e.abortController.signal,once:!0})):console.error("Unexpected attempt to add listeners using a client-provided request.")}removeEventListenersFromRequest(){!this.isServiceRequest&&this.abortController?(this.abortController.abort(),this.abortController=void 0):this.isServiceRequest&&console.error("Unexpected attempt to remove listeners using a client-provided request.")}hasAnyChannelsOrGroups(e,t){return this.channels.some((t=>e.includes(t)))||this.channelGroups.some((e=>t.includes(e)))}addRequestInformationForResult(e,t,s){this.isServiceRequest||(s.clientIdentifier=this.client.identifier,s.identifier=this.identifier,s.url=t.url)}logRequestStart(e){this.isServiceRequest||this.client.logger.debug((()=>({messageType:"network-request",message:e.request})))}logRequestSuccess(e,t){this.isServiceRequest||this.client.logger.debug((()=>{const{status:s,headers:n,body:i}=t.response,r=e.asFetchRequest;return Object.entries(n).forEach((([e,t])=>t)),{messageType:"network-response",message:{status:s,url:r.url,headers:n,body:i}}}))}logRequestError(e,t){this.isServiceRequest||((t.error?t.error.message:"Unknown").toLowerCase().includes("timeout")?this.client.logger.debug((()=>({messageType:"network-request",message:e.request,details:"Timeout",canceled:!0}))):this.client.logger.warn((()=>{const{details:s,canceled:n}=this.errorDetailsFromSendingError(t);let i=s;return n?i="Aborted":s.toLowerCase().includes("network")&&(i="Network error"),{messageType:"network-request",message:e.request,details:i,canceled:n,failed:!n}})))}errorDetailsFromSendingError(e){const t=!!e.error&&("TIMEOUT"===e.error.type||"ABORTED"===e.error.type);let s=e.error?e.error.message:"Unknown";if(e.response){const t=e.response.headers["content-type"];if(e.response.body&&t&&(-1!==t.indexOf("javascript")||-1!==t.indexOf("json")))try{const t=JSON.parse((new TextDecoder).decode(e.response.body));"message"in t?s=t.message:"error"in t&&("string"==typeof t.error?s=t.error:"object"==typeof t.error&&"message"in t.error&&(s=t.error.message))}catch(e){}"Unknown"===s&&(s=e.response.status>=500?"Internal Server Error":400==e.response.status?"Bad request":403==e.response.status?"Access denied":`${e.response.status}`)}return{details:s,canceled:t}}encodeString(e){return encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))}}class F extends O{static fromTransportRequest(e,t,s){return new F(e,t,s)}static fromCachedState(e,t,s,n,i,r){return new F(e,t,r,s,n,i)}static fromRequests(e,t,s,n,i){var r;const a=e[Math.floor(Math.random()*e.length)],o="0"===(null!==(r=a.request.queryParameters.tt)&&void 0!==r?r:"0"),c=o&&null!=i?i:{},l=Object.assign({},a.request),h=new Set,u=new Set;for(const t of e)o&&!i&&t.state&&Object.assign(c,t.state),t.channelGroups.forEach(h.add,h),t.channels.forEach(u.add,u);if(u.size||h.size){const e=l.path.split("/");e[4]=u.size?[...u].sort().join(","):",",l.path=e.join("/")}h.size&&(l.queryParameters["channel-group"]=[...h].sort().join(",")),Object.keys(c).length?l.queryParameters.state=JSON.stringify(c):delete l.queryParameters.state,t&&(l.queryParameters.auth=t.toString()),l.identifier=P.createUUID();const d=new F(l,a.subscribeKey,t,[...h],[...u],c);for(const t of e)t.serviceRequest=d;return d.isInitialSubscribe&&s&&"0"!==s&&(d.timetokenOverride=s,n&&(d.timetokenRegionOverride=n)),d}constructor(e,t,s,n,i,r){var a;const o=!!e.queryParameters&&"on-demand"in e.queryParameters;if(delete e.queryParameters["on-demand"],super(e,t,e.queryParameters.uuid,null!=i?i:F.channelsFromRequest(e),null!=n?n:F.channelGroupsFromRequest(e),s),this._creationDate=Date.now(),this.timetokenRegionOverride="0",this._creationDate<=F.lastCreationDate?(F.lastCreationDate++,this._creationDate=F.lastCreationDate):F.lastCreationDate=this._creationDate,this._requireCachedStateReset=o,e.queryParameters["filter-expr"]&&(this.filterExpression=e.queryParameters["filter-expr"]),this._timetoken=null!==(a=e.queryParameters.tt)&&void 0!==a?a:"0","0"===this._timetoken&&(delete e.queryParameters.tt,delete e.queryParameters.tr),e.queryParameters.tr&&(this._region=e.queryParameters.tr),r&&(this.state=r),this.state||!e.queryParameters.state||e.queryParameters.state.length<=2||"0"!==this._timetoken)return;const c=JSON.parse(e.queryParameters.state);for(const e of Object.keys(c))this.channels.includes(e)||this.channelGroups.includes(e)||delete c[e];this.state=c}get creationDate(){return this._creationDate}get asIdentifier(){const e=this.accessToken?this.accessToken.asIdentifier:void 0,t=`${this.userId}-${this.subscribeKey}${e?`-${e}`:""}`;return this.filterExpression?`${t}-${this.filterExpression}`:t}get isInitialSubscribe(){return"0"===this._timetoken}get timetoken(){return this._timetoken}set timetoken(e){this._timetoken=e,this.request.queryParameters.tt=e}get region(){return this._region}set region(e){this._region=e,e?this.request.queryParameters.tr=e:delete this.request.queryParameters.tr}get requireCachedStateReset(){return this._requireCachedStateReset}static useCachedState(e){return!!e.queryParameters&&!("on-demand"in e.queryParameters)}resetToInitialRequest(){this._requireCachedStateReset=!0,this._timetoken="0",this._region=void 0,delete this.request.queryParameters.tt}isSubsetOf(e){return!(e.channelGroups.length&&!this.includesStrings(e.channelGroups,this.channelGroups))&&(!(e.channels.length&&!this.includesStrings(e.channels,this.channels))&&("0"===this.timetoken||this.timetoken===e.timetoken||"0"===e.timetoken))}toString(){return`SubscribeRequest { clientIdentifier: ${this.client?this.client.identifier:"service request"}, requestIdentifier: ${this.identifier}, serviceRequestIdentified: ${this.client?this.serviceRequest?this.serviceRequest.identifier:"'not set'":"'is service request"}, channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}], timetoken: ${this.timetoken}, region: ${this.region}, reset: ${this._requireCachedStateReset?"'reset'":"'do not reset'"} }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[4];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}includesStrings(e,t){const s=new Set(e);return t.every(s.has,s)}}F.lastCreationDate=0;class L{static compare(e,t){var s,n;return(null!==(s=e.expiration)&&void 0!==s?s:0)-(null!==(n=t.expiration)&&void 0!==n?n:0)}constructor(e,t,s){this.token=e,this.simplifiedToken=t,this.expiration=s}get asIdentifier(){var e;return null!==(e=this.simplifiedToken)&&void 0!==e?e:this.token}equalTo(e,t=!1){return this.asIdentifier===e.asIdentifier&&(!t||this.expiration===e.expiration)}isNewerThan(e){return!!this.simplifiedToken&&this.expiration>e.expiration}toString(){return this.token}}!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.PUT="PUT",e.DELETE="DELETE",e.LOCAL="LOCAL"}(I||(I={}));class j extends O{static fromTransportRequest(e,t,s){return new j(e,t,s)}constructor(e,t,s){const n=j.channelGroupsFromRequest(e),i=j.channelsFromRequest(e),r=n.filter((e=>!e.endsWith("-pnpres"))),a=i.filter((e=>!e.endsWith("-pnpres")));super(e,t,e.queryParameters.uuid,a,r,s),this.allChannelGroups=n,this.allChannels=i}toString(){return`LeaveRequest { channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}] }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[6];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}}const _=(e,t,s)=>{if(t=t.filter((e=>!e.endsWith("-pnpres"))).map((e=>x(e))).sort(),s=s.filter((e=>!e.endsWith("-pnpres"))).map((e=>x(e))).sort(),0===t.length&&0===s.length)return;const n=s.length>0?s.join(","):void 0,i=0===t.length?",":t.join(","),r=Object.assign(Object.assign({instanceid:e.identifier,uuid:e.userId,requestid:P.createUUID()},e.accessToken?{auth:e.accessToken.toString()}:{}),n?{"channel-group":n}:{}),a={origin:e.origin,path:`/v2/presence/sub-key/${e.subKey}/channel/${i}/leave`,queryParameters:r,method:I.GET,headers:{},timeout:10,cancellable:!1,compressible:!1,identifier:r.requestid};return j.fromTransportRequest(a,e.subKey,e.accessToken)},x=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`));class U{static squashedChanges(e){if(!e.length||1===e.length)return e;const t=e.sort(((e,t)=>e.timestamp-t.timestamp)),s=t.filter((e=>!e.remove));s.forEach((e=>{for(let n=0;n{if(n[e.clientIdentifier]){const s=t.indexOf(e);s>=0&&t.splice(s,1)}n[e.clientIdentifier]=e})),t}constructor(e,t,s,n,i=!1){this.clientIdentifier=e,this.request=t,this.remove=s,this.sendLeave=n,this.clientInvalidate=i,this._timestamp=this.timestampForChange()}get timestamp(){return this._timestamp}toString(){return`SubscriptionStateChange { timestamp: ${this.timestamp}, client: ${this.clientIdentifier}, request: ${this.request.toString()}, remove: ${this.remove?"'remove'":"'do not remove'"}, sendLeave: ${this.sendLeave?"'send'":"'do not send'"} }`}toJSON(){return this.toString()}timestampForChange(){const e=Date.now();return e<=U.previousChangeTimestamp?U.previousChangeTimestamp++:U.previousChangeTimestamp=e,U.previousChangeTimestamp}}U.previousChangeTimestamp=0;class G extends EventTarget{constructor(e){super(),this.identifier=e,this.requestListenersAbort={},this.clientsState={},this.clientsPresenceState={},this.lastCompletedRequest={},this.clientsForInvalidation=[],this.requests={},this.serviceRequests=[],this.channelGroups=new Set,this.channels=new Set}hasStateForClient(e){return!!this.clientsState[e.identifier]}uniqueStateForClient(e,t,s){let n=[...s],i=[...t];return Object.entries(this.clientsState).forEach((([t,s])=>{t!==e.identifier&&(n=n.filter((e=>!s.channelGroups.has(e))),i=i.filter((e=>!s.channels.has(e))))})),{channels:i,channelGroups:n}}requestForClient(e,t=!1){var s;return null!==(s=this.requests[e.identifier])&&void 0!==s?s:t?this.lastCompletedRequest[e.identifier]:void 0}updateClientAccessToken(e){this.accessToken&&!e.isNewerThan(this.accessToken)||(this.accessToken=e)}updateClientPresenceState(e,t){const s=this.clientsPresenceState[e.identifier];null!=t||(t={}),s?(Object.assign(s.state,t),s.update=Date.now()):this.clientsPresenceState[e.identifier]={update:Date.now(),state:t}}invalidateClient(e){this.clientsForInvalidation.includes(e.identifier)||this.clientsForInvalidation.push(e.identifier)}processChanges(e){if(e.length&&(e=U.squashedChanges(e)),!e.length)return;let t=0===this.channelGroups.size&&0===this.channels.size;t||(t=e.some((e=>e.remove||e.request.requireCachedStateReset)));const s=this.applyChanges(e);let n;t&&(n=this.refreshInternalState()),this.handleSubscriptionStateChange(e,n,s.initial,s.continuation,s.removed),Object.keys(this.clientsState).length||this.dispatchEvent(new m)}applyChanges(e){const t=[],s=[],n=[];return e.forEach((e=>{const{remove:i,request:r,clientIdentifier:a,clientInvalidate:o}=e;i||(r.isInitialSubscribe?s.push(r):t.push(r),this.requests[a]=r,this.addListenersForRequestEvents(r)),i&&(this.requests[a]||this.lastCompletedRequest[a])&&(o&&(delete this.clientsPresenceState[a],delete this.lastCompletedRequest[a],delete this.clientsState[a]),delete this.requests[a],n.push(r))})),{initial:s,continuation:t,removed:n}}handleSubscriptionStateChange(e,t,s,n,i){var r,a,o,c;const l=this.serviceRequests.filter((e=>!e.completed&&!e.canceled)),h=[],u=[],d=[],g=[];let p,f,q,m;const b=e=>{g.push(e);const t=e.dependentRequests().filter((e=>!i.includes(e)));0!==t.length&&(t.forEach((e=>e.serviceRequest=void 0)),(e.isInitialSubscribe?s:n).push(...t))};if(t)if(t.channels.added||t.channelGroups.added){for(const e of l)b(e);l.length=0}else if(t.channels.removed||t.channelGroups.removed){const e=null!==(r=t.channelGroups.removed)&&void 0!==r?r:[],s=null!==(a=t.channels.removed)&&void 0!==a?a:[];for(let t=l.length-1;t>=0;t--){const n=l[t];n.hasAnyChannelsOrGroups(s,e)&&(b(n),l.splice(t,1))}}n=this.squashSameClientRequests(n),((s=this.squashSameClientRequests(s)).length?n:[]).forEach((e=>{let t=!m;t||"0"===e.timetoken||("0"===m?t=!0:e.timetokenf)),t&&(f=e.creationDate,m=e.timetoken,q=e.region)}));const S={};n.forEach((e=>{S[e.timetoken]?S[e.timetoken].push(e):S[e.timetoken]=[e]})),this.attachToServiceRequest(l,s);for(let e=s.length-1;e>=0;e--){const t=s[e];l.forEach((n=>{if(!t.isSubsetOf(n)||n.isInitialSubscribe)return;const{region:i,timetoken:r}=n;h.push({request:t,timetoken:r,region:i}),s.splice(e,1)}))}if(s.length){let e;if(n.length){m=Object.keys(S).sort().pop();const t=S[m];q=t[0].region,delete S[m],t.forEach((e=>e.resetToInitialRequest())),e=[...s,...t]}else e=s;this.createAggregatedRequest(e,d,m,q)}Object.values(S).forEach((e=>{this.attachToServiceRequest(d,e),this.attachToServiceRequest(l,e),this.createAggregatedRequest(e,u)}));const C=new Set,R=new Set;if(t&&i.length&&(t.channels.removed||t.channelGroups.removed)){const s=null!==(o=t.channelGroups.removed)&&void 0!==o?o:[],n=null!==(c=t.channels.removed)&&void 0!==c?c:[],r=i[0].client;e.filter((e=>e.remove&&e.sendLeave)).forEach((e=>{const{channels:t,channelGroups:i}=e.request;s.forEach((e=>i.includes(e)&&C.add(e))),n.forEach((e=>t.includes(e)&&R.add(e)))})),p=_(r,[...R],[...C])}(h.length||d.length||u.length||g.length||p)&&this.dispatchEvent(new v(h,[...d,...u],g,p))}refreshInternalState(){const e=new Set,t=new Set;Object.entries(this.requests).forEach((([s,n])=>{var i,r;const a=this.clientsPresenceState[s],o=a?Object.keys(a.state):[],c=null!==(i=(r=this.clientsState)[s])&&void 0!==i?i:r[s]={channels:new Set,channelGroups:new Set};n.channelGroups.forEach((t=>{c.channelGroups.add(t),e.add(t)})),n.channels.forEach((e=>{c.channels.add(e),t.add(e)})),a&&o.length&&(o.forEach((e=>{n.channels.includes(e)||n.channelGroups.includes(e)||delete a.state[e]})),0===Object.keys(a.state).length&&delete this.clientsPresenceState[s])}));const s=this.subscriptionStateChanges(t,e);this.channelGroups=e,this.channels=t;const n=Object.values(this.requests).flat().filter((e=>!!e.accessToken)).map((e=>e.accessToken)).sort(L.compare);if(n&&n.length>0){const e=n.pop();(!this.accessToken||e&&e.isNewerThan(this.accessToken))&&(this.accessToken=e)}return s}addListenersForRequestEvents(e){const t=this.requestListenersAbort[e.identifier]=new AbortController,s=()=>{if(this.removeListenersFromRequestEvents(e),!e.isServiceRequest){if(this.requests[e.client.identifier]){this.lastCompletedRequest[e.client.identifier]=e,delete this.requests[e.client.identifier];const t=this.clientsForInvalidation.indexOf(e.client.identifier);t>0&&(this.clientsForInvalidation.splice(t,1),delete this.clientsPresenceState[e.client.identifier],delete this.lastCompletedRequest[e.client.identifier],delete this.clientsState[e.client.identifier],Object.keys(this.clientsState).length||this.dispatchEvent(new m))}return}const t=this.serviceRequests.indexOf(e);t>=0&&this.serviceRequests.splice(t,1)};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}removeListenersFromRequestEvents(e){this.requestListenersAbort[e.request.identifier]&&(this.requestListenersAbort[e.request.identifier].abort(),delete this.requestListenersAbort[e.request.identifier])}subscriptionStateChanges(e,t){const s=0===this.channelGroups.size&&0===this.channels.size,n={channelGroups:{},channels:{}},i=[],r=[],a=[],o=[];for(const e of t)this.channelGroups.has(e)||r.push(e);for(const t of e)this.channels.has(t)||o.push(t);if(!s){for(const e of this.channelGroups)t.has(e)||i.push(e);for(const t of this.channels)e.has(t)||a.push(t)}return(o.length||a.length)&&(n.channels=Object.assign(Object.assign({},o.length?{added:o}:{}),a.length?{removed:a}:{})),(r.length||i.length)&&(n.channelGroups=Object.assign(Object.assign({},r.length?{added:r}:{}),i.length?{removed:i}:{})),0===Object.keys(n.channelGroups).length&&0===Object.keys(n.channels).length?void 0:n}squashSameClientRequests(e){if(!e.length||1===e.length)return e;const t=e.sort(((e,t)=>e.creationDate-t.creationDate));return Object.values(t.reduce(((e,t)=>(e[t.client.identifier]=t,e)),{}))}attachToServiceRequest(e,t){e.length&&t.length&&[...t].forEach((s=>{for(const n of e){if(s.serviceRequest||!s.isSubsetOf(n)||s.isInitialSubscribe&&!n.isInitialSubscribe)continue;s.serviceRequest=n;const e=t.indexOf(s);t.splice(e,1);break}}))}createAggregatedRequest(e,t,s,n){var i;if(0===e.length)return;let r;"0"===(null!==(i=e[0].request.queryParameters.tt)&&void 0!==i?i:"0")&&Object.keys(this.clientsPresenceState).length&&(r={},e.forEach((e=>{var t;return Object.keys(null!==(t=e.state)&&void 0!==t?t:{}).length&&Object.assign(r,e.state)})),Object.values(this.clientsPresenceState).sort(((e,t)=>e.update-t.update)).forEach((({state:e})=>Object.assign(r,e))));const a=F.fromRequests(e,this.accessToken,s,n,r);this.addListenersForRequestEvents(a),e.forEach((e=>e.serviceRequest=a)),this.serviceRequests.push(a),t.push(a)}}function $(e,t,s,n){return new(s||(s=Promise))((function(i,r){function a(e){try{c(n.next(e))}catch(e){r(e)}}function o(e){try{c(n.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?i(e.value):(t=e.value,t instanceof s?t:new s((function(e){e(t)}))).then(a,o)}c((n=n.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class D extends EventTarget{sendRequest(e,t,s,n){e.handleProcessingStarted(),e.cancellable&&(e.fetchAbortController=new AbortController);const i=e.asFetchRequest;(()=>{$(this,void 0,void 0,(function*(){Promise.race([fetch(i,Object.assign(Object.assign({},e.fetchAbortController?{signal:e.fetchAbortController.signal}:{}),{keepalive:!0})),e.requestTimeoutTimer()]).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>n?n(e):e)).then((e=>{e[0].status>=400?s(i,this.requestProcessingError(void 0,e)):t(i,this.requestProcessingSuccess(e))})).catch((t=>{let n=t;if("string"==typeof t){const e=t.toLowerCase();n=new Error(t),!e.includes("timeout")&&e.includes("cancel")&&(n.name="AbortError")}e.stopRequestTimeoutTimer(),s(i,this.requestProcessingError(n))}))}))})()}requestProcessingSuccess(e){var t;const[s,n]=e,i=n.byteLength>0?n:void 0,r=parseInt(null!==(t=s.headers.get("Content-Length"))&&void 0!==t?t:"0",10),a=s.headers.get("Content-Type"),o={};return s.headers.forEach(((e,t)=>o[t.toLowerCase()]=e.toLowerCase())),{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentLength:r,contentType:a,headers:o,status:s.status,body:i}}}requestProcessingError(e,t){if(t)return Object.assign(Object.assign({},this.requestProcessingSuccess(t)),{type:"request-process-error"});let s="NETWORK_ISSUE",n="Unknown error",i="Error";e&&e instanceof Error&&(n=e.message,i=e.name);const r=n.toLowerCase();return r.includes("timeout")?s="TIMEOUT":("AbortError"===i||r.includes("aborted")||r.includes("cancel"))&&(n="Request aborted",s="ABORTED"),{type:"request-process-error",clientIdentifier:"",identifier:"",url:"",error:{name:i,type:s,message:n}}}encodeString(e){return encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`))}}class K extends D{constructor(e){super(),this.clientsManager=e,this.requestsChangeAggregationQueue={},this.clientAbortControllers={},this.subscriptionStates={},this.addEventListenersForClientsManager(e)}requestsChangeAggregationQueueForClient(e){for(const t of Object.keys(this.requestsChangeAggregationQueue)){const{changes:s}=this.requestsChangeAggregationQueue[t];if(Array.from(s).some((t=>t.clientIdentifier===e.identifier)))return[t,s]}return[void 0,new Set]}moveClient(e){const[t,s]=this.requestsChangeAggregationQueueForClient(e);let n=this.subscriptionStateForClient(e);const i=null==n?void 0:n.requestForClient(e);if(!n&&!s.size)return;n&&n.invalidateClient(e);let r=null==i?void 0:i.asIdentifier;if(!r&&s.size){const[e]=s;r=e.request.asIdentifier}if(!r)return;if(i&&(i.serviceRequest=void 0,n.processChanges([new U(e.identifier,i,!0,!1,!0)]),n=this.subscriptionStateForIdentifier(r),i.resetToInitialRequest(),n.processChanges([new U(e.identifier,i,!1,!1)])),!s.size||!this.requestsChangeAggregationQueue[t])return;this.startAggregationTimer(r);const a=this.requestsChangeAggregationQueue[t].changes;U.squashedChanges([...s]).filter((t=>t.clientIdentifier!==e.identifier||t.remove)).forEach(a.delete,a);const{changes:o}=this.requestsChangeAggregationQueue[r];U.squashedChanges([...s]).filter((t=>t.clientIdentifier===e.identifier&&!t.request.completed&&t.request.canceled&&!t.remove)).forEach(o.add,o)}removeClient(e,t,s,n=!1){var i;const[r,a]=this.requestsChangeAggregationQueueForClient(e),o=this.subscriptionStateForClient(e),c=null==o?void 0:o.requestForClient(e,n);if(!o&&!a.size)return;const l=null!==(i=o&&o.identifier)&&void 0!==i?i:r;if(a.size&&this.requestsChangeAggregationQueue[l]){const{changes:e}=this.requestsChangeAggregationQueue[l];a.forEach(e.delete,e),this.stopAggregationTimerIfEmptyQueue(l)}c&&(c.serviceRequest=void 0,t?(this.startAggregationTimer(l),this.enqueueForAggregation(e,c,!0,s,n)):o&&o.processChanges([new U(e.identifier,c,!0,s,n)]))}enqueueForAggregation(e,t,s,n,i=!1){const r=t.asIdentifier;this.startAggregationTimer(r);const{changes:a}=this.requestsChangeAggregationQueue[r];a.add(new U(e.identifier,t,s,n,i))}startAggregationTimer(e){this.requestsChangeAggregationQueue[e]||(this.requestsChangeAggregationQueue[e]={timeout:setTimeout((()=>this.handleDelayedAggregation(e)),50),changes:new Set})}stopAggregationTimerIfEmptyQueue(e){const t=this.requestsChangeAggregationQueue[e];t&&0===t.changes.size&&(t.timeout&&clearTimeout(t.timeout),delete this.requestsChangeAggregationQueue[e])}handleDelayedAggregation(e){if(!this.requestsChangeAggregationQueue[e])return;const t=this.subscriptionStateForIdentifier(e),s=[...this.requestsChangeAggregationQueue[e].changes];delete this.requestsChangeAggregationQueue[e],t.processChanges(s)}subscriptionStateForIdentifier(e){let t=this.subscriptionStates[e];return t||(t=this.subscriptionStates[e]=new G(e),this.addListenerForSubscriptionStateEvents(t)),t}addEventListenersForClientsManager(s){s.addEventListener(t.Registered,(t=>{const{client:s}=t,n=new AbortController;this.clientAbortControllers[s.identifier]=n,s.addEventListener(e.IdentityChange,(e=>{e instanceof o&&(!!e.oldUserId!=!!e.newUserId||e.oldUserId&&e.newUserId&&e.newUserId!==e.oldUserId)&&this.moveClient(s)}),{signal:n.signal}),s.addEventListener(e.AuthChange,(e=>{var t;e instanceof c&&(!!e.oldAuth!=!!e.newAuth||e.oldAuth&&e.newAuth&&!e.oldAuth.equalTo(e.newAuth)?this.moveClient(s):e.oldAuth&&e.newAuth&&e.oldAuth.equalTo(e.newAuth)&&(null===(t=this.subscriptionStateForClient(s))||void 0===t||t.updateClientAccessToken(e.newAuth)))}),{signal:n.signal}),s.addEventListener(e.PresenceStateChange,(e=>{var t;e instanceof h&&(null===(t=this.subscriptionStateForClient(e.client))||void 0===t||t.updateClientPresenceState(e.client,e.state))}),{signal:n.signal}),s.addEventListener(e.SendSubscribeRequest,(e=>{e instanceof u&&this.enqueueForAggregation(e.client,e.request,!1,!1)}),{signal:n.signal}),s.addEventListener(e.CancelSubscribeRequest,(e=>{e instanceof d&&this.enqueueForAggregation(e.client,e.request,!0,!1)}),{signal:n.signal}),s.addEventListener(e.SendLeaveRequest,(e=>{if(!(e instanceof p))return;const t=this.patchedLeaveRequest(e.request);t&&this.sendRequest(t,((e,s)=>t.handleProcessingSuccess(e,s)),((e,s)=>t.handleProcessingError(e,s)))}),{signal:n.signal})})),s.addEventListener(t.Unregistered,(e=>{const{client:t,withLeave:s}=e,n=this.clientAbortControllers[t.identifier];delete this.clientAbortControllers[t.identifier],n&&n.abort(),this.removeClient(t,!1,s,!0)}))}addListenerForSubscriptionStateEvents(e){const t=new AbortController;e.addEventListener(s.Changed,(e=>{const{requestsWithInitialResponse:t,canceledRequests:s,newRequests:n,leaveRequest:i}=e;s.forEach((e=>e.cancel("Cancel request"))),n.forEach((e=>{this.sendRequest(e,((t,s)=>e.handleProcessingSuccess(t,s)),((t,s)=>e.handleProcessingError(t,s)),e.isInitialSubscribe&&"0"!==e.timetokenOverride?t=>this.patchInitialSubscribeResponse(t,e.timetokenOverride,e.timetokenRegionOverride):void 0)})),t.forEach((e=>{const{request:t,timetoken:s,region:n}=e;t.handleProcessingStarted(),this.makeResponseOnHandshakeRequest(t,s,n)})),i&&this.sendRequest(i,((e,t)=>i.handleProcessingSuccess(e,t)),((e,t)=>i.handleProcessingError(e,t)))}),{signal:t.signal}),e.addEventListener(s.Invalidated,(()=>{delete this.subscriptionStates[e.identifier],t.abort()}),{signal:t.signal,once:!0})}subscriptionStateForClient(e){return Object.values(this.subscriptionStates).find((t=>t.hasStateForClient(e)))}patchedLeaveRequest(e){const t=this.subscriptionStateForClient(e.client);if(!t)return void e.cancel();const s=t.uniqueStateForClient(e.client,e.channels,e.channelGroups),n=_(e.client,s.channels,s.channelGroups);return n&&(e.serviceRequest=n),n}makeResponseOnHandshakeRequest(e,t,s){const n=(new TextEncoder).encode(`{"t":{"t":"${t}","r":${null!=s?s:"0"}},"m":[]}`);e.handleProcessingSuccess(e.asFetchRequest,{type:"request-process-success",clientIdentifier:"",identifier:"",url:"",response:{contentType:'text/javascript; charset="UTF-8"',contentLength:n.length,headers:{"content-type":'text/javascript; charset="UTF-8"',"content-length":`${n.length}`},status:200,body:n}})}patchInitialSubscribeResponse(e,t,s){if(void 0===t||"0"===t||e[0].status>=400)return e;let n;const i=e[0];let r=i,a=e[1];try{n=JSON.parse(K.textDecoder.decode(a))}catch(t){return console.error(`Subscribe response parse error: ${t}`),e}n.t.t=t,s&&(n.t.r=parseInt(s,10));try{if(a=K.textEncoder.encode(JSON.stringify(n)).buffer,a.byteLength){const e=new Headers(i.headers);e.set("Content-Length",`${a.byteLength}`),r=new Response(a,{status:i.status,statusText:i.statusText,headers:e})}}catch(t){return console.error(`Subscribe serialization error: ${t}`),e}return a.byteLength>0?[r,a]:e}}var H,N;K.textDecoder=new TextDecoder,K.textEncoder=new TextEncoder,function(e){e.Heartbeat="heartbeat",e.Invalidated="invalidated"}(H||(H={}));class B extends CustomEvent{constructor(e){super(H.Heartbeat,{detail:e})}get request(){return this.detail}clone(){return new B(this.request)}}class Q extends CustomEvent{constructor(){super(H.Invalidated)}clone(){return new Q}}class W extends O{static fromTransportRequest(e,t,s){return new W(e,t,s)}static fromCachedState(e,t,s,n,i,r){if(n.length||s.length){const t=e.path.split("/");t[6]=n.length?[...n].sort().join(","):",",e.path=t.join("/")}return s.length&&(e.queryParameters["channel-group"]=[...s].sort().join(",")),i&&Object.keys(i).length?e.queryParameters.state=JSON.stringify(i):delete e.queryParameters.state,r&&(e.queryParameters.auth=r.toString()),e.identifier=P.createUUID(),new W(e,t,r)}constructor(e,t,s){const n=W.channelGroupsFromRequest(e).filter((e=>!e.endsWith("-pnpres"))),i=W.channelsFromRequest(e).filter((e=>!e.endsWith("-pnpres")));if(super(e,t,e.queryParameters.uuid,i,n,s),!e.queryParameters.state||0===e.queryParameters.state.length)return;const r=JSON.parse(e.queryParameters.state);for(const e of Object.keys(r))this.channels.includes(e)||this.channelGroups.includes(e)||delete r[e];this.state=r}get asIdentifier(){const e=this.accessToken?this.accessToken.asIdentifier:void 0;return`${this.userId}-${this.subscribeKey}${e?`-${e}`:""}`}toString(){return`HeartbeatRequest { channels: [${this.channels.length?this.channels.map((e=>`'${e}'`)).join(", "):""}], channelGroups: [${this.channelGroups.length?this.channelGroups.map((e=>`'${e}'`)).join(", "):""}] }`}toJSON(){return this.toString()}static channelsFromRequest(e){const t=e.path.split("/")[6];return","===t?[]:t.split(",").filter((e=>e.length>0))}static channelGroupsFromRequest(e){if(!e.queryParameters||!e.queryParameters["channel-group"])return[];const t=e.queryParameters["channel-group"];return 0===t.length?[]:t.split(",").filter((e=>e.length>0))}}class M extends EventTarget{constructor(e){super(),this.identifier=e,this.clientsState={},this.clientsPresenceState={},this.requests={},this.lastHeartbeatTimestamp=0,this.canSendBackupHeartbeat=!0,this.isAccessDeniedError=!1,this._interval=0}set interval(e){const t=this._interval!==e;this._interval=e,t&&(0===e?this.stopTimer():this.startTimer())}set accessToken(e){if(!e)return void(this._accessToken=e);const t=Object.values(this.requests).filter((e=>!!e.accessToken)).map((e=>e.accessToken));t.push(e);const s=t.sort(L.compare).pop();(!this._accessToken||s&&s.isNewerThan(this._accessToken))&&(this._accessToken=s),this.isAccessDeniedError&&(this.canSendBackupHeartbeat=!0,this.startTimer(this.presenceTimerTimeout()))}stateForClient(e){if(!this.clientsState[e.identifier])return;const t=this.clientsState[e.identifier];return t?{channels:[...t.channels],channelGroups:[...t.channelGroups],state:t.state}:{channels:[],channelGroups:[]}}requestForClient(e){return this.requests[e.identifier]}addClientRequest(e,t){this.requests[e.identifier]=t,this.clientsState[e.identifier]={channels:t.channels,channelGroups:t.channelGroups},t.state&&(this.clientsState[e.identifier].state=Object.assign({},t.state));const s=this.clientsPresenceState[e.identifier],n=s?Object.keys(s.state):[];s&&n.length&&(n.forEach((e=>{t.channels.includes(e)||t.channelGroups.includes(e)||delete s.state[e]})),0===Object.keys(s.state).length&&delete this.clientsPresenceState[e.identifier]);const i=Object.values(this.requests).filter((e=>!!e.accessToken)).map((e=>e.accessToken)).sort(L.compare);if(i&&i.length>0){const e=i.pop();(!this._accessToken||e&&e.isNewerThan(this._accessToken))&&(this._accessToken=e)}this.sendAggregatedHeartbeat(t)}removeClient(e){delete this.clientsPresenceState[e.identifier],delete this.clientsState[e.identifier],delete this.requests[e.identifier],Object.keys(this.clientsState).length||(this.stopTimer(),this.dispatchEvent(new Q))}removeFromClientState(e,t,s){const n=this.clientsPresenceState[e.identifier],i=this.clientsState[e.identifier];i&&(i.channelGroups=i.channelGroups.filter((e=>!s.includes(e))),i.channels=i.channels.filter((e=>!t.includes(e))),n&&Object.keys(n.state).length&&(s.forEach((e=>delete n.state[e])),t.forEach((e=>delete n.state[e])),0===Object.keys(n.state).length&&delete this.clientsPresenceState[e.identifier]),0!==i.channels.length||0!==i.channelGroups.length?i.state&&Object.keys(i.state).forEach((e=>{i.channels.includes(e)||i.channelGroups.includes(e)||delete i.state[e]})):this.removeClient(e))}updateClientPresenceState(e,t){const s=this.clientsPresenceState[e.identifier];null!=t||(t={}),s?(Object.assign(s.state,t),s.update=Date.now()):this.clientsPresenceState[e.identifier]={update:Date.now(),state:t}}startTimer(e){this.stopTimer(),0!==Object.keys(this.clientsState).length&&(this.timeout=setTimeout((()=>this.handlePresenceTimer()),1e3*(null!=e?e:this._interval)))}stopTimer(){this.timeout&&clearTimeout(this.timeout),this.timeout=void 0}sendAggregatedHeartbeat(e){if(0!==this.lastHeartbeatTimestamp){const t=this.lastHeartbeatTimestamp+1e3*this._interval;let s=.05*this._interval;this._interval-s<3&&(s=0);if(t-Date.now()>1e3*s){if(e&&this.previousRequestResult){const t=e.asFetchRequest,s=Object.assign(Object.assign({},this.previousRequestResult),{clientIdentifier:e.client.identifier,identifier:e.identifier,url:t.url});return e.handleProcessingStarted(),void e.handleProcessingSuccess(t,s)}if(!e)return}}const t=Object.values(this.requests),s=t[Math.floor(Math.random()*t.length)],n=Object.assign({},s.request),i={},r=new Set,a=new Set;Object.entries(this.clientsState).forEach((([e,t])=>{t.state&&Object.assign(i,t.state),t.channelGroups.forEach(r.add,r),t.channels.forEach(a.add,a)})),Object.keys(this.clientsPresenceState).length&&Object.values(this.clientsPresenceState).sort(((e,t)=>e.update-t.update)).forEach((({state:e})=>Object.assign(i,e))),this.lastHeartbeatTimestamp=Date.now();const o=W.fromCachedState(n,t[0].subscribeKey,[...r],[...a],Object.keys(i).length>0?i:void 0,this._accessToken);Object.values(this.requests).forEach((e=>!e.serviceRequest&&(e.serviceRequest=o))),this.addListenersForRequest(o),this.dispatchEvent(new B(o)),e&&this.startTimer()}addListenersForRequest(e){const t=new AbortController,s=e=>{if(t.abort(),e instanceof C){const{response:t}=e;this.previousRequestResult=t}else if(e instanceof R){const{error:t}=e;this.canSendBackupHeartbeat=!0,this.isAccessDeniedError=!1,t.response&&t.response.status>=400&&t.response.status<500&&(this.isAccessDeniedError=403===t.response.status,this.canSendBackupHeartbeat=!1)}};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}handlePresenceTimer(){if(0===Object.keys(this.clientsState).length||!this.canSendBackupHeartbeat)return;const e=this.presenceTimerTimeout();this.sendAggregatedHeartbeat(),this.startTimer(e)}presenceTimerTimeout(){const e=(Date.now()-this.lastHeartbeatTimestamp)/1e3;let t=this._interval;return e0&&e.heartbeatInterval>0&&e.heartbeatInterval{const{client:s}=t,n=new AbortController;this.clientAbortControllers[s.identifier]=n,s.addEventListener(e.Disconnect,(()=>this.removeClient(s)),{signal:n.signal}),s.addEventListener(e.IdentityChange,(e=>{if(e instanceof o&&(!!e.oldUserId!=!!e.newUserId||e.oldUserId&&e.newUserId&&e.newUserId!==e.oldUserId)){const t=this.heartbeatStateForClient(s),n=t?t.requestForClient(s):void 0;n&&(n.userId=e.newUserId),this.moveClient(s)}}),{signal:n.signal}),s.addEventListener(e.AuthChange,(e=>{if(!(e instanceof c))return;const t=this.heartbeatStateForClient(s),n=t?t.requestForClient(s):void 0;n&&(n.accessToken=e.newAuth),!!e.oldAuth!=!!e.newAuth||e.oldAuth&&e.newAuth&&!e.newAuth.equalTo(e.oldAuth)?this.moveClient(s):t&&e.oldAuth&&e.newAuth&&e.oldAuth.equalTo(e.newAuth)&&(t.accessToken=e.newAuth)}),{signal:n.signal}),s.addEventListener(e.HeartbeatIntervalChange,(e=>{var t;const n=e,i=this.heartbeatStateForClient(s);i&&(i.interval=null!==(t=n.newInterval)&&void 0!==t?t:0)}),{signal:n.signal}),s.addEventListener(e.PresenceStateChange,(e=>{var t;e instanceof h&&(null===(t=this.heartbeatStateForClient(e.client))||void 0===t||t.updateClientPresenceState(e.client,e.state))}),{signal:n.signal}),s.addEventListener(e.SendHeartbeatRequest,(e=>this.addClient(s,e.request)),{signal:n.signal}),s.addEventListener(e.SendLeaveRequest,(e=>{const{request:t}=e,n=this.heartbeatStateForClient(s);n&&n.removeFromClientState(s,t.channels,t.channelGroups)}),{signal:n.signal})})),s.addEventListener(t.Unregistered,(e=>{const{client:t}=e,s=this.clientAbortControllers[t.identifier];delete this.clientAbortControllers[t.identifier],s&&s.abort(),this.removeClient(t)}))}addListenerForHeartbeatStateEvents(e){const t=new AbortController;e.addEventListener(H.Heartbeat,(e=>{const{request:t}=e;this.sendRequest(t,((e,s)=>t.handleProcessingSuccess(e,s)),((e,s)=>t.handleProcessingError(e,s)))}),{signal:t.signal}),e.addEventListener(H.Invalidated,(()=>{delete this.heartbeatStates[e.identifier],t.abort()}),{signal:t.signal,once:!0})}}z.textDecoder=new TextDecoder,function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(N||(N={}));class J{constructor(e,t){this.minLogLevel=e,this.port=t}debug(e){this.log(e,N.Debug)}error(e){this.log(e,N.Error)}info(e){this.log(e,N.Info)}trace(e){this.log(e,N.Trace)}warn(e){this.log(e,N.Warn)}log(e,t){if(t{"client-unregister"===e.data.type?this.handleUnregisterEvent():"client-update"===e.data.type?this.handleConfigurationUpdateEvent(e.data):"client-presence-state-update"===e.data.type?this.handlePresenceStateUpdateEvent(e.data):"send-request"===e.data.type?this.handleSendRequestEvent(e.data):"cancel-request"===e.data.type?this.handleCancelRequestEvent(e.data):"client-disconnect"===e.data.type?this.handleDisconnectEvent():"client-pong"===e.data.type&&this.handlePongEvent()}),{signal:this.listenerAbortController.signal})}handleUnregisterEvent(){this.invalidate(),this.dispatchEvent(new r(this))}handleConfigurationUpdateEvent(e){const{userId:t,accessToken:s,preProcessedToken:n,heartbeatInterval:i,workerLogLevel:r}=e;if(this.logger.minLogLevel=r,this.logger.debug((()=>({messageType:"object",message:{userId:t,authKey:s,token:n,heartbeatInterval:i,workerLogLevel:r},details:"Update client configuration with parameters:"}))),s||this.accessToken){const e=s?new L(s,(null!=n?n:{}).token,(null!=n?n:{}).expiration):void 0;if(!!e!=!!this.accessToken||e&&this.accessToken&&!e.equalTo(this.accessToken,!0)){const t=this._accessToken;this._accessToken=e,Object.values(this.requests).filter((e=>!e.completed&&e instanceof F||e instanceof W)).forEach((t=>t.accessToken=e)),this.dispatchEvent(new c(this,e,t))}}if(this.userId!==t){const e=this.userId;this.userId=t,Object.values(this.requests).filter((e=>!e.completed&&e instanceof F||e instanceof W)).forEach((e=>e.userId=t)),this.dispatchEvent(new o(this,e,t))}if(this._heartbeatInterval!==i){const e=this._heartbeatInterval;this._heartbeatInterval=i,this.dispatchEvent(new l(this,i,e))}}handlePresenceStateUpdateEvent(e){this.dispatchEvent(new h(this,e.state))}handleSendRequestEvent(e){var t;let s;if(!this._accessToken&&(null===(t=e.request.queryParameters)||void 0===t?void 0:t.auth)&&e.preProcessedToken){const t=e.request.queryParameters.auth;this._accessToken=new L(t,e.preProcessedToken.token,e.preProcessedToken.expiration)}e.request.path.startsWith("/v2/subscribe")?F.useCachedState(e.request)&&(this.cachedSubscriptionChannelGroups.length||this.cachedSubscriptionChannels.length)?s=F.fromCachedState(e.request,this.subKey,this.cachedSubscriptionChannelGroups,this.cachedSubscriptionChannels,this.cachedSubscriptionState,this.accessToken):(s=F.fromTransportRequest(e.request,this.subKey,this.accessToken),this.cachedSubscriptionChannelGroups=[...s.channelGroups],this.cachedSubscriptionChannels=[...s.channels],s.state?this.cachedSubscriptionState=Object.assign({},s.state):this.cachedSubscriptionState=void 0):s=e.request.path.endsWith("/heartbeat")?W.fromTransportRequest(e.request,this.subKey,this.accessToken):j.fromTransportRequest(e.request,this.subKey,this.accessToken),s.client=this,this.requests[s.request.identifier]=s,this._origin||(this._origin=s.origin),this.listenRequestCompletion(s),this.dispatchEvent(this.eventWithRequest(s))}handleCancelRequestEvent(e){if(!this.requests[e.identifier])return;this.requests[e.identifier].cancel("Cancel request")}handleDisconnectEvent(){this.dispatchEvent(new a(this))}handlePongEvent(){this._lastPongEvent=Date.now()/1e3}listenRequestCompletion(e){const t=new AbortController,s=s=>{delete this.requests[e.identifier],t.abort(),s instanceof C?this.postEvent(s.response):s instanceof R?this.postEvent(s.error):s instanceof E&&(this.postEvent(this.requestCancelError(e)),!this._invalidated&&e instanceof F&&this.dispatchEvent(new d(e.client,e)))};e.addEventListener(n.Success,s,{signal:t.signal,once:!0}),e.addEventListener(n.Error,s,{signal:t.signal,once:!0}),e.addEventListener(n.Canceled,s,{signal:t.signal,once:!0})}cancelRequests(){Object.values(this.requests).forEach((e=>e.cancel()))}eventWithRequest(e){let t;return t=e instanceof F?new u(this,e):e instanceof W?new g(this,e):new p(this,e),t}requestCancelError(e){return{type:"request-process-error",clientIdentifier:this.identifier,identifier:e.request.identifier,url:e.asFetchRequest.url,error:{name:"AbortError",type:"ABORTED",message:"Request aborted"}}}}class X extends EventTarget{constructor(e){super(),this.sharedWorkerIdentifier=e,this.timeouts={},this.clients={},this.clientBySubscribeKey={}}createClient(e,t){var s;if(this.clients[e.clientIdentifier])return this.clients[e.clientIdentifier];const n=new V(e.clientIdentifier,e.subscriptionKey,e.userId,t,e.workerLogLevel,e.heartbeatInterval);return this.registerClient(n),e.workerOfflineClientsCheckInterval&&this.startClientTimeoutCheck(e.subscriptionKey,e.workerOfflineClientsCheckInterval,null!==(s=e.workerUnsubscribeOfflineClients)&&void 0!==s&&s),n}registerClient(e){this.clients[e.identifier]={client:e,abortController:new AbortController},this.clientBySubscribeKey[e.subKey]?this.clientBySubscribeKey[e.subKey].push(e):this.clientBySubscribeKey[e.subKey]=[e],this.forEachClient(e.subKey,(t=>t.logger.debug(`'${e.identifier}' client registered with '${this.sharedWorkerIdentifier}' shared worker (${this.clientBySubscribeKey[e.subKey].length} active clients).`))),this.subscribeOnClientEvents(e),this.dispatchEvent(new f(e))}unregisterClient(e,t=!1,s=!1){if(!this.clients[e.identifier])return;this.clients[e.identifier].abortController&&this.clients[e.identifier].abortController.abort(),delete this.clients[e.identifier];const n=this.clientBySubscribeKey[e.subKey];if(n){const t=n.indexOf(e);n.splice(t,1),0===n.length&&(delete this.clientBySubscribeKey[e.subKey],this.stopClientTimeoutCheck(e))}this.forEachClient(e.subKey,(t=>t.logger.debug(`'${this.sharedWorkerIdentifier}' shared worker unregistered '${e.identifier}' client (${this.clientBySubscribeKey[e.subKey].length} active clients).`))),s||e.invalidate(),this.dispatchEvent(new q(e,t))}startClientTimeoutCheck(e,t,s){this.timeouts[e]||(this.forEachClient(e,(e=>e.logger.debug(`Setup PubNub client ping for every ${t} seconds.`))),this.timeouts[e]={interval:t,unsubscribeOffline:s,timeout:setTimeout((()=>this.handleTimeoutCheck(e)),500*t-1)})}stopClientTimeoutCheck(e){this.timeouts[e.subKey]&&(this.timeouts[e.subKey].timeout&&clearTimeout(this.timeouts[e.subKey].timeout),delete this.timeouts[e.subKey])}handleTimeoutCheck(e){if(!this.timeouts[e])return;const t=this.timeouts[e].interval;[...this.clientBySubscribeKey[e]].forEach((s=>{s.lastPingRequest&&Date.now()/1e3-s.lastPingRequest-.2>.5*t&&(s.logger.warn("PubNub clients timeout timer fired after throttling past due time."),s.lastPingRequest=void 0),s.lastPingRequest&&(!s.lastPongEvent||Math.abs(s.lastPongEvent-s.lastPingRequest)>t)&&(this.unregisterClient(s,this.timeouts[e].unsubscribeOffline),this.forEachClient(e,(e=>{e.identifier!==s.identifier&&e.logger.debug(`'${s.identifier}' client is inactive. Invalidating...`)}))),this.clients[s.identifier]&&(s.lastPingRequest=Date.now()/1e3,s.postEvent({type:"shared-worker-ping"}))})),this.timeouts[e]&&(this.timeouts[e].timeout=setTimeout((()=>this.handleTimeoutCheck(e)),500*t))}subscribeOnClientEvents(t){t.addEventListener(e.Unregister,(()=>this.unregisterClient(t,!!this.timeouts[t.subKey]&&this.timeouts[t.subKey].unsubscribeOffline,!0)),{signal:this.clients[t.identifier].abortController.signal,once:!0})}forEachClient(e,t){this.clientBySubscribeKey[e]&&this.clientBySubscribeKey[e].forEach(t)}}const Y=new X(P.createUUID());new K(Y),new z(Y),self.onconnect=e=>{e.ports.forEach((e=>{e.start(),e.onmessage=t=>{const s=t.data;"client-register"===s.type&&Y.createClient(s,e)},e.postMessage({type:"shared-worker-connected"})}))}})); diff --git a/lib/core/components/request.js b/lib/core/components/request.js index 009611791..a3d38f3af 100644 --- a/lib/core/components/request.js +++ b/lib/core/components/request.js @@ -116,7 +116,9 @@ class AbstractRequest { if (headers) request.headers = headers; // Attach body (if required). - if (request.method === transport_request_1.TransportMethod.POST || request.method === transport_request_1.TransportMethod.PATCH) { + if (request.method === transport_request_1.TransportMethod.POST || + request.method === transport_request_1.TransportMethod.PATCH || + request.method === transport_request_1.TransportMethod.PUT) { const [body, formData] = [this.body, this.formData]; if (formData) request.formData = formData; diff --git a/lib/core/constants/operations.js b/lib/core/constants/operations.js index 120c312a9..204fd25a1 100644 --- a/lib/core/constants/operations.js +++ b/lib/core/constants/operations.js @@ -145,6 +145,57 @@ var RequestOperation; */ RequestOperation["PNSetMembershipsOperation"] = "PNSetMembershipsOperation"; // -------------------------------------------------------- + // ------------------- DataSync API ---------------------- + // -------------------------------------------------------- + /** + * Create entity REST API operation. + */ + RequestOperation["PNCreateEntityOperation"] = "PNCreateEntityOperation"; + /** + * Get entity REST API operation. + */ + RequestOperation["PNGetEntityOperation"] = "PNGetEntityOperation"; + /** + * Get all entities REST API operation. + */ + RequestOperation["PNGetAllEntitiesOperation"] = "PNGetAllEntitiesOperation"; + /** + * Update entity REST API operation. + */ + RequestOperation["PNUpdateEntityOperation"] = "PNUpdateEntityOperation"; + /** + * Patch entity REST API operation. + */ + RequestOperation["PNPatchEntityOperation"] = "PNPatchEntityOperation"; + /** + * Remove entity REST API operation. + */ + RequestOperation["PNRemoveEntityOperation"] = "PNRemoveEntityOperation"; + /** + * Create relationship REST API operation. + */ + RequestOperation["PNCreateRelationshipOperation"] = "PNCreateRelationshipOperation"; + /** + * Get relationship REST API operation. + */ + RequestOperation["PNGetRelationshipOperation"] = "PNGetRelationshipOperation"; + /** + * Get all relationships REST API operation. + */ + RequestOperation["PNGetAllRelationshipsOperation"] = "PNGetAllRelationshipsOperation"; + /** + * Update relationship REST API operation. + */ + RequestOperation["PNUpdateRelationshipOperation"] = "PNUpdateRelationshipOperation"; + /** + * Patch relationship REST API operation. + */ + RequestOperation["PNPatchRelationshipOperation"] = "PNPatchRelationshipOperation"; + /** + * Remove relationship REST API operation. + */ + RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- /** diff --git a/lib/core/endpoints/data_sync/entity/create.js b/lib/core/endpoints/data_sync/entity/create.js new file mode 100644 index 000000000..5cfb59db5 --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/create.js @@ -0,0 +1,52 @@ +"use strict"; +/** + * Create Entity REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateEntityRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// endregion +/** + * Create Entity request. + * + * @internal + */ +class CreateEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNCreateEntityOperation; + } + validate() { + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (!this.parameters.entity.entityClass) + return 'Entity class cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/subkeys/${subscribeKey}/entities`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } +} +exports.CreateEntityRequest = CreateEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/get-all.js b/lib/core/endpoints/data_sync/entity/get-all.js new file mode 100644 index 000000000..5d02092fc --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/get-all.js @@ -0,0 +1,51 @@ +"use strict"; +/** + * Get All Entities REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetAllEntitiesRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion +/** + * Get All Entities request. + * + * @internal + */ +class GetAllEntitiesRequest extends request_1.AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return operations_1.default.PNGetAllEntitiesOperation; + } + validate() { + if (!this.parameters.entityClass) + return 'Entity class cannot be empty'; + } + get path() { + return `/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + } + get queryParameters() { + const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ entity_class: entityClass }, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } +} +exports.GetAllEntitiesRequest = GetAllEntitiesRequest; diff --git a/lib/core/endpoints/data_sync/entity/get.js b/lib/core/endpoints/data_sync/entity/get.js new file mode 100644 index 000000000..25a62ab40 --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/get.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * Get Entity REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetEntityRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Get Entity request. + * + * @internal + */ +class GetEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNGetEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + } +} +exports.GetEntityRequest = GetEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/patch.js b/lib/core/endpoints/data_sync/entity/patch.js new file mode 100644 index 000000000..1b1452ca1 --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/patch.js @@ -0,0 +1,68 @@ +"use strict"; +/** + * Patch Entity REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) + * and converts them to JSON Patch operations on the wire. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PatchEntityRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const data_sync_1 = require("../../../types/api/data-sync"); +const utils_1 = require("../../../utils"); +// endregion +/** + * Patch Entity request. + * + * @internal + */ +class PatchEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNPatchEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasSet && !hasRemove) + return 'At least one of set or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. + const prefixedSet = this.parameters.set + ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) + : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedSet, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} +exports.PatchEntityRequest = PatchEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/remove.js b/lib/core/endpoints/data_sync/entity/remove.js new file mode 100644 index 000000000..ad2d9e88f --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/remove.js @@ -0,0 +1,60 @@ +"use strict"; +/** + * Remove Entity REST API module. + * + * @internal + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RemoveEntityRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Remove Entity request. + * + * @internal + */ +class RemoveEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNRemoveEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + } +} +exports.RemoveEntityRequest = RemoveEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/update.js b/lib/core/endpoints/data_sync/entity/update.js new file mode 100644 index 000000000..bb9896be0 --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/update.js @@ -0,0 +1,56 @@ +"use strict"; +/** + * Update Entity REST API module. + * + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UpdateEntityRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Update Entity request. + * + * @internal + */ +class UpdateEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNUpdateEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } +} +exports.UpdateEntityRequest = UpdateEntityRequest; diff --git a/lib/core/endpoints/data_sync/relationship/create.js b/lib/core/endpoints/data_sync/relationship/create.js new file mode 100644 index 000000000..15db5ddef --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/create.js @@ -0,0 +1,52 @@ +"use strict"; +/** + * Create Relationship REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateRelationshipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// endregion +/** + * Create Relationship request. + * + * @internal + */ +class CreateRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNCreateRelationshipOperation; + } + validate() { + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); + } +} +exports.CreateRelationshipRequest = CreateRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/get-all.js b/lib/core/endpoints/data_sync/relationship/get-all.js new file mode 100644 index 000000000..4e60df6f9 --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/get-all.js @@ -0,0 +1,47 @@ +"use strict"; +/** + * Get All Relationships REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetAllRelationshipsRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion +/** + * Get All Relationships request. + * + * @internal + */ +class GetAllRelationshipsRequest extends request_1.AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return operations_1.default.PNGetAllRelationshipsOperation; + } + get path() { + return `/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + } + get queryParameters() { + const { entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } +} +exports.GetAllRelationshipsRequest = GetAllRelationshipsRequest; diff --git a/lib/core/endpoints/data_sync/relationship/get.js b/lib/core/endpoints/data_sync/relationship/get.js new file mode 100644 index 000000000..9edc65cd6 --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/get.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * Get Relationship REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetRelationshipRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Get Relationship request. + * + * @internal + */ +class GetRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNGetRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + } +} +exports.GetRelationshipRequest = GetRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/patch.js b/lib/core/endpoints/data_sync/relationship/patch.js new file mode 100644 index 000000000..6e25fb9ac --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/patch.js @@ -0,0 +1,68 @@ +"use strict"; +/** + * Patch Relationship REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) + * and converts them to JSON Patch operations on the wire. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PatchRelationshipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const data_sync_1 = require("../../../types/api/data-sync"); +const utils_1 = require("../../../utils"); +// endregion +/** + * Patch Relationship request. + * + * @internal + */ +class PatchRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNPatchRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasSet && !hasRemove) + return 'At least one of set or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + if (this.parameters.idempotencyKey) + headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'role') and the SDK produces '/payload/role' on the wire. + const prefixedSet = this.parameters.set + ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) + : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedSet, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} +exports.PatchRelationshipRequest = PatchRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/remove.js b/lib/core/endpoints/data_sync/relationship/remove.js new file mode 100644 index 000000000..25bc77d84 --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/remove.js @@ -0,0 +1,60 @@ +"use strict"; +/** + * Remove Relationship REST API module. + * + * @internal + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RemoveRelationshipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Remove Relationship request. + * + * @internal + */ +class RemoveRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNRemoveRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + } +} +exports.RemoveRelationshipRequest = RemoveRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/update.js b/lib/core/endpoints/data_sync/relationship/update.js new file mode 100644 index 000000000..0d6928c4a --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/update.js @@ -0,0 +1,57 @@ +"use strict"; +/** + * Update Relationship REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UpdateRelationshipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Update Relationship request. + * + * @internal + */ +class UpdateRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNUpdateRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); + } +} +exports.UpdateRelationshipRequest = UpdateRelationshipRequest; diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index e2a36c9a8..d0d84f006 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -125,6 +125,9 @@ const pubnub_channel_groups_1 = __importDefault(require("./pubnub-channel-groups const pubnub_push_1 = __importDefault(require("./pubnub-push")); const pubnub_objects_1 = __importDefault(require("./pubnub-objects")); // endregion +// region DataSync +const pubnub_data_sync_1 = __importDefault(require("./pubnub-data-sync")); +// endregion // region Time const Time = __importStar(require("./endpoints/time")); const download_file_1 = require("./endpoints/file_upload/download_file"); @@ -203,6 +206,7 @@ class PubNubCore { // API group entry points initialization. if (process.env.APP_CONTEXT_MODULE !== 'disabled') this._objects = new pubnub_objects_1.default(this._configuration, this.sendRequest.bind(this)); + this._dataSync = new pubnub_data_sync_1.default(this._configuration, this.sendRequest.bind(this)); if (process.env.CHANNEL_GROUPS_MODULE !== 'disabled') this._channelGroups = new pubnub_channel_groups_1.default(this._configuration.logger(), this._configuration.keySet, this.sendRequest.bind(this)); if (process.env.MOBILE_PUSH_MODULE !== 'disabled') @@ -811,17 +815,18 @@ class PubNubCore { }) .catch((error) => { const apiError = !(error instanceof pubnub_api_error_1.PubNubAPIError) ? pubnub_api_error_1.PubNubAPIError.create(error) : error; + const errorMessage = apiError.toFormattedMessage(operation); // Notify callback (if possible). if (callback) { if (apiError.category !== categories_2.default.PNCancelledCategory) { this.logger.error('PubNub', () => ({ messageType: 'error', - message: apiError.toPubNubError(operation, 'REST API request processing error, check status for details'), + message: apiError.toPubNubError(operation, errorMessage), })); } return callback(apiError.toStatus(operation), null); } - const pubNubError = apiError.toPubNubError(operation, 'REST API request processing error, check status for details'); + const pubNubError = apiError.toPubNubError(operation, errorMessage); if (apiError.category !== categories_2.default.PNCancelledCategory) this.logger.error('PubNub', () => ({ messageType: 'error', message: pubNubError })); throw pubNubError; @@ -2281,6 +2286,16 @@ class PubNubCore { get objects() { return this._objects; } + // -------------------------------------------------------- + // -------------------- DataSync API --------------------- + // -------------------------------------------------------- + // region DataSync API + /** + * PubNub DataSync API group. + */ + get dataSync() { + return this._dataSync; + } /** Fetch a paginated list of User objects. * diff --git a/lib/core/pubnub-data-sync.js b/lib/core/pubnub-data-sync.js new file mode 100644 index 000000000..eaf88b758 --- /dev/null +++ b/lib/core/pubnub-data-sync.js @@ -0,0 +1,315 @@ +"use strict"; +/** + * PubNub DataSync API module. + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const create_1 = require("./endpoints/data_sync/relationship/create"); +const get_all_1 = require("./endpoints/data_sync/relationship/get-all"); +const update_1 = require("./endpoints/data_sync/relationship/update"); +const remove_1 = require("./endpoints/data_sync/relationship/remove"); +const patch_1 = require("./endpoints/data_sync/relationship/patch"); +const get_1 = require("./endpoints/data_sync/relationship/get"); +const create_2 = require("./endpoints/data_sync/entity/create"); +const get_all_2 = require("./endpoints/data_sync/entity/get-all"); +const update_2 = require("./endpoints/data_sync/entity/update"); +const remove_2 = require("./endpoints/data_sync/entity/remove"); +const patch_2 = require("./endpoints/data_sync/entity/patch"); +const get_2 = require("./endpoints/data_sync/entity/get"); +/** + * PubNub DataSync API interface. + */ +class PubNubDataSync { + /** + * Create DataSync API access object. + * + * @param configuration - Extended PubNub client configuration object. + * @param sendRequest - Function which should be used to send REST API calls. + * + * @internal + */ + constructor(configuration, + /* eslint-disable @typescript-eslint/no-explicit-any */ + sendRequest) { + this.keySet = configuration.keySet; + this.configuration = configuration; + this.sendRequest = sendRequest; + } + /** + * Get registered loggers' manager. + * + * @returns Registered loggers' manager. + * + * @internal + */ + get logger() { + return this.configuration.logger(); + } + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create entity response or `void` in case if `callback` provided. + */ + createEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Entity with parameters:', + })); + const request = new create_2.CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get entity response or `void` in case if `callback` provided. + */ + getEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Entity with parameters:', + })); + const request = new get_2.GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all entities response or `void` in case if `callback` provided. + */ + getAllEntities(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Entities with parameters:', + })); + const request = new get_all_2.GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update entity response or `void` in case if `callback` provided. + */ + updateEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Entity with parameters:', + })); + const request = new update_2.UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch entity response or `void` in case if `callback` provided. + */ + patchEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Entity with parameters:', + })); + const request = new patch_2.PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove entity response or `void` in case if `callback` provided. + */ + removeEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Entity with parameters:', + })); + const request = new remove_2.RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create relationship response or `void` in case if `callback` provided. + */ + createRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Relationship with parameters:', + })); + const request = new create_1.CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get relationship response or `void` in case if `callback` provided. + */ + getRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Relationship with parameters:', + })); + const request = new get_1.GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Relationships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + */ + getAllRelationships(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Relationships with parameters:', + })); + const request = new get_all_1.GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. + */ + updateRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Relationship with parameters:', + })); + const request = new update_1.UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch relationship response or `void` in case if `callback` provided. + */ + patchRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Relationship with parameters:', + })); + const request = new patch_1.PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove relationship response or `void` in case if `callback` provided. + */ + removeRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Relationship with parameters:', + })); + const request = new remove_1.RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } +} +exports.default = PubNubDataSync; diff --git a/lib/core/types/api/data-sync.js b/lib/core/types/api/data-sync.js new file mode 100644 index 000000000..becbd26ae --- /dev/null +++ b/lib/core/types/api/data-sync.js @@ -0,0 +1,42 @@ +"use strict"; +/** + * PubNub DataSync API type definitions. + * + * Types for Entity Class CRUD operations. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.toJsonPointer = toJsonPointer; +exports.toJsonPatchOperations = toJsonPatchOperations; +/** + * Convert dot-notation path to JSON Pointer (RFC 6901). + * + * "config.ttlSec" → "/config/ttlSec" + * "filterableFields.0.name" → "/filterableFields/0/name" + * + * @internal + */ +function toJsonPointer(dotPath) { + return '/' + dotPath.split('.').join('/'); +} +/** + * Convert `set` and `remove` parameters to JSON Patch operations (wire format). + * + * - Each key in `set` becomes a "replace" operation. + * - Each entry in `remove` becomes a "remove" operation. + * + * @internal + */ +function toJsonPatchOperations(set, remove) { + const ops = []; + if (set) { + for (const [dotPath, value] of Object.entries(set)) { + ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); + } + } + if (remove) { + for (const dotPath of remove) { + ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); + } + } + return ops; +} diff --git a/lib/core/types/transport-request.js b/lib/core/types/transport-request.js index f72b28210..2d959bed7 100644 --- a/lib/core/types/transport-request.js +++ b/lib/core/types/transport-request.js @@ -20,6 +20,10 @@ var TransportMethod; * Request will be sent using `PATCH` method. */ TransportMethod["PATCH"] = "PATCH"; + /** + * Request will be sent using `PUT` method. + */ + TransportMethod["PUT"] = "PUT"; /** * Request will be sent using `DELETE` method. */ diff --git a/lib/errors/pubnub-api-error.js b/lib/errors/pubnub-api-error.js index 72d3eb738..ae7d564c5 100644 --- a/lib/errors/pubnub-api-error.js +++ b/lib/errors/pubnub-api-error.js @@ -162,6 +162,24 @@ class PubNubAPIError extends Error { errorData = errorResponse; status = errorResponse.status; } + else if ('errors' in errorResponse && + Array.isArray(errorResponse.errors) && + errorResponse.errors.length > 0) { + // Handle DataSync-style structured error responses: + // { errors: [{ errorCode: "SYN-0008", message: "...", path: "/id" }] } + errorData = errorResponse; + const errors = errorResponse.errors; + message = errors + .map((e) => { + const parts = []; + if (e.errorCode) + parts.push(e.errorCode); + if (e.message) + parts.push(e.message); + return parts.join(': '); + }) + .join('; '); + } else errorData = errorResponse; if ('error' in errorResponse && errorResponse.error instanceof Error) @@ -242,6 +260,30 @@ class PubNubAPIError extends Error { }, }; } + /** + * Format a user-facing error message for this API error. + * + * When the error contains structured details extracted from the service response + * (e.g., DataSync `errors` array), those details are included in the message. + * Otherwise, falls back to a generic description. + * + * @param operation - Request operation during which error happened. + * + * @returns Formatted error message string. + */ + toFormattedMessage(operation) { + const fallback = 'REST API request processing error, check status for details'; + // When errorData contains a structured `errors` array, `this.message` was already + // constructed from it in `createFromServiceResponse` — prefer it over the generic fallback. + if (this.errorData && + typeof this.errorData === 'object' && + !('name' in this.errorData && 'message' in this.errorData && 'stack' in this.errorData) && + 'errors' in this.errorData && + Array.isArray(this.errorData.errors)) { + return `${operation}: ${this.message}`; + } + return fallback; + } /** * Convert API error object to PubNub client error object. * diff --git a/lib/transport/middleware.js b/lib/transport/middleware.js index f4690f9ef..80d467f04 100644 --- a/lib/transport/middleware.js +++ b/lib/transport/middleware.js @@ -33,7 +33,7 @@ class RequestSignature { signature(req) { const method = req.path.startsWith('/publish') ? transport_request_1.TransportMethod.GET : req.method; let signatureInput = `${method}\n${this.publishKey}\n${req.path}\n${this.queryParameters(req.queryParameters)}\n`; - if (method === transport_request_1.TransportMethod.POST || method === transport_request_1.TransportMethod.PATCH) { + if (method === transport_request_1.TransportMethod.POST || method === transport_request_1.TransportMethod.PATCH || method === transport_request_1.TransportMethod.PUT) { const body = req.body; let payload; if (body && body instanceof ArrayBuffer) { diff --git a/lib/types/index.d.ts b/lib/types/index.d.ts index ef27f1ba8..2534bd371 100644 --- a/lib/types/index.d.ts +++ b/lib/types/index.d.ts @@ -769,6 +769,10 @@ declare class PubNubCore< * PubNub App Context API group. */ get objects(): PubNub.PubNubObjects; + /** + * PubNub DataSync API group. + */ + get dataSync(): PubNub.PubNubDataSync; /** * Fetch a paginated list of User objects. * @@ -2025,6 +2029,54 @@ declare namespace PubNub { * Update channel memberships REST API operation. */ PNSetMembershipsOperation = 'PNSetMembershipsOperation', + /** + * Create entity REST API operation. + */ + PNCreateEntityOperation = 'PNCreateEntityOperation', + /** + * Get entity REST API operation. + */ + PNGetEntityOperation = 'PNGetEntityOperation', + /** + * Get all entities REST API operation. + */ + PNGetAllEntitiesOperation = 'PNGetAllEntitiesOperation', + /** + * Update entity REST API operation. + */ + PNUpdateEntityOperation = 'PNUpdateEntityOperation', + /** + * Patch entity REST API operation. + */ + PNPatchEntityOperation = 'PNPatchEntityOperation', + /** + * Remove entity REST API operation. + */ + PNRemoveEntityOperation = 'PNRemoveEntityOperation', + /** + * Create relationship REST API operation. + */ + PNCreateRelationshipOperation = 'PNCreateRelationshipOperation', + /** + * Get relationship REST API operation. + */ + PNGetRelationshipOperation = 'PNGetRelationshipOperation', + /** + * Get all relationships REST API operation. + */ + PNGetAllRelationshipsOperation = 'PNGetAllRelationshipsOperation', + /** + * Update relationship REST API operation. + */ + PNUpdateRelationshipOperation = 'PNUpdateRelationshipOperation', + /** + * Patch relationship REST API operation. + */ + PNPatchRelationshipOperation = 'PNPatchRelationshipOperation', + /** + * Remove relationship REST API operation. + */ + PNRemoveRelationshipOperation = 'PNRemoveRelationshipOperation', /** * Fetch list of files sent to the channel REST API operation. */ @@ -3074,6 +3126,10 @@ declare namespace PubNub { * Request will be sent using `PATCH` method. */ PATCH = 'PATCH', + /** + * Request will be sent using `PUT` method. + */ + PUT = 'PUT', /** * Request will be sent using `DELETE` method. */ @@ -5478,6 +5534,241 @@ declare namespace PubNub { >; } + /** + * PubNub DataSync API interface. + */ + export class PubNubDataSync { + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + createEntity( + parameters: DataSync.CreateEntityParameters, + callback: ResultCallback, + ): void; + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create entity response. + */ + createEntity(parameters: DataSync.CreateEntityParameters): Promise; + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getEntity(parameters: DataSync.GetEntityParameters, callback: ResultCallback): void; + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get entity response. + */ + getEntity(parameters: DataSync.GetEntityParameters): Promise; + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getAllEntities( + parameters: DataSync.GetAllEntitiesParameters, + callback: ResultCallback, + ): void; + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get all entities response. + */ + getAllEntities(parameters: DataSync.GetAllEntitiesParameters): Promise; + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback: ResultCallback, + ): void; + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update entity response. + */ + updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + patchEntity( + parameters: DataSync.PatchEntityParameters, + callback: ResultCallback, + ): void; + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch entity response. + */ + patchEntity(parameters: DataSync.PatchEntityParameters): Promise; + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + removeEntity( + parameters: DataSync.RemoveEntityParameters, + callback: ResultCallback, + ): void; + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove entity response. + */ + removeEntity(parameters: DataSync.RemoveEntityParameters): Promise; + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + createRelationship( + parameters: DataSync.CreateRelationshipParameters, + callback: ResultCallback, + ): void; + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create relationship response. + */ + createRelationship(parameters: DataSync.CreateRelationshipParameters): Promise; + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getRelationship( + parameters: DataSync.GetRelationshipParameters, + callback: ResultCallback, + ): void; + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get relationship response. + */ + getRelationship(parameters: DataSync.GetRelationshipParameters): Promise; + /** + * Fetch a paginated list of Relationships. + * + * @param callback - Request completion handler callback. + */ + getAllRelationships(callback: ResultCallback): void; + /** + * Fetch a paginated list of Relationships. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getAllRelationships( + parameters: DataSync.GetAllRelationshipsParameters, + callback: ResultCallback, + ): void; + /** + * Fetch a paginated list of Relationships. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all relationships response. + */ + getAllRelationships( + parameters?: DataSync.GetAllRelationshipsParameters, + ): Promise; + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback: ResultCallback, + ): void; + /** + * Update a Relationship (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update relationship response. + */ + updateRelationship(parameters: DataSync.UpdateRelationshipParameters): Promise; + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + patchRelationship( + parameters: DataSync.PatchRelationshipParameters, + callback: ResultCallback, + ): void; + /** + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch relationship response. + */ + patchRelationship(parameters: DataSync.PatchRelationshipParameters): Promise; + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + removeRelationship( + parameters: DataSync.RemoveRelationshipParameters, + callback: ResultCallback, + ): void; + /** + * Remove a Relationship. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove relationship response. + */ + removeRelationship(parameters: DataSync.RemoveRelationshipParameters): Promise; + } + /** * Logging module manager. * @@ -8928,6 +9219,523 @@ declare namespace PubNub { }; } + export namespace DataSync { + /** + * Filterable field definition for entity classes. + */ + export type FilterableField = { + /** Unique semantic identifier for the property. */ + name: string; + /** JSON Pointer (RFC 6901) to the property location. */ + path: string; + /** Data type of the property value. */ + valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; + /** + * Whether the property should be indexed for full-text search. + * @default false + */ + enabledAdvancedFiltering?: boolean; + /** + * Whether the property can have null values. + * @default true + */ + isNullable?: boolean; + }; + + /** + * Cursor-based pagination metadata returned by the server. + */ + export type DataSyncPageMeta = { + /** Opaque cursor for the next page. Null if no more results. */ + next_cursor: string | null; + /** Opaque cursor for the previous page. Null if first page. */ + prev_cursor: string | null; + /** Whether there are more results after this page. */ + has_next: boolean; + /** Whether there are results before this page. */ + has_prev: boolean; + /** The limit applied to this page. */ + limit: number; + }; + + /** + * HATEOAS navigation links. + */ + export type DataSyncLinks = { + /** Link to the current page. */ + self: string; + /** Link to the next page, if available. */ + next?: string | null; + /** Link to the previous page, if available. */ + prev?: string | null; + /** Additional links for related resources. */ + [key: string]: string | null | undefined; + }; + + /** + * Common parameters for paginated list requests. + */ + type PagedRequestParameters = { + /** Opaque cursor for pagination. Omit for the first page. */ + cursor?: string; + /** + * Maximum number of items per page. + * @default 20 + * @max 100 + */ + limit?: number; + /** Filter expression for results. */ + filter?: string; + /** + * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). + * Example: "+name,-createdAt" + */ + sort?: string; + }; + + /** + * Single-entity response envelope. + */ + type DataSyncEntityResponse = { + /** HTTP status code. */ + status: number; + /** Response data. */ + data: T; + /** HATEOAS links. */ + links?: DataSyncLinks; + /** Response metadata. */ + meta?: DataSyncPageMeta; + }; + + /** + * Paged list response envelope. + */ + type DataSyncPagedResponse = { + /** HTTP status code. */ + status: number; + /** Array of response items. */ + data: T[]; + /** HATEOAS links for pagination. */ + links?: DataSyncLinks; + /** Cursor-based pagination metadata. */ + meta?: DataSyncPageMeta; + }; + + /** + * Entity properties for create requests. + * + * Includes `entityClass` since it must be set at creation time and is immutable afterward. + */ + export type CreateEntityProperties = { + /** Entity class this entity belongs to. */ + entityClass: string; + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity properties for update (PUT) requests. + * + * `entityClass` is immutable after creation and therefore excluded from updates. + */ + export type UpdateEntityProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity resource as returned from the server. + */ + export type EntityObject = { + /** Unique identifier (UUID). */ + id: string; + /** Entity class this entity belongs to. */ + entityClass: string; + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + /** Date and time the entity was created (ISO 8601). */ + createdAt: string; + /** Date and time the entity was last updated (ISO 8601). */ + updatedAt: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ + expiresAt?: string; + }; + + /** + * Create Entity request parameters. + */ + export type CreateEntityParameters = { + /** + * Entity properties to create. + * + * All entity properties go inside `entity` because they map to the request body envelope. + * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation + * posts to a collection URL with all fields in the body. + */ + entity: CreateEntityProperties & { + /** + * Optional entity ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Get Entity request parameters. + */ + export type GetEntityParameters = { + /** Entity ID. */ + id: string; + }; + + /** + * Get All Entities request parameters. + * + * `entityClass` is required — entities are always listed within the context of their class. + */ + export type GetAllEntitiesParameters = PagedRequestParameters & { + /** Entity class name to filter by (required). */ + entityClass: string; + /** + * Entity class version. If not provided, the server returns entities for the latest version. + */ + entityClassVersion?: number; + /** + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. + */ + filterAdvanced?: string; + }; + + /** + * Update Entity request parameters (full replacement via PUT). + * + * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, + * and `payload` can be updated. + */ + export type UpdateEntityParameters = { + /** Entity ID. */ + id: string; + /** Complete entity properties for replacement (excludes immutable `entityClass`). */ + entity: UpdateEntityProperties; + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `set` or `remove` must be provided. + */ + export type PatchEntityParameters = { + /** Entity ID. */ + id: string; + /** + * Fields to add or replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * set: { + * 'status': 'active', + * 'payload.score': 300, + * 'payload.profile.displayName': 'Alice', + * } + * ``` + */ + set?: Record; + /** + * Array of dot-notation field paths to remove. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['payload.tempFlag', 'payload.legacyField'] + * ``` + */ + remove?: string[]; + /** + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Remove Entity request parameters. + */ + export type RemoveEntityParameters = { + /** Entity ID. */ + id: string; + /** + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** Response for creating an entity. */ + export type CreateEntityResponse = DataSyncEntityResponse; + + /** Response for getting a single entity. */ + export type GetEntityResponse = DataSyncEntityResponse; + + /** Response for listing entities. */ + export type GetAllEntitiesResponse = DataSyncPagedResponse; + + /** Response for updating an entity (PUT). */ + export type UpdateEntityResponse = DataSyncEntityResponse; + + /** Response for patching an entity (PATCH). */ + export type PatchEntityResponse = DataSyncEntityResponse; + + /** Response for removing an entity. */ + export type RemoveEntityResponse = { + /** HTTP status code. */ + status: number; + }; + + /** + * Relationship properties for create requests. + * + * Both `entityAId` and `entityBId` must be set at creation time. + */ + export type CreateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Relationship properties for update (PUT) requests. + * + * PUT is a full replacement — `entityAId` and `entityBId` are required. + */ + export type UpdateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + }; + + /** + * Relationship resource as returned from the server. + */ + export type RelationshipObject = { + /** Unique identifier. */ + id: string; + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + /** Date and time the relationship was created (ISO 8601). */ + createdAt: string; + /** Date and time the relationship was last updated (ISO 8601). */ + updatedAt: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; + }; + + /** + * Create Relationship request parameters. + */ + export type CreateRelationshipParameters = { + /** + * Relationship properties to create. + * + * All relationship properties go inside `relationship` because they map to the request body envelope. + */ + relationship: CreateRelationshipProperties & { + /** + * Optional relationship ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Get Relationship request parameters. + */ + export type GetRelationshipParameters = { + /** Relationship ID. */ + id: string; + }; + + /** + * Get All Relationships request parameters. + * + * All parameters are optional — relationships can be listed without any filters. + */ + export type GetAllRelationshipsParameters = PagedRequestParameters & { + /** Filter relationships by first entity ID. */ + entityAId?: string; + /** Filter relationships by second entity ID. */ + entityBId?: string; + /** + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. + */ + filterAdvanced?: string; + }; + + /** + * Update Relationship request parameters (full replacement via PUT). + */ + export type UpdateRelationshipParameters = { + /** Relationship ID. */ + id: string; + /** Complete relationship properties for replacement. */ + relationship: UpdateRelationshipProperties; + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** + * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `set` and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `set` or `remove` must be provided. + */ + export type PatchRelationshipParameters = { + /** Relationship ID. */ + id: string; + /** + * Fields to add or replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * set: { + * 'role': 'admin', + * 'permissions.read': true, + * } + * ``` + */ + set?: Record; + /** + * Array of dot-notation field paths to remove from `payload`. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['tempFlag', 'legacyField'] + * ``` + */ + remove?: string[]; + /** + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; + }; + + /** + * Remove Relationship request parameters. + */ + export type RemoveRelationshipParameters = { + /** Relationship ID. */ + id: string; + /** + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; + }; + + /** Response for creating a relationship. */ + export type CreateRelationshipResponse = DataSyncEntityResponse; + + /** Response for getting a single relationship. */ + export type GetRelationshipResponse = DataSyncEntityResponse; + + /** Response for listing relationships. */ + export type GetAllRelationshipsResponse = DataSyncPagedResponse; + + /** Response for updating a relationship (PUT). */ + export type UpdateRelationshipResponse = DataSyncEntityResponse; + + /** Response for patching a relationship (PATCH). */ + export type PatchRelationshipResponse = DataSyncEntityResponse; + + /** Response for removing a relationship. */ + export type RemoveRelationshipResponse = { + /** HTTP status code. */ + status: number; + }; + } + export namespace Push { /** * Common managed channels push notification parameters. diff --git a/package-lock.json b/package-lock.json index 80223696f..a59cd7b74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pubnub", - "version": "10.2.9", + "version": "11.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pubnub", - "version": "10.2.9", + "version": "11.0.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "agentkeepalive": "^3.5.2", From e82c07a2f690691c728759097122d5640bbd66bd Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:35:57 +0530 Subject: [PATCH 09/19] fix lint --- .../endpoints/data_sync/channel/create.ts | 10 +- .../endpoints/data_sync/channel/get-all.ts | 7 +- src/core/endpoints/data_sync/channel/get.ts | 7 +- src/core/endpoints/data_sync/channel/patch.ts | 13 +- .../endpoints/data_sync/channel/remove.ts | 10 +- .../endpoints/data_sync/channel/update.ts | 10 +- src/core/endpoints/data_sync/entity/create.ts | 10 +- .../endpoints/data_sync/entity/get-all.ts | 7 +- src/core/endpoints/data_sync/entity/get.ts | 4 +- src/core/endpoints/data_sync/entity/patch.ts | 13 +- src/core/endpoints/data_sync/entity/remove.ts | 10 +- src/core/endpoints/data_sync/entity/update.ts | 10 +- .../endpoints/data_sync/membership/create.ts | 10 +- .../endpoints/data_sync/membership/get-all.ts | 11 +- .../endpoints/data_sync/membership/get.ts | 7 +- .../endpoints/data_sync/membership/patch.ts | 13 +- .../endpoints/data_sync/membership/remove.ts | 10 +- .../endpoints/data_sync/membership/update.ts | 10 +- .../data_sync/relationship/create.ts | 10 +- .../data_sync/relationship/get-all.ts | 7 +- .../endpoints/data_sync/relationship/get.ts | 7 +- .../endpoints/data_sync/relationship/patch.ts | 13 +- .../data_sync/relationship/remove.ts | 10 +- .../data_sync/relationship/update.ts | 10 +- src/core/endpoints/data_sync/user/create.ts | 10 +- src/core/endpoints/data_sync/user/get-all.ts | 7 +- src/core/endpoints/data_sync/user/get.ts | 4 +- src/core/endpoints/data_sync/user/patch.ts | 10 +- src/core/endpoints/data_sync/user/remove.ts | 10 +- src/core/endpoints/data_sync/user/update.ts | 10 +- src/core/pubnub-data-sync.ts | 32 +- src/core/types/api/data-sync.ts | 2172 ++++++++--------- 32 files changed, 1231 insertions(+), 1253 deletions(-) diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts index b4a9c0ab4..8162a32c0 100644 --- a/src/core/endpoints/data_sync/channel/create.ts +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.CreateChannelParameters & { * * @internal */ -export class CreateChannelRequest< - Response extends DataSync.CreateChannelResponse, -> extends AbstractRequest { +export class CreateChannelRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.POST }); } @@ -51,8 +52,7 @@ export class CreateChannelRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/channel/get-all.ts b/src/core/endpoints/data_sync/channel/get-all.ts index e5a204da2..2c3df4edb 100644 --- a/src/core/endpoints/data_sync/channel/get-all.ts +++ b/src/core/endpoints/data_sync/channel/get-all.ts @@ -41,9 +41,10 @@ type RequestParameters = DataSync.GetAllChannelsParameters & { * * @internal */ -export class GetAllChannelsRequest< - Response extends DataSync.GetAllChannelsResponse, -> extends AbstractRequest { +export class GetAllChannelsRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); diff --git a/src/core/endpoints/data_sync/channel/get.ts b/src/core/endpoints/data_sync/channel/get.ts index 251de4434..1bcb5a06b 100644 --- a/src/core/endpoints/data_sync/channel/get.ts +++ b/src/core/endpoints/data_sync/channel/get.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.GetChannelParameters & { * * @internal */ -export class GetChannelRequest< - Response extends DataSync.GetChannelResponse, -> extends AbstractRequest { +export class GetChannelRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/endpoints/data_sync/channel/patch.ts b/src/core/endpoints/data_sync/channel/patch.ts index 01476cc81..05c73b6ff 100644 --- a/src/core/endpoints/data_sync/channel/patch.ts +++ b/src/core/endpoints/data_sync/channel/patch.ts @@ -37,9 +37,10 @@ type RequestParameters = DataSync.PatchChannelParameters & { * * @internal */ -export class PatchChannelRequest< - Response extends DataSync.PatchChannelResponse, -> extends AbstractRequest { +export class PatchChannelRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PATCH }); } @@ -60,11 +61,9 @@ export class PatchChannelRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/channel/remove.ts b/src/core/endpoints/data_sync/channel/remove.ts index cac10fd68..f6cdd378b 100644 --- a/src/core/endpoints/data_sync/channel/remove.ts +++ b/src/core/endpoints/data_sync/channel/remove.ts @@ -33,9 +33,10 @@ type RequestParameters = DataSync.RemoveChannelParameters & { * * @internal */ -export class RemoveChannelRequest< - Response extends DataSync.RemoveChannelResponse, -> extends AbstractRequest { +export class RemoveChannelRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.DELETE }); } @@ -51,8 +52,7 @@ export class RemoveChannelRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return Object.keys(headers).length > 0 ? headers : undefined; } diff --git a/src/core/endpoints/data_sync/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts index 71ff5d386..a2583c5a2 100644 --- a/src/core/endpoints/data_sync/channel/update.ts +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -34,9 +34,10 @@ type RequestParameters = DataSync.UpdateChannelParameters & { * * @internal */ -export class UpdateChannelRequest< - Response extends DataSync.UpdateChannelResponse, -> extends AbstractRequest { +export class UpdateChannelRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PUT }); } @@ -55,8 +56,7 @@ export class UpdateChannelRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return { ...headers, diff --git a/src/core/endpoints/data_sync/entity/create.ts b/src/core/endpoints/data_sync/entity/create.ts index 8e77b1a59..ac265bbae 100644 --- a/src/core/endpoints/data_sync/entity/create.ts +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.CreateEntityParameters & { * * @internal */ -export class CreateEntityRequest< - Response extends DataSync.CreateEntityResponse, -> extends AbstractRequest { +export class CreateEntityRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.POST }); } @@ -52,8 +53,7 @@ export class CreateEntityRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/entity/get-all.ts b/src/core/endpoints/data_sync/entity/get-all.ts index 00ffb0ea9..5b43a6379 100644 --- a/src/core/endpoints/data_sync/entity/get-all.ts +++ b/src/core/endpoints/data_sync/entity/get-all.ts @@ -41,9 +41,10 @@ type RequestParameters = DataSync.GetAllEntitiesParameters & { * * @internal */ -export class GetAllEntitiesRequest< - Response extends DataSync.GetAllEntitiesResponse, -> extends AbstractRequest { +export class GetAllEntitiesRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); diff --git a/src/core/endpoints/data_sync/entity/get.ts b/src/core/endpoints/data_sync/entity/get.ts index 004b5e534..47ddcb28e 100644 --- a/src/core/endpoints/data_sync/entity/get.ts +++ b/src/core/endpoints/data_sync/entity/get.ts @@ -31,9 +31,7 @@ type RequestParameters = DataSync.GetEntityParameters & { * * @internal */ -export class GetEntityRequest< - Response extends DataSync.GetEntityResponse, -> extends AbstractRequest { +export class GetEntityRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/patch.ts index 17d759176..48e093eaf 100644 --- a/src/core/endpoints/data_sync/entity/patch.ts +++ b/src/core/endpoints/data_sync/entity/patch.ts @@ -37,9 +37,10 @@ type RequestParameters = DataSync.PatchEntityParameters & { * * @internal */ -export class PatchEntityRequest< - Response extends DataSync.PatchEntityResponse, -> extends AbstractRequest { +export class PatchEntityRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PATCH }); } @@ -60,11 +61,9 @@ export class PatchEntityRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/entity/remove.ts b/src/core/endpoints/data_sync/entity/remove.ts index c80b537b1..a2b770107 100644 --- a/src/core/endpoints/data_sync/entity/remove.ts +++ b/src/core/endpoints/data_sync/entity/remove.ts @@ -33,9 +33,10 @@ type RequestParameters = DataSync.RemoveEntityParameters & { * * @internal */ -export class RemoveEntityRequest< - Response extends DataSync.RemoveEntityResponse, -> extends AbstractRequest { +export class RemoveEntityRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.DELETE }); } @@ -51,8 +52,7 @@ export class RemoveEntityRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return Object.keys(headers).length > 0 ? headers : undefined; } diff --git a/src/core/endpoints/data_sync/entity/update.ts b/src/core/endpoints/data_sync/entity/update.ts index 6c68bf143..a5b36e4f2 100644 --- a/src/core/endpoints/data_sync/entity/update.ts +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -35,9 +35,10 @@ type RequestParameters = DataSync.UpdateEntityParameters & { * * @internal */ -export class UpdateEntityRequest< - Response extends DataSync.UpdateEntityResponse, -> extends AbstractRequest { +export class UpdateEntityRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PUT }); } @@ -56,8 +57,7 @@ export class UpdateEntityRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return { ...headers, diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 40a0a27a5..40078a834 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.CreateMembershipParameters & { * * @internal */ -export class CreateMembershipRequest< - Response extends DataSync.CreateMembershipResponse, -> extends AbstractRequest { +export class CreateMembershipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.POST }); } @@ -52,8 +53,7 @@ export class CreateMembershipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/membership/get-all.ts b/src/core/endpoints/data_sync/membership/get-all.ts index 5ba206399..bfb490652 100644 --- a/src/core/endpoints/data_sync/membership/get-all.ts +++ b/src/core/endpoints/data_sync/membership/get-all.ts @@ -41,9 +41,10 @@ type RequestParameters = DataSync.GetAllMembershipsParameters & { * * @internal */ -export class GetAllMembershipsRequest< - Response extends DataSync.GetAllMembershipsResponse, -> extends AbstractRequest { +export class GetAllMembershipsRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); @@ -66,9 +67,7 @@ export class GetAllMembershipsRequest< return { ...(userId ? { user_id: userId } : {}), ...(channelId ? { channel_id: channelId } : {}), - ...(relationshipClassVersion !== undefined - ? { relationship_class_version: `${relationshipClassVersion}` } - : {}), + ...(relationshipClassVersion !== undefined ? { relationship_class_version: `${relationshipClassVersion}` } : {}), ...(cursor ? { cursor } : {}), ...(limit ? { limit: `${limit}` } : {}), ...(filter ? { filter } : {}), diff --git a/src/core/endpoints/data_sync/membership/get.ts b/src/core/endpoints/data_sync/membership/get.ts index 9909e258f..bd7ecb1cf 100644 --- a/src/core/endpoints/data_sync/membership/get.ts +++ b/src/core/endpoints/data_sync/membership/get.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.GetMembershipParameters & { * * @internal */ -export class GetMembershipRequest< - Response extends DataSync.GetMembershipResponse, -> extends AbstractRequest { +export class GetMembershipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/endpoints/data_sync/membership/patch.ts b/src/core/endpoints/data_sync/membership/patch.ts index efab09b08..97549e2b4 100644 --- a/src/core/endpoints/data_sync/membership/patch.ts +++ b/src/core/endpoints/data_sync/membership/patch.ts @@ -37,9 +37,10 @@ type RequestParameters = DataSync.PatchMembershipParameters & { * * @internal */ -export class PatchMembershipRequest< - Response extends DataSync.PatchMembershipResponse, -> extends AbstractRequest { +export class PatchMembershipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PATCH }); } @@ -60,11 +61,9 @@ export class PatchMembershipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/membership/remove.ts b/src/core/endpoints/data_sync/membership/remove.ts index 32461f73f..4924d2c4e 100644 --- a/src/core/endpoints/data_sync/membership/remove.ts +++ b/src/core/endpoints/data_sync/membership/remove.ts @@ -33,9 +33,10 @@ type RequestParameters = DataSync.RemoveMembershipParameters & { * * @internal */ -export class RemoveMembershipRequest< - Response extends DataSync.RemoveMembershipResponse, -> extends AbstractRequest { +export class RemoveMembershipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.DELETE }); } @@ -51,8 +52,7 @@ export class RemoveMembershipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return Object.keys(headers).length > 0 ? headers : undefined; } diff --git a/src/core/endpoints/data_sync/membership/update.ts b/src/core/endpoints/data_sync/membership/update.ts index f6d4d236e..8064893c5 100644 --- a/src/core/endpoints/data_sync/membership/update.ts +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -34,9 +34,10 @@ type RequestParameters = DataSync.UpdateMembershipParameters & { * * @internal */ -export class UpdateMembershipRequest< - Response extends DataSync.UpdateMembershipResponse, -> extends AbstractRequest { +export class UpdateMembershipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PUT }); } @@ -55,8 +56,7 @@ export class UpdateMembershipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return { ...headers, diff --git a/src/core/endpoints/data_sync/relationship/create.ts b/src/core/endpoints/data_sync/relationship/create.ts index 9f371b4d3..d8ef9243d 100644 --- a/src/core/endpoints/data_sync/relationship/create.ts +++ b/src/core/endpoints/data_sync/relationship/create.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.CreateRelationshipParameters & { * * @internal */ -export class CreateRelationshipRequest< - Response extends DataSync.CreateRelationshipResponse, -> extends AbstractRequest { +export class CreateRelationshipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.POST }); } @@ -53,8 +54,7 @@ export class CreateRelationshipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/relationship/get-all.ts b/src/core/endpoints/data_sync/relationship/get-all.ts index a23aa3278..0b616df69 100644 --- a/src/core/endpoints/data_sync/relationship/get-all.ts +++ b/src/core/endpoints/data_sync/relationship/get-all.ts @@ -41,9 +41,10 @@ type RequestParameters = DataSync.GetAllRelationshipsParameters & { * * @internal */ -export class GetAllRelationshipsRequest< - Response extends DataSync.GetAllRelationshipsResponse, -> extends AbstractRequest { +export class GetAllRelationshipsRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); diff --git a/src/core/endpoints/data_sync/relationship/get.ts b/src/core/endpoints/data_sync/relationship/get.ts index 73be5ee90..5788e31c5 100644 --- a/src/core/endpoints/data_sync/relationship/get.ts +++ b/src/core/endpoints/data_sync/relationship/get.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.GetRelationshipParameters & { * * @internal */ -export class GetRelationshipRequest< - Response extends DataSync.GetRelationshipResponse, -> extends AbstractRequest { +export class GetRelationshipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/endpoints/data_sync/relationship/patch.ts b/src/core/endpoints/data_sync/relationship/patch.ts index 71063bdcc..da188e510 100644 --- a/src/core/endpoints/data_sync/relationship/patch.ts +++ b/src/core/endpoints/data_sync/relationship/patch.ts @@ -37,9 +37,10 @@ type RequestParameters = DataSync.PatchRelationshipParameters & { * * @internal */ -export class PatchRelationshipRequest< - Response extends DataSync.PatchRelationshipResponse, -> extends AbstractRequest { +export class PatchRelationshipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PATCH }); } @@ -60,11 +61,9 @@ export class PatchRelationshipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/relationship/remove.ts b/src/core/endpoints/data_sync/relationship/remove.ts index 275a15a26..82c555f46 100644 --- a/src/core/endpoints/data_sync/relationship/remove.ts +++ b/src/core/endpoints/data_sync/relationship/remove.ts @@ -33,9 +33,10 @@ type RequestParameters = DataSync.RemoveRelationshipParameters & { * * @internal */ -export class RemoveRelationshipRequest< - Response extends DataSync.RemoveRelationshipResponse, -> extends AbstractRequest { +export class RemoveRelationshipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.DELETE }); } @@ -51,8 +52,7 @@ export class RemoveRelationshipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return Object.keys(headers).length > 0 ? headers : undefined; } diff --git a/src/core/endpoints/data_sync/relationship/update.ts b/src/core/endpoints/data_sync/relationship/update.ts index 1b8041f06..a84379447 100644 --- a/src/core/endpoints/data_sync/relationship/update.ts +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -34,9 +34,10 @@ type RequestParameters = DataSync.UpdateRelationshipParameters & { * * @internal */ -export class UpdateRelationshipRequest< - Response extends DataSync.UpdateRelationshipResponse, -> extends AbstractRequest { +export class UpdateRelationshipRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PUT }); } @@ -55,8 +56,7 @@ export class UpdateRelationshipRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return { ...headers, diff --git a/src/core/endpoints/data_sync/user/create.ts b/src/core/endpoints/data_sync/user/create.ts index ea0ae4f65..5dc9bde73 100644 --- a/src/core/endpoints/data_sync/user/create.ts +++ b/src/core/endpoints/data_sync/user/create.ts @@ -31,9 +31,10 @@ type RequestParameters = DataSync.CreateUserParameters & { * * @internal */ -export class CreateUserRequest< - Response extends DataSync.CreateUserResponse, -> extends AbstractRequest { +export class CreateUserRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.POST }); } @@ -51,8 +52,7 @@ export class CreateUserRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/user/get-all.ts b/src/core/endpoints/data_sync/user/get-all.ts index 3acfe0803..2e8e08fb2 100644 --- a/src/core/endpoints/data_sync/user/get-all.ts +++ b/src/core/endpoints/data_sync/user/get-all.ts @@ -41,9 +41,10 @@ type RequestParameters = DataSync.GetAllUsersParameters & { * * @internal */ -export class GetAllUsersRequest< - Response extends DataSync.GetAllUsersResponse, -> extends AbstractRequest { +export class GetAllUsersRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); diff --git a/src/core/endpoints/data_sync/user/get.ts b/src/core/endpoints/data_sync/user/get.ts index 5fd12ef43..93c4b105f 100644 --- a/src/core/endpoints/data_sync/user/get.ts +++ b/src/core/endpoints/data_sync/user/get.ts @@ -31,9 +31,7 @@ type RequestParameters = DataSync.GetUserParameters & { * * @internal */ -export class GetUserRequest< - Response extends DataSync.GetUserResponse, -> extends AbstractRequest { +export class GetUserRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/patch.ts index 8d97b75aa..8bd5f77a0 100644 --- a/src/core/endpoints/data_sync/user/patch.ts +++ b/src/core/endpoints/data_sync/user/patch.ts @@ -37,9 +37,7 @@ type RequestParameters = DataSync.PatchUserParameters & { * * @internal */ -export class PatchUserRequest< - Response extends DataSync.PatchUserResponse, -> extends AbstractRequest { +export class PatchUserRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PATCH }); } @@ -60,11 +58,9 @@ export class PatchUserRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) - headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; + if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; return { ...headers, diff --git a/src/core/endpoints/data_sync/user/remove.ts b/src/core/endpoints/data_sync/user/remove.ts index d553462ad..de8c33b69 100644 --- a/src/core/endpoints/data_sync/user/remove.ts +++ b/src/core/endpoints/data_sync/user/remove.ts @@ -33,9 +33,10 @@ type RequestParameters = DataSync.RemoveUserParameters & { * * @internal */ -export class RemoveUserRequest< - Response extends DataSync.RemoveUserResponse, -> extends AbstractRequest { +export class RemoveUserRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.DELETE }); } @@ -51,8 +52,7 @@ export class RemoveUserRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return Object.keys(headers).length > 0 ? headers : undefined; } diff --git a/src/core/endpoints/data_sync/user/update.ts b/src/core/endpoints/data_sync/user/update.ts index 34e693d65..333e0f677 100644 --- a/src/core/endpoints/data_sync/user/update.ts +++ b/src/core/endpoints/data_sync/user/update.ts @@ -34,9 +34,10 @@ type RequestParameters = DataSync.UpdateUserParameters & { * * @internal */ -export class UpdateUserRequest< - Response extends DataSync.UpdateUserResponse, -> extends AbstractRequest { +export class UpdateUserRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super({ method: TransportMethod.PUT }); } @@ -55,8 +56,7 @@ export class UpdateUserRequest< protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.ifMatchesEtag) - headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; + if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; return { ...headers, diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index 9f47d0e47..11fb07f1b 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -117,9 +117,7 @@ export default class PubNubDataSync { * * @returns Asynchronous create entity response. */ - public async createEntity( - parameters: DataSync.CreateEntityParameters, - ): Promise; + public async createEntity(parameters: DataSync.CreateEntityParameters): Promise; /** * Create a new Entity. @@ -166,9 +164,7 @@ export default class PubNubDataSync { * * @returns Asynchronous get entity response. */ - public async getEntity( - parameters: DataSync.GetEntityParameters, - ): Promise; + public async getEntity(parameters: DataSync.GetEntityParameters): Promise; /** * Fetch a specific Entity. @@ -215,9 +211,7 @@ export default class PubNubDataSync { * * @returns Asynchronous get all entities response. */ - public async getAllEntities( - parameters: DataSync.GetAllEntitiesParameters, - ): Promise; + public async getAllEntities(parameters: DataSync.GetAllEntitiesParameters): Promise; /** * Fetch a paginated list of Entities for a given Entity Class. @@ -264,9 +258,7 @@ export default class PubNubDataSync { * * @returns Asynchronous update entity response. */ - public async updateEntity( - parameters: DataSync.UpdateEntityParameters, - ): Promise; + public async updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; /** * Update an Entity (full replacement via PUT). @@ -317,9 +309,7 @@ export default class PubNubDataSync { * * @returns Asynchronous patch entity response. */ - public async patchEntity( - parameters: DataSync.PatchEntityParameters, - ): Promise; + public async patchEntity(parameters: DataSync.PatchEntityParameters): Promise; /** * Patch an Entity (partial update via JSON Patch RFC 6902). @@ -368,9 +358,7 @@ export default class PubNubDataSync { * * @returns Asynchronous remove entity response. */ - public async removeEntity( - parameters: DataSync.RemoveEntityParameters, - ): Promise; + public async removeEntity(parameters: DataSync.RemoveEntityParameters): Promise; /** * Remove an Entity. @@ -509,9 +497,7 @@ export default class PubNubDataSync { * * @param callback - Request completion handler callback. */ - public getAllRelationships( - callback: ResultCallback, - ): void; + public getAllRelationships(callback: ResultCallback): void; /** * Fetch a paginated list of Relationships. @@ -1150,9 +1136,7 @@ export default class PubNubDataSync { * * @returns Asynchronous get all channels response. */ - public async getAllChannels( - parameters?: DataSync.GetAllChannelsParameters, - ): Promise; + public async getAllChannels(parameters?: DataSync.GetAllChannelsParameters): Promise; /** * Fetch a paginated list of Channels. diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 7e60516cb..c614aa6e6 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -12,1336 +12,1336 @@ * Filterable field definition for entity classes. */ export type FilterableField = { - /** Unique semantic identifier for the property. */ - name: string; - - /** JSON Pointer (RFC 6901) to the property location. */ - path: string; - - /** Data type of the property value. */ - valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; - - /** - * Whether the property should be indexed for full-text search. - * @default false - */ - enabledAdvancedFiltering?: boolean; - - /** - * Whether the property can have null values. - * @default true - */ - isNullable?: boolean; - }; - - /** - * Cursor-based pagination metadata returned by the server. - */ - export type DataSyncPageMeta = { - /** Opaque cursor for the next page. Null if no more results. */ - next_cursor: string | null; - - /** Opaque cursor for the previous page. Null if first page. */ - prev_cursor: string | null; - - /** Whether there are more results after this page. */ - has_next: boolean; - - /** Whether there are results before this page. */ - has_prev: boolean; - - /** The limit applied to this page. */ - limit: number; - }; - - /** - * HATEOAS navigation links. - */ - export type DataSyncLinks = { - /** Link to the current page. */ - self: string; - - /** Link to the next page, if available. */ - next?: string | null; - - /** Link to the previous page, if available. */ - prev?: string | null; - - /** Additional links for related resources. */ - [key: string]: string | null | undefined; - }; - - /** - * Common parameters for paginated list requests. - */ - type PagedRequestParameters = { - /** Opaque cursor for pagination. Omit for the first page. */ - cursor?: string; - - /** - * Maximum number of items per page. - * @default 20 - * @max 100 - */ - limit?: number; - - /** Filter expression for results. */ - filter?: string; - - /** - * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). - * Example: "+name,-createdAt" - */ - sort?: string; - }; - - /** - * Single-entity response envelope. - */ - type DataSyncEntityResponse = { - /** HTTP status code. */ - status: number; - - /** Response data. */ - data: T; - - /** HATEOAS links. */ - links?: DataSyncLinks; - - /** Response metadata. */ - meta?: DataSyncPageMeta; - }; - + /** Unique semantic identifier for the property. */ + name: string; + + /** JSON Pointer (RFC 6901) to the property location. */ + path: string; + + /** Data type of the property value. */ + valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; + /** - * Paged list response envelope. + * Whether the property should be indexed for full-text search. + * @default false */ - type DataSyncPagedResponse = { - /** HTTP status code. */ - status: number; - - /** Array of response items. */ - data: T[]; - - /** HATEOAS links for pagination. */ - links?: DataSyncLinks; - - /** Cursor-based pagination metadata. */ - meta?: DataSyncPageMeta; - }; - - // -------------------------------------------------------- - // -------------- Patch Operation Types ------------------- - // -------------------------------------------------------- - + enabledAdvancedFiltering?: boolean; + /** - * JSON Patch operation as defined by RFC 6902. - * - * Internal wire format. Developers use `add`/`replace`/`remove` with dot notation instead. - * - * @internal + * Whether the property can have null values. + * @default true */ - export type JsonPatchOperation = { - op: 'add' | 'remove' | 'replace'; - path: string; - value?: unknown; - }; + isNullable?: boolean; +}; + +/** + * Cursor-based pagination metadata returned by the server. + */ +export type DataSyncPageMeta = { + /** Opaque cursor for the next page. Null if no more results. */ + next_cursor: string | null; + + /** Opaque cursor for the previous page. Null if first page. */ + prev_cursor: string | null; + + /** Whether there are more results after this page. */ + has_next: boolean; + + /** Whether there are results before this page. */ + has_prev: boolean; + + /** The limit applied to this page. */ + limit: number; +}; + +/** + * HATEOAS navigation links. + */ +export type DataSyncLinks = { + /** Link to the current page. */ + self: string; + + /** Link to the next page, if available. */ + next?: string | null; + + /** Link to the previous page, if available. */ + prev?: string | null; + + /** Additional links for related resources. */ + [key: string]: string | null | undefined; +}; + +/** + * Common parameters for paginated list requests. + */ +type PagedRequestParameters = { + /** Opaque cursor for pagination. Omit for the first page. */ + cursor?: string; /** - * Convert dot-notation path to JSON Pointer (RFC 6901). - * - * "config.ttlSec" → "/config/ttlSec" - * "filterableFields.0.name" → "/filterableFields/0/name" - * - * @internal + * Maximum number of items per page. + * @default 20 + * @max 100 */ - export function toJsonPointer(dotPath: string): string { - return '/' + dotPath.split('.').join('/'); - } + limit?: number; + + /** Filter expression for results. */ + filter?: string; /** - * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). - * - * - Each key in `add` becomes an "add" operation. - * - Each key in `replace` becomes a "replace" operation. - * - Each entry in `remove` becomes a "remove" operation. - * - * @internal + * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). + * Example: "+name,-createdAt" */ - export function toJsonPatchOperations( - add?: Record, - replace?: Record, - remove?: string[], - ): JsonPatchOperation[] { - const ops: JsonPatchOperation[] = []; - - if (add) { - for (const [dotPath, value] of Object.entries(add)) { - ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); - } - } + sort?: string; +}; + +/** + * Single-entity response envelope. + */ +type DataSyncEntityResponse = { + /** HTTP status code. */ + status: number; + + /** Response data. */ + data: T; + + /** HATEOAS links. */ + links?: DataSyncLinks; + + /** Response metadata. */ + meta?: DataSyncPageMeta; +}; + +/** + * Paged list response envelope. + */ +type DataSyncPagedResponse = { + /** HTTP status code. */ + status: number; + + /** Array of response items. */ + data: T[]; + + /** HATEOAS links for pagination. */ + links?: DataSyncLinks; + + /** Cursor-based pagination metadata. */ + meta?: DataSyncPageMeta; +}; - if (replace) { - for (const [dotPath, value] of Object.entries(replace)) { - ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); - } +// -------------------------------------------------------- +// -------------- Patch Operation Types ------------------- +// -------------------------------------------------------- + +/** + * JSON Patch operation as defined by RFC 6902. + * + * Internal wire format. Developers use `add`/`replace`/`remove` with dot notation instead. + * + * @internal + */ +export type JsonPatchOperation = { + op: 'add' | 'remove' | 'replace'; + path: string; + value?: unknown; +}; + +/** + * Convert dot-notation path to JSON Pointer (RFC 6901). + * + * "config.ttlSec" → "/config/ttlSec" + * "filterableFields.0.name" → "/filterableFields/0/name" + * + * @internal + */ +export function toJsonPointer(dotPath: string): string { + return '/' + dotPath.split('.').join('/'); +} + +/** + * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). + * + * - Each key in `add` becomes an "add" operation. + * - Each key in `replace` becomes a "replace" operation. + * - Each entry in `remove` becomes a "remove" operation. + * + * @internal + */ +export function toJsonPatchOperations( + add?: Record, + replace?: Record, + remove?: string[], +): JsonPatchOperation[] { + const ops: JsonPatchOperation[] = []; + + if (add) { + for (const [dotPath, value] of Object.entries(add)) { + ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); } + } - if (remove) { - for (const dotPath of remove) { - ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); - } + if (replace) { + for (const [dotPath, value] of Object.entries(replace)) { + ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); } + } - return ops; + if (remove) { + for (const dotPath of remove) { + ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); + } } - // -------------------------------------------------------- - // ------------------- Entity Types ----------------------- - // -------------------------------------------------------- - + return ops; +} + +// -------------------------------------------------------- +// ------------------- Entity Types ----------------------- +// -------------------------------------------------------- + +/** + * Entity properties for create requests. + * + * Includes `entityClass` since it must be set at creation time and is immutable afterward. + */ +export type CreateEntityProperties = { + /** Entity class this entity belongs to. */ + entityClass: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; + +/** + * Entity properties for update (PUT) requests. + * + * `entityClass` is immutable after creation and therefore excluded from updates. + */ +export type UpdateEntityProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; + +/** + * Entity resource as returned from the server. + */ +export type EntityObject = { + /** Unique identifier (UUID). */ + id: string; + + /** Entity class this entity belongs to. */ + entityClass: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the entity was created (ISO 8601). */ + createdAt: string; + + /** Date and time the entity was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ + expiresAt?: string; +}; + +// ----- Entity Request Parameters ----- + +/** + * Create Entity request parameters. + */ +export type CreateEntityParameters = { /** - * Entity properties for create requests. + * Entity properties to create. * - * Includes `entityClass` since it must be set at creation time and is immutable afterward. + * All entity properties go inside `entity` because they map to the request body envelope. + * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation + * posts to a collection URL with all fields in the body. */ - export type CreateEntityProperties = { - /** Entity class this entity belongs to. */ - entityClass: string; - - /** Version of the entity class schema. */ - entityClassVersion: number; - - /** Optional lifecycle status. */ - status?: string; - - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; + entity: CreateEntityProperties & { + /** + * Optional entity ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; }; - + /** - * Entity properties for update (PUT) requests. - * - * `entityClass` is immutable after creation and therefore excluded from updates. + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. */ - export type UpdateEntityProperties = { - /** Version of the entity class schema. */ - entityClassVersion: number; - - /** Optional lifecycle status. */ - status?: string; - - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; - }; - + idempotencyKey?: string; +}; + +/** + * Get Entity request parameters. + */ +export type GetEntityParameters = { + /** Entity ID. */ + id: string; +}; + +/** + * Get All Entities request parameters. + * + * `entityClass` is required — entities are always listed within the context of their class. + */ +export type GetAllEntitiesParameters = PagedRequestParameters & { + /** Entity class name to filter by (required). */ + entityClass: string; + /** - * Entity resource as returned from the server. + * Entity class version. If not provided, the server returns entities for the latest version. */ - export type EntityObject = { - /** Unique identifier (UUID). */ - id: string; - - /** Entity class this entity belongs to. */ - entityClass: string; - - /** Version of the entity class schema. */ - entityClassVersion: number; - - /** Lifecycle status. */ - status?: string; - - /** User-defined JSON payload. */ - payload?: Record; - - /** Date and time the entity was created (ISO 8601). */ - createdAt: string; - - /** Date and time the entity was last updated (ISO 8601). */ - updatedAt: string; - - /** Content fingerprint for optimistic concurrency control. */ - eTag: string; - - /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ - expiresAt?: string; - }; - - // ----- Entity Request Parameters ----- - + entityClassVersion?: number; + /** - * Create Entity request parameters. + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. */ - export type CreateEntityParameters = { - /** - * Entity properties to create. - * - * All entity properties go inside `entity` because they map to the request body envelope. - * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation - * posts to a collection URL with all fields in the body. - */ - entity: CreateEntityProperties & { - /** - * Optional entity ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; - }; - + filterAdvanced?: string; +}; + +/** + * Update Entity request parameters (full replacement via PUT). + * + * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, + * and `payload` can be updated. + */ +export type UpdateEntityParameters = { + /** Entity ID. */ + id: string; + + /** Complete entity properties for replacement (excludes immutable `entityClass`). */ + entity: UpdateEntityProperties; + /** - * Get Entity request parameters. + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. */ - export type GetEntityParameters = { - /** Entity ID. */ - id: string; - }; - + ifMatchesEtag?: string; +}; + +/** + * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ +export type PatchEntityParameters = { + /** Entity ID. */ + id: string; + /** - * Get All Entities request parameters. + * Fields to add, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "add" operations. * - * `entityClass` is required — entities are always listed within the context of their class. + * @example + * ```typescript + * add: { + * 'payload.tags.0': 'priority', + * 'payload.profile.displayName': 'Alice', + * } + * ``` */ - export type GetAllEntitiesParameters = PagedRequestParameters & { - /** Entity class name to filter by (required). */ - entityClass: string; - - /** - * Entity class version. If not provided, the server returns entities for the latest version. - */ - entityClassVersion?: number; - - /** - * Advanced filter expression for complex queries. - * - * Supports logical operators and nested conditions for sophisticated filtering - * beyond what the basic `filter` parameter provides. - */ - filterAdvanced?: string; - }; - + add?: Record; + /** - * Update Entity request parameters (full replacement via PUT). + * Fields to replace, using dot-notation keys. * - * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, - * and `payload` can be updated. + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * replace: { + * 'status': 'active', + * 'payload.score': 300, + * } + * ``` */ - export type UpdateEntityParameters = { - /** Entity ID. */ - id: string; - - /** Complete entity properties for replacement (excludes immutable `entityClass`). */ - entity: UpdateEntityProperties; - - /** - * ETag for optimistic concurrency control. - * If provided, the update only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - }; - + replace?: Record; + /** - * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * Array of dot-notation field paths to remove. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * The SDK converts these to JSON Patch "remove" operations. * - * At least one of `add`, `replace`, or `remove` must be provided. + * @example + * ```typescript + * remove: ['payload.tempFlag', 'payload.legacyField'] + * ``` */ - export type PatchEntityParameters = { - /** Entity ID. */ - id: string; - - /** - * Fields to add, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field. - * The SDK converts these to JSON Patch "add" operations. - * - * @example - * ```typescript - * add: { - * 'payload.tags.0': 'priority', - * 'payload.profile.displayName': 'Alice', - * } - * ``` - */ - add?: Record; + remove?: string[]; - /** - * Fields to replace, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field. - * The SDK converts these to JSON Patch "replace" operations. - * - * @example - * ```typescript - * replace: { - * 'status': 'active', - * 'payload.score': 300, - * } - * ``` - */ - replace?: Record; + /** + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; - /** - * Array of dot-notation field paths to remove. - * - * The SDK converts these to JSON Patch "remove" operations. - * - * @example - * ```typescript - * remove: ['payload.tempFlag', 'payload.legacyField'] - * ``` - */ - remove?: string[]; - - /** - * ETag for optimistic concurrency control. - * If provided, the patch only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; - }; - /** - * Remove Entity request parameters. + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. */ - export type RemoveEntityParameters = { - /** Entity ID. */ - id: string; - - /** - * ETag for optimistic concurrency control. - * If provided, the delete only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - }; - - // ----- Entity Response Types ----- - - /** Response for creating an entity. */ - export type CreateEntityResponse = DataSyncEntityResponse; - - /** Response for getting a single entity. */ - export type GetEntityResponse = DataSyncEntityResponse; - - /** Response for listing entities. */ - export type GetAllEntitiesResponse = DataSyncPagedResponse; - - /** Response for updating an entity (PUT). */ - export type UpdateEntityResponse = DataSyncEntityResponse; - - /** Response for patching an entity (PATCH). */ - export type PatchEntityResponse = DataSyncEntityResponse; - - /** Response for removing an entity. */ - export type RemoveEntityResponse = { - /** HTTP status code. */ - status: number; - }; - - // -------------------------------------------------------- - // --------------- Relationship Types --------------------- - // -------------------------------------------------------- - + idempotencyKey?: string; +}; + +/** + * Remove Entity request parameters. + */ +export type RemoveEntityParameters = { + /** Entity ID. */ + id: string; + /** - * Relationship properties for create requests. - * - * Both `entityAId` and `entityBId` must be set at creation time. + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. */ - export type CreateRelationshipProperties = { - /** First entity ID in the relationship. */ - entityAId: string; + ifMatchesEtag?: string; +}; - /** Second entity ID in the relationship. */ - entityBId: string; +// ----- Entity Response Types ----- - /** Relationship class this relationship belongs to. */ - relationshipClass: string; +/** Response for creating an entity. */ +export type CreateEntityResponse = DataSyncEntityResponse; - /** Version of the relationship class schema. */ - relationshipClassVersion: number; +/** Response for getting a single entity. */ +export type GetEntityResponse = DataSyncEntityResponse; - /** Optional lifecycle status. */ - status?: string; +/** Response for listing entities. */ +export type GetAllEntitiesResponse = DataSyncPagedResponse; - /** User-defined JSON payload. */ - payload?: Record; - }; - - /** - * Relationship properties for update (PUT) requests. - * - * PUT is a full replacement — `entityAId` and `entityBId` are required. - */ - export type UpdateRelationshipProperties = { - /** First entity ID in the relationship. */ - entityAId: string; - - /** Second entity ID in the relationship. */ - entityBId: string; - - /** Optional lifecycle status. */ - status?: string; - - /** User-defined JSON payload. */ - payload?: Record; - }; - - /** - * Relationship resource as returned from the server. - */ - export type RelationshipObject = { - /** Unique identifier. */ - id: string; +/** Response for updating an entity (PUT). */ +export type UpdateEntityResponse = DataSyncEntityResponse; + +/** Response for patching an entity (PATCH). */ +export type PatchEntityResponse = DataSyncEntityResponse; - /** First entity ID in the relationship. */ - entityAId: string; +/** Response for removing an entity. */ +export type RemoveEntityResponse = { + /** HTTP status code. */ + status: number; +}; - /** Second entity ID in the relationship. */ - entityBId: string; +// -------------------------------------------------------- +// --------------- Relationship Types --------------------- +// -------------------------------------------------------- + +/** + * Relationship properties for create requests. + * + * Both `entityAId` and `entityBId` must be set at creation time. + */ +export type CreateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Relationship class this relationship belongs to. */ + relationshipClass: string; - /** Relationship class this relationship belongs to. */ - relationshipClass: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; - /** Version of the relationship class schema. */ - relationshipClassVersion: number; + /** Optional lifecycle status. */ + status?: string; - /** Lifecycle status. */ - status?: string; + /** User-defined JSON payload. */ + payload?: Record; +}; - /** User-defined JSON payload. */ - payload?: Record; +/** + * Relationship properties for update (PUT) requests. + * + * PUT is a full replacement — `entityAId` and `entityBId` are required. + */ +export type UpdateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; - /** Date and time the relationship was created (ISO 8601). */ - createdAt: string; + /** Second entity ID in the relationship. */ + entityBId: string; - /** Date and time the relationship was last updated (ISO 8601). */ - updatedAt: string; + /** Optional lifecycle status. */ + status?: string; - /** Content fingerprint for optimistic concurrency control. */ - eTag: string; + /** User-defined JSON payload. */ + payload?: Record; +}; - /** Auto-deletion timestamp (ISO 8601). */ - expiresAt?: string; - }; - - // ----- Relationship Request Parameters ----- - +/** + * Relationship resource as returned from the server. + */ +export type RelationshipObject = { + /** Unique identifier. */ + id: string; + + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Relationship class this relationship belongs to. */ + relationshipClass: string; + + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the relationship was created (ISO 8601). */ + createdAt: string; + + /** Date and time the relationship was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; +}; + +// ----- Relationship Request Parameters ----- + +/** + * Create Relationship request parameters. + */ +export type CreateRelationshipParameters = { /** - * Create Relationship request parameters. + * Relationship properties to create. + * + * All relationship properties go inside `relationship` because they map to the request body envelope. */ - export type CreateRelationshipParameters = { - /** - * Relationship properties to create. - * - * All relationship properties go inside `relationship` because they map to the request body envelope. - */ - relationship: CreateRelationshipProperties & { - /** - * Optional relationship ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; - + relationship: CreateRelationshipProperties & { /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. + * Optional relationship ID. + * Server auto-generates a UUID if not provided. */ - idempotencyKey?: string; + id?: string; }; - + /** - * Get Relationship request parameters. + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. */ - export type GetRelationshipParameters = { - /** Relationship ID. */ - id: string; - }; - + idempotencyKey?: string; +}; + +/** + * Get Relationship request parameters. + */ +export type GetRelationshipParameters = { + /** Relationship ID. */ + id: string; +}; + +/** + * Get All Relationships request parameters. + * + * All parameters are optional — relationships can be listed without any filters. + */ +export type GetAllRelationshipsParameters = PagedRequestParameters & { + /** Filter relationships by first entity ID. */ + entityAId?: string; + + /** Filter relationships by second entity ID. */ + entityBId?: string; + /** - * Get All Relationships request parameters. + * Advanced filter expression for complex queries. * - * All parameters are optional — relationships can be listed without any filters. + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. */ - export type GetAllRelationshipsParameters = PagedRequestParameters & { - /** Filter relationships by first entity ID. */ - entityAId?: string; - - /** Filter relationships by second entity ID. */ - entityBId?: string; - - /** - * Advanced filter expression for complex queries. - * - * Supports logical operators and nested conditions for sophisticated filtering - * beyond what the basic `filter` parameter provides. - */ - filterAdvanced?: string; - }; - + filterAdvanced?: string; +}; + +/** + * Update Relationship request parameters (full replacement via PUT). + */ +export type UpdateRelationshipParameters = { + /** Relationship ID. */ + id: string; + + /** Complete relationship properties for replacement. */ + relationship: UpdateRelationshipProperties; + /** - * Update Relationship request parameters (full replacement via PUT). + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. */ - export type UpdateRelationshipParameters = { - /** Relationship ID. */ - id: string; - - /** Complete relationship properties for replacement. */ - relationship: UpdateRelationshipProperties; - - /** - * ETag for optimistic concurrency control. - * If provided, the update only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - }; - + ifMatchesEtag?: string; +}; + +/** + * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ +export type PatchRelationshipParameters = { + /** Relationship ID. */ + id: string; + /** - * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * Fields to add, using dot-notation keys. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "add" operations. * - * At least one of `add`, `replace`, or `remove` must be provided. + * @example + * ```typescript + * add: { + * 'tags.0': 'mentor', + * } + * ``` */ - export type PatchRelationshipParameters = { - /** Relationship ID. */ - id: string; - - /** - * Fields to add, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field within `payload`. - * The SDK converts these to JSON Patch "add" operations. - * - * @example - * ```typescript - * add: { - * 'tags.0': 'mentor', - * } - * ``` - */ - add?: Record; + add?: Record; - /** - * Fields to replace, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field within `payload`. - * The SDK converts these to JSON Patch "replace" operations. - * - * @example - * ```typescript - * replace: { - * 'role': 'admin', - * 'permissions.read': true, - * } - * ``` - */ - replace?: Record; - - /** - * Array of dot-notation field paths to remove from `payload`. - * - * The SDK converts these to JSON Patch "remove" operations. - * - * @example - * ```typescript - * remove: ['tempFlag', 'legacyField'] - * ``` - */ - remove?: string[]; - - /** - * ETag for optimistic concurrency control. - * If provided, the patch only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; - }; - /** - * Remove Relationship request parameters. + * Fields to replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * replace: { + * 'role': 'admin', + * 'permissions.read': true, + * } + * ``` */ - export type RemoveRelationshipParameters = { - /** Relationship ID. */ - id: string; - - /** - * ETag for optimistic concurrency control. - * If provided, the delete only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - }; - - // ----- Relationship Response Types ----- - - /** Response for creating a relationship. */ - export type CreateRelationshipResponse = DataSyncEntityResponse; - - /** Response for getting a single relationship. */ - export type GetRelationshipResponse = DataSyncEntityResponse; - - /** Response for listing relationships. */ - export type GetAllRelationshipsResponse = DataSyncPagedResponse; - - /** Response for updating a relationship (PUT). */ - export type UpdateRelationshipResponse = DataSyncEntityResponse; - - /** Response for patching a relationship (PATCH). */ - export type PatchRelationshipResponse = DataSyncEntityResponse; - - /** Response for removing a relationship. */ - export type RemoveRelationshipResponse = { - /** HTTP status code. */ - status: number; - }; + replace?: Record; - // -------------------------------------------------------- - // ------------------ User Types -------------------------- - // -------------------------------------------------------- + /** + * Array of dot-notation field paths to remove from `payload`. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['tempFlag', 'legacyField'] + * ``` + */ + remove?: string[]; /** - * User properties for create requests. + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. */ - export type CreateUserProperties = { - /** Version of the entity class schema. */ - entityClassVersion: number; + ifMatchesEtag?: string; - /** Optional lifecycle status. */ - status?: string; + /** + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. + */ + idempotencyKey?: string; +}; - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; - }; +/** + * Remove Relationship request parameters. + */ +export type RemoveRelationshipParameters = { + /** Relationship ID. */ + id: string; /** - * User resource as returned from the server. + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. */ - export type UserObject = { - /** Unique identifier (UUID). */ - id: string; + ifMatchesEtag?: string; +}; - /** Version of the entity class schema. */ - entityClassVersion: number; +// ----- Relationship Response Types ----- - /** Lifecycle status. */ - status?: string; +/** Response for creating a relationship. */ +export type CreateRelationshipResponse = DataSyncEntityResponse; - /** User-defined JSON payload. */ - payload?: Record; +/** Response for getting a single relationship. */ +export type GetRelationshipResponse = DataSyncEntityResponse; - /** Date and time the user was created (ISO 8601). */ - createdAt: string; +/** Response for listing relationships. */ +export type GetAllRelationshipsResponse = DataSyncPagedResponse; - /** Date and time the user was last updated (ISO 8601). */ - updatedAt: string; +/** Response for updating a relationship (PUT). */ +export type UpdateRelationshipResponse = DataSyncEntityResponse; - /** Content fingerprint for optimistic concurrency control. */ - eTag: string; +/** Response for patching a relationship (PATCH). */ +export type PatchRelationshipResponse = DataSyncEntityResponse; - /** Auto-deletion timestamp (ISO 8601). Users expire at this time. */ - expiresAt?: string; - }; +/** Response for removing a relationship. */ +export type RemoveRelationshipResponse = { + /** HTTP status code. */ + status: number; +}; + +// -------------------------------------------------------- +// ------------------ User Types -------------------------- +// -------------------------------------------------------- + +/** + * User properties for create requests. + */ +export type CreateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Optional lifecycle status. */ + status?: string; + + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; - // ----- User Request Parameters ----- +/** + * User resource as returned from the server. + */ +export type UserObject = { + /** Unique identifier (UUID). */ + id: string; + + /** Version of the entity class schema. */ + entityClassVersion: number; + + /** Lifecycle status. */ + status?: string; + + /** User-defined JSON payload. */ + payload?: Record; + + /** Date and time the user was created (ISO 8601). */ + createdAt: string; + + /** Date and time the user was last updated (ISO 8601). */ + updatedAt: string; + + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). Users expire at this time. */ + expiresAt?: string; +}; + +// ----- User Request Parameters ----- + +/** + * Create User request parameters. + */ +export type CreateUserParameters = { /** - * Create User request parameters. + * User properties to create. */ - export type CreateUserParameters = { + user: CreateUserProperties & { /** - * User properties to create. + * Optional user ID. + * Server auto-generates a UUID if not provided. */ - user: CreateUserProperties & { - /** - * Optional user ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; + id?: string; }; /** - * User properties for update (PUT) requests. + * UUIDv4 idempotency key for safe retries. + * Auto-generated if not provided. */ - export type UpdateUserProperties = { - /** Version of the entity class schema. */ - entityClassVersion: number; + idempotencyKey?: string; +}; + +/** + * User properties for update (PUT) requests. + */ +export type UpdateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; - /** Optional lifecycle status. */ - status?: string; + /** Optional lifecycle status. */ + status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; - }; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; + +/** + * Get User request parameters. + */ +export type GetUserParameters = { + /** User ID. */ + id: string; +}; +/** + * Get All Users request parameters. + */ +export type GetAllUsersParameters = PagedRequestParameters & { /** - * Get User request parameters. + * Entity class version. If not provided, the server returns users for the latest version. */ - export type GetUserParameters = { - /** User ID. */ - id: string; - }; + entityClassVersion?: number; /** - * Get All Users request parameters. + * Advanced filter expression for complex queries. */ - export type GetAllUsersParameters = PagedRequestParameters & { - /** - * Entity class version. If not provided, the server returns users for the latest version. - */ - entityClassVersion?: number; + filterAdvanced?: string; +}; - /** - * Advanced filter expression for complex queries. - */ - filterAdvanced?: string; - }; +/** + * Update User request parameters (full replacement via PUT). + */ +export type UpdateUserParameters = { + /** User ID. */ + id: string; + + /** Complete user properties for replacement. */ + user: UpdateUserProperties; /** - * Update User request parameters (full replacement via PUT). + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. */ - export type UpdateUserParameters = { - /** User ID. */ - id: string; - - /** Complete user properties for replacement. */ - user: UpdateUserProperties; + ifMatchesEtag?: string; +}; - /** - * ETag for optimistic concurrency control. - * If provided, the update only succeeds if the server's ETag matches. - */ - ifMatchesEtag?: string; - }; +/** + * Patch User request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ +export type PatchUserParameters = { + /** User ID. */ + id: string; /** - * Patch User request parameters (partial update via JSON Patch RFC 6902). - * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. - * - * At least one of `add`, `replace`, or `remove` must be provided. + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. */ - export type PatchUserParameters = { - /** User ID. */ - id: string; + add?: Record; - /** - * Fields to add, using dot-notation keys. - * The SDK converts these to JSON Patch "add" operations. - */ - add?: Record; + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; - /** - * Fields to replace, using dot-notation keys. - * The SDK converts these to JSON Patch "replace" operations. - */ - replace?: Record; + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; - /** - * Array of dot-notation field paths to remove. - * The SDK converts these to JSON Patch "remove" operations. - */ - remove?: string[]; + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; + /** + * UUIDv4 idempotency key for safe retries. + */ + idempotencyKey?: string; +}; - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; - }; +/** + * Remove User request parameters. + */ +export type RemoveUserParameters = { + /** User ID. */ + id: string; /** - * Remove User request parameters. + * ETag for optimistic concurrency control. */ - export type RemoveUserParameters = { - /** User ID. */ - id: string; + ifMatchesEtag?: string; +}; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; - }; - - // ----- User Response Types ----- +// ----- User Response Types ----- - /** Response for creating a user. */ - export type CreateUserResponse = DataSyncEntityResponse; +/** Response for creating a user. */ +export type CreateUserResponse = DataSyncEntityResponse; - /** Response for getting a single user. */ - export type GetUserResponse = DataSyncEntityResponse; +/** Response for getting a single user. */ +export type GetUserResponse = DataSyncEntityResponse; - /** Response for listing users. */ - export type GetAllUsersResponse = DataSyncPagedResponse; +/** Response for listing users. */ +export type GetAllUsersResponse = DataSyncPagedResponse; - /** Response for updating a user (PUT). */ - export type UpdateUserResponse = DataSyncEntityResponse; +/** Response for updating a user (PUT). */ +export type UpdateUserResponse = DataSyncEntityResponse; - /** Response for patching a user (PATCH). */ - export type PatchUserResponse = DataSyncEntityResponse; +/** Response for patching a user (PATCH). */ +export type PatchUserResponse = DataSyncEntityResponse; - /** Response for removing a user. */ - export type RemoveUserResponse = { - /** HTTP status code. */ - status: number; - }; +/** Response for removing a user. */ +export type RemoveUserResponse = { + /** HTTP status code. */ + status: number; +}; - // -------------------------------------------------------- - // ----------------- Channel Types ------------------------ - // -------------------------------------------------------- +// -------------------------------------------------------- +// ----------------- Channel Types ------------------------ +// -------------------------------------------------------- - /** - * Channel properties for create requests. - */ - export type CreateChannelProperties = { - /** Version of the entity class schema. */ - entityClassVersion: number; +/** + * Channel properties for create requests. + */ +export type CreateChannelProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; - /** Optional lifecycle status. */ - status?: string; + /** Optional lifecycle status. */ + status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; - }; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; - /** - * Channel properties for update (PUT) requests. - */ - export type UpdateChannelProperties = { - /** Version of the entity class schema. */ - entityClassVersion: number; +/** + * Channel properties for update (PUT) requests. + */ +export type UpdateChannelProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; - /** Optional lifecycle status. */ - status?: string; + /** Optional lifecycle status. */ + status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ - payload?: Record; - }; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; +}; - /** - * Channel resource as returned from the server. - */ - export type ChannelObject = { - /** Unique identifier (UUID). */ - id: string; +/** + * Channel resource as returned from the server. + */ +export type ChannelObject = { + /** Unique identifier (UUID). */ + id: string; - /** Version of the entity class schema. */ - entityClassVersion: number; + /** Version of the entity class schema. */ + entityClassVersion: number; - /** Lifecycle status. */ - status?: string; + /** Lifecycle status. */ + status?: string; - /** User-defined JSON payload. */ - payload?: Record; + /** User-defined JSON payload. */ + payload?: Record; - /** Date and time the channel was created (ISO 8601). */ - createdAt: string; + /** Date and time the channel was created (ISO 8601). */ + createdAt: string; - /** Date and time the channel was last updated (ISO 8601). */ - updatedAt: string; + /** Date and time the channel was last updated (ISO 8601). */ + updatedAt: string; - /** Content fingerprint for optimistic concurrency control. */ - eTag: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; - /** Auto-deletion timestamp (ISO 8601). Channels expire at this time. */ - expiresAt?: string; - }; + /** Auto-deletion timestamp (ISO 8601). Channels expire at this time. */ + expiresAt?: string; +}; - // ----- Channel Request Parameters ----- +// ----- Channel Request Parameters ----- +/** + * Create Channel request parameters. + */ +export type CreateChannelParameters = { /** - * Create Channel request parameters. + * Channel properties to create. */ - export type CreateChannelParameters = { + channel: CreateChannelProperties & { /** - * Channel properties to create. + * Optional channel ID. + * Server auto-generates a UUID if not provided. */ - channel: CreateChannelProperties & { - /** - * Optional channel ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; + id?: string; }; /** - * Get Channel request parameters. + * UUIDv4 idempotency key for safe retries. */ - export type GetChannelParameters = { - /** Channel ID. */ - id: string; - }; + idempotencyKey?: string; +}; +/** + * Get Channel request parameters. + */ +export type GetChannelParameters = { + /** Channel ID. */ + id: string; +}; + +/** + * Get All Channels request parameters. + */ +export type GetAllChannelsParameters = PagedRequestParameters & { /** - * Get All Channels request parameters. + * Entity class version. If not provided, the server returns channels for the latest version. */ - export type GetAllChannelsParameters = PagedRequestParameters & { - /** - * Entity class version. If not provided, the server returns channels for the latest version. - */ - entityClassVersion?: number; - - /** - * Advanced filter expression for complex queries. - */ - filterAdvanced?: string; - }; + entityClassVersion?: number; /** - * Update Channel request parameters (full replacement via PUT). + * Advanced filter expression for complex queries. */ - export type UpdateChannelParameters = { - /** Channel ID. */ - id: string; + filterAdvanced?: string; +}; - /** Complete channel properties for replacement. */ - channel: UpdateChannelProperties; +/** + * Update Channel request parameters (full replacement via PUT). + */ +export type UpdateChannelParameters = { + /** Channel ID. */ + id: string; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; - }; + /** Complete channel properties for replacement. */ + channel: UpdateChannelProperties; /** - * Patch Channel request parameters (partial update via JSON Patch RFC 6902). - * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * - * At least one of `add`, `replace`, or `remove` must be provided. + * ETag for optimistic concurrency control. */ - export type PatchChannelParameters = { - /** Channel ID. */ - id: string; + ifMatchesEtag?: string; +}; - /** - * Fields to add, using dot-notation keys. - * The SDK converts these to JSON Patch "add" operations. - */ - add?: Record; +/** + * Patch Channel request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ +export type PatchChannelParameters = { + /** Channel ID. */ + id: string; - /** - * Fields to replace, using dot-notation keys. - * The SDK converts these to JSON Patch "replace" operations. - */ - replace?: Record; + /** + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; - /** - * Array of dot-notation field paths to remove. - * The SDK converts these to JSON Patch "remove" operations. - */ - remove?: string[]; + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; - }; + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; /** - * Remove Channel request parameters. + * UUIDv4 idempotency key for safe retries. */ - export type RemoveChannelParameters = { - /** Channel ID. */ - id: string; + idempotencyKey?: string; +}; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; - }; +/** + * Remove Channel request parameters. + */ +export type RemoveChannelParameters = { + /** Channel ID. */ + id: string; - // ----- Channel Response Types ----- + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; +}; - /** Response for creating a channel. */ - export type CreateChannelResponse = DataSyncEntityResponse; +// ----- Channel Response Types ----- - /** Response for getting a single channel. */ - export type GetChannelResponse = DataSyncEntityResponse; +/** Response for creating a channel. */ +export type CreateChannelResponse = DataSyncEntityResponse; - /** Response for listing channels. */ - export type GetAllChannelsResponse = DataSyncPagedResponse; +/** Response for getting a single channel. */ +export type GetChannelResponse = DataSyncEntityResponse; - /** Response for updating a channel (PUT). */ - export type UpdateChannelResponse = DataSyncEntityResponse; +/** Response for listing channels. */ +export type GetAllChannelsResponse = DataSyncPagedResponse; - /** Response for patching a channel (PATCH). */ - export type PatchChannelResponse = DataSyncEntityResponse; +/** Response for updating a channel (PUT). */ +export type UpdateChannelResponse = DataSyncEntityResponse; - /** Response for removing a channel. */ - export type RemoveChannelResponse = { - /** HTTP status code. */ - status: number; - }; +/** Response for patching a channel (PATCH). */ +export type PatchChannelResponse = DataSyncEntityResponse; - // -------------------------------------------------------- - // ---------------- Membership Types ---------------------- - // -------------------------------------------------------- +/** Response for removing a channel. */ +export type RemoveChannelResponse = { + /** HTTP status code. */ + status: number; +}; - /** - * Membership properties for create requests. - * - * Both `userId` and `channelId` must be set at creation time. - */ - export type CreateMembershipProperties = { - /** User ID reference. */ - userId: string; +// -------------------------------------------------------- +// ---------------- Membership Types ---------------------- +// -------------------------------------------------------- - /** Channel ID reference. */ - channelId: string; +/** + * Membership properties for create requests. + * + * Both `userId` and `channelId` must be set at creation time. + */ +export type CreateMembershipProperties = { + /** User ID reference. */ + userId: string; - /** Version of the Membership relationship class. */ - relationshipClassVersion: number; + /** Channel ID reference. */ + channelId: string; - /** Optional lifecycle status. */ - status?: string; + /** Version of the Membership relationship class. */ + relationshipClassVersion: number; - /** User-defined JSON payload. */ - payload?: Record; - }; + /** Optional lifecycle status. */ + status?: string; - /** - * Membership properties for update (PUT) requests. - * - * PUT is a full replacement — `userId` and `channelId` are required. - */ - export type UpdateMembershipProperties = { - /** User ID reference. */ - userId: string; + /** User-defined JSON payload. */ + payload?: Record; +}; - /** Channel ID reference. */ - channelId: string; +/** + * Membership properties for update (PUT) requests. + * + * PUT is a full replacement — `userId` and `channelId` are required. + */ +export type UpdateMembershipProperties = { + /** User ID reference. */ + userId: string; - /** Optional lifecycle status. */ - status?: string; + /** Channel ID reference. */ + channelId: string; - /** User-defined JSON payload. */ - payload?: Record; - }; + /** Optional lifecycle status. */ + status?: string; - /** - * Membership resource as returned from the server. - * - * Note: server responses are shaped like a relationship — `entityAId` corresponds - * to `channelId` and `entityBId` corresponds to `userId`. - */ - export type MembershipObject = { - /** Unique identifier. */ - id: string; + /** User-defined JSON payload. */ + payload?: Record; +}; - /** Channel ID (server returns this as `entityAId`). */ - entityAId: string; +/** + * Membership resource as returned from the server. + * + * Note: server responses are shaped like a relationship — `entityAId` corresponds + * to `channelId` and `entityBId` corresponds to `userId`. + */ +export type MembershipObject = { + /** Unique identifier. */ + id: string; - /** User ID (server returns this as `entityBId`). */ - entityBId: string; + /** Channel ID (server returns this as `entityAId`). */ + entityAId: string; - /** Relationship class. */ - relationshipClass: string; + /** User ID (server returns this as `entityBId`). */ + entityBId: string; - /** Version of the relationship class schema. */ - relationshipClassVersion: number; + /** Relationship class. */ + relationshipClass: string; - /** Lifecycle status. */ - status?: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; - /** User-defined JSON payload. */ - payload?: Record; + /** Lifecycle status. */ + status?: string; - /** Date and time the membership was created (ISO 8601). */ - createdAt: string; + /** User-defined JSON payload. */ + payload?: Record; - /** Date and time the membership was last updated (ISO 8601). */ - updatedAt: string; + /** Date and time the membership was created (ISO 8601). */ + createdAt: string; - /** Content fingerprint for optimistic concurrency control. */ - eTag: string; + /** Date and time the membership was last updated (ISO 8601). */ + updatedAt: string; - /** Auto-deletion timestamp (ISO 8601). */ - expiresAt?: string; - }; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; - // ----- Membership Request Parameters ----- + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; +}; +// ----- Membership Request Parameters ----- + +/** + * Create Membership request parameters. + */ +export type CreateMembershipParameters = { /** - * Create Membership request parameters. + * Membership properties to create. */ - export type CreateMembershipParameters = { - /** - * Membership properties to create. - */ - membership: CreateMembershipProperties & { - /** - * Optional membership ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; - + membership: CreateMembershipProperties & { /** - * UUIDv4 idempotency key for safe retries. + * Optional membership ID. + * Server auto-generates a UUID if not provided. */ - idempotencyKey?: string; + id?: string; }; /** - * Get Membership request parameters. + * UUIDv4 idempotency key for safe retries. */ - export type GetMembershipParameters = { - /** Membership ID. */ - id: string; - }; + idempotencyKey?: string; +}; - /** - * Get All Memberships request parameters. - */ - export type GetAllMembershipsParameters = PagedRequestParameters & { - /** Filter memberships by user ID. */ - userId?: string; +/** + * Get Membership request parameters. + */ +export type GetMembershipParameters = { + /** Membership ID. */ + id: string; +}; - /** Filter memberships by channel ID. */ - channelId?: string; +/** + * Get All Memberships request parameters. + */ +export type GetAllMembershipsParameters = PagedRequestParameters & { + /** Filter memberships by user ID. */ + userId?: string; - /** - * Schema version of the relationship class. - * If not provided, the server uses the latest version. - */ - relationshipClassVersion?: number; + /** Filter memberships by channel ID. */ + channelId?: string; - /** - * Advanced filter expression for complex queries. - */ - filterAdvanced?: string; - }; + /** + * Schema version of the relationship class. + * If not provided, the server uses the latest version. + */ + relationshipClassVersion?: number; /** - * Update Membership request parameters (full replacement via PUT). + * Advanced filter expression for complex queries. */ - export type UpdateMembershipParameters = { - /** Membership ID. */ - id: string; + filterAdvanced?: string; +}; - /** Complete membership properties for replacement. */ - membership: UpdateMembershipProperties; +/** + * Update Membership request parameters (full replacement via PUT). + */ +export type UpdateMembershipParameters = { + /** Membership ID. */ + id: string; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; - }; + /** Complete membership properties for replacement. */ + membership: UpdateMembershipProperties; /** - * Patch Membership request parameters (partial update via JSON Patch RFC 6902). - * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * - * At least one of `add`, `replace`, or `remove` must be provided. + * ETag for optimistic concurrency control. */ - export type PatchMembershipParameters = { - /** Membership ID. */ - id: string; + ifMatchesEtag?: string; +}; - /** - * Fields to add, using dot-notation keys. - * The SDK converts these to JSON Patch "add" operations. - */ - add?: Record; +/** + * Patch Membership request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ +export type PatchMembershipParameters = { + /** Membership ID. */ + id: string; - /** - * Fields to replace, using dot-notation keys. - * The SDK converts these to JSON Patch "replace" operations. - */ - replace?: Record; + /** + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; - /** - * Array of dot-notation field paths to remove. - * The SDK converts these to JSON Patch "remove" operations. - */ - remove?: string[]; + /** + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. + */ + replace?: Record; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; - }; + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; /** - * Remove Membership request parameters. + * UUIDv4 idempotency key for safe retries. */ - export type RemoveMembershipParameters = { - /** Membership ID. */ - id: string; + idempotencyKey?: string; +}; - /** - * ETag for optimistic concurrency control. - */ - ifMatchesEtag?: string; - }; +/** + * Remove Membership request parameters. + */ +export type RemoveMembershipParameters = { + /** Membership ID. */ + id: string; - // ----- Membership Response Types ----- + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; +}; - /** Response for creating a membership. */ - export type CreateMembershipResponse = DataSyncEntityResponse; +// ----- Membership Response Types ----- - /** Response for getting a single membership. */ - export type GetMembershipResponse = DataSyncEntityResponse; +/** Response for creating a membership. */ +export type CreateMembershipResponse = DataSyncEntityResponse; - /** Response for listing memberships. */ - export type GetAllMembershipsResponse = DataSyncPagedResponse; +/** Response for getting a single membership. */ +export type GetMembershipResponse = DataSyncEntityResponse; - /** Response for updating a membership (PUT). */ - export type UpdateMembershipResponse = DataSyncEntityResponse; +/** Response for listing memberships. */ +export type GetAllMembershipsResponse = DataSyncPagedResponse; - /** Response for patching a membership (PATCH). */ - export type PatchMembershipResponse = DataSyncEntityResponse; +/** Response for updating a membership (PUT). */ +export type UpdateMembershipResponse = DataSyncEntityResponse; - /** Response for removing a membership. */ - export type RemoveMembershipResponse = { - /** HTTP status code. */ - status: number; - }; +/** Response for patching a membership (PATCH). */ +export type PatchMembershipResponse = DataSyncEntityResponse; + +/** Response for removing a membership. */ +export type RemoveMembershipResponse = { + /** HTTP status code. */ + status: number; +}; From f57123ed39088954aca3b6f13ada56e29b275a56 Mon Sep 17 00:00:00 2001 From: Mohit Tejani <60129002+mohitpubnub@users.noreply.github.com> Date: Fri, 22 May 2026 13:40:41 +0530 Subject: [PATCH 10/19] Fix CODEOWNERS syntax for jguz-pubnub --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e42bd3603..d7cb51b00 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ -* @mohitpubnub @parfeon jguz-pubnub +* @mohitpubnub @parfeon @jguz-pubnub README.md @techwritermat @kazydek @mohitpubnub @parfeon From 38760803e8b48c2396fdef33d6fb5f6f88a5ebe1 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Wed, 27 May 2026 13:38:48 +0530 Subject: [PATCH 11/19] dataSync relationship api for getAll should have class and version input accepted --- .../data_sync/relationship/get-all.ts | 18 +++++++++++++++++- src/core/types/api/data-sync.ts | 8 ++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/core/endpoints/data_sync/relationship/get-all.ts b/src/core/endpoints/data_sync/relationship/get-all.ts index 0b616df69..be6a1c797 100644 --- a/src/core/endpoints/data_sync/relationship/get-all.ts +++ b/src/core/endpoints/data_sync/relationship/get-all.ts @@ -56,14 +56,30 @@ export class GetAllRelationshipsRequest Date: Thu, 28 May 2026 11:13:03 +0530 Subject: [PATCH 12/19] sync package.json with latest --- package-lock.json | 12 ++++++------ package.json | 7 +++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index a59cd7b74..9e3ba24f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pubnub", - "version": "11.0.0", + "version": "11.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pubnub", - "version": "11.0.0", + "version": "11.0.1", "license": "SEE LICENSE IN LICENSE", "dependencies": { "agentkeepalive": "^3.5.2", @@ -5816,9 +5816,9 @@ } }, "node_modules/basic-ftp": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", - "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", + "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -8106,7 +8106,7 @@ "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "license": "MIT", "dependencies": { - "basic-ftp": "^5.0.2", + "basic-ftp": "^5.3.1", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" }, diff --git a/package.json b/package.json index aae0fa88e..d915b2cfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pubnub", - "version": "11.0.0", + "version": "11.0.1", "author": "PubNub ", "description": "Publish & Subscribe Real-time Messaging with PubNub", "scripts": { @@ -68,6 +68,9 @@ "proxy-agent": "^6.3.0", "react-native-url-polyfill": "^2.0.0" }, + "overrides": { + "basic-ftp": "5.3.1" + }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.1.0", @@ -134,4 +137,4 @@ "engine": { "node": ">=18" } -} +} \ No newline at end of file From fd1b9e45c19f621ed4a04d19f072fd5438b79515 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 28 May 2026 11:29:57 +0530 Subject: [PATCH 13/19] fix type definition for getAllRelationships --- src/core/pubnub-data-sync.ts | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index 11fb07f1b..531e30a96 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -492,13 +492,6 @@ export default class PubNubDataSync { // endregion // region Get All Relationships - /** - * Fetch a paginated list of Relationships. - * - * @param callback - Request completion handler callback. - */ - public getAllRelationships(callback: ResultCallback): void; - /** * Fetch a paginated list of Relationships. * @@ -513,32 +506,26 @@ export default class PubNubDataSync { /** * Fetch a paginated list of Relationships. * - * @param [parameters] - Request configuration parameters. + * @param parameters - Request configuration parameters. * * @returns Asynchronous get all relationships response. */ public async getAllRelationships( - parameters?: DataSync.GetAllRelationshipsParameters, + parameters: DataSync.GetAllRelationshipsParameters, ): Promise; /** * Fetch a paginated list of Relationships. * - * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. */ async getAllRelationships( - parametersOrCallback?: - | DataSync.GetAllRelationshipsParameters - | ResultCallback, + parameters: DataSync.GetAllRelationshipsParameters, callback?: ResultCallback, ): Promise { - const parameters: DataSync.GetAllRelationshipsParameters = - parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; - callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; - this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, From 4be5002ab79460915941bb17d56d151de4c2faa4 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 10 Jul 2026 14:57:12 +0530 Subject: [PATCH 14/19] datasync event handling, grantToken update for datasync permissions --- src/core/components/event-dispatcher.ts | 18 ++ .../endpoints/access_manager/grant_token.ts | 124 +++++++++- .../data_sync/relationship/update.ts | 1 + src/core/endpoints/subscribe.ts | 217 ++++++++++++++++++ src/core/pubnub-common.ts | 12 + src/core/types/api/access-manager.ts | 120 ++++++++++ src/core/types/api/data-sync.ts | 7 +- src/core/types/api/subscription.ts | 49 +++- src/entities/interfaces/event-emit-capable.ts | 7 + src/entities/subscription-base.ts | 10 + 10 files changed, 558 insertions(+), 7 deletions(-) diff --git a/src/core/components/event-dispatcher.ts b/src/core/components/event-dispatcher.ts index 1516c39df..be36c0abf 100644 --- a/src/core/components/event-dispatcher.ts +++ b/src/core/components/event-dispatcher.ts @@ -52,6 +52,13 @@ export type Listener = { */ file?: (file: Subscription.File) => void; + /** + * Real-time DataSync change events listener. + * + * @param event - Changed DataSync object information. + */ + dataSync?: (event: Subscription.DataSyncObject) => void; + /** * Real-time PubNub client status change event. * @@ -182,6 +189,16 @@ export class EventDispatcher { this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'file' }); } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener: ((event: Subscription.DataSyncObject) => void) | undefined) { + this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'dataSync' }); + } + /** * Dispatch received a real-time update. * @@ -249,6 +266,7 @@ export class EventDispatcher { } } else if (event.type === PubNubEventType.MessageAction) this.announce('messageAction', event.data); else if (event.type === PubNubEventType.Files) this.announce('file', event.data); + else if (event.type === PubNubEventType.DataSync) this.announce('dataSync', event.data); } /** diff --git a/src/core/endpoints/access_manager/grant_token.ts b/src/core/endpoints/access_manager/grant_token.ts index 6c985f10d..1d88270f1 100644 --- a/src/core/endpoints/access_manager/grant_token.ts +++ b/src/core/endpoints/access_manager/grant_token.ts @@ -47,6 +47,21 @@ type PermissionPayload = { */ groups?: Record; + /** + * Object containing DataSync `entity` permissions. + */ + 'datasync:entities'?: Record; + + /** + * Object containing DataSync `relationship` permissions. + */ + 'datasync:relationships'?: Record; + + /** + * Object containing DataSync `membership` permissions. + */ + 'datasync:memberships'?: Record; + /** * Extra metadata to be published with the request. * @@ -55,6 +70,18 @@ type PermissionPayload = { meta?: PAM.Metadata; }; +/** + * Encoded DataSync projections payload, stored under the `pn-projections` meta key. + */ +type ProjectionsPayload = Record<'res' | 'pat', Record>; + +/** + * Wire-level `meta` section. + * + * Holds user-supplied scalar metadata plus the SDK-injected `pn-projections` object. + */ +type MetaPayload = Record; + /** * Service success response. */ @@ -111,10 +138,14 @@ export class GrantTokenRequest extends AbstractRequest { @@ -162,7 +193,7 @@ export class GrantTokenRequest extends AbstractRequest> = {}; + const permissions: Record> = {}; const resourcePermissions: PermissionPayload = {}; const patternPermissions: PermissionPayload = {}; const mapPermissions = ( @@ -213,17 +244,95 @@ export class GrantTokenRequest extends AbstractRequest mapPermissions(uuids, this.extractPermissions(uuidsPermissions[uuids]), 'uuids', target), ); + + if (refPerm && 'dataSync' in refPerm) this.mapDataSyncPermissions(refPerm.dataSync, target, mapPermissions); }); if (uuid) permissions.uuid = `${uuid}`; permissions.resources = resourcePermissions; permissions.patterns = patternPermissions; - permissions.meta = meta ?? {}; + + // Merge DataSync projections into `meta` under `pn-projections`, preserving user-supplied meta. + // `pn-projections` is omitted entirely when no projections are set. + const projections = this.buildProjections(); + permissions.meta = { ...(meta ?? {}), ...(projections ? { 'pn-projections': projections } : {}) }; body.permissions = permissions; return JSON.stringify(body); } + /** + * Serialize DataSync entity-level permissions into a resources / patterns target. + * + * The `datasync:*` wire keys are only written when their scope map is non-empty, so tokens that + * don't use DataSync stay byte-for-byte identical. + * + * @param dataSync - User provided DataSync permission scopes. + * @param target - Resources or patterns payload to populate. + * @param mapPermissions - Helper which writes a single bit-encoded permission into the target. + */ + private mapDataSyncPermissions( + dataSync: PAM.DataSyncTokenScopes | undefined, + target: PermissionPayload, + mapPermissions: ( + name: string, + permissionBit: number, + type: keyof PermissionPayload, + target: PermissionPayload, + ) => void, + ) { + if (!dataSync) return; + + const dataSyncScopes: [keyof PAM.DataSyncTokenScopes, keyof PermissionPayload][] = [ + ['entities', 'datasync:entities'], + ['relationships', 'datasync:relationships'], + ['memberships', 'datasync:memberships'], + ]; + + dataSyncScopes.forEach(([scope, wireKey]) => { + const scopePermissions = dataSync[scope]; + if (!scopePermissions) return; + + Object.keys(scopePermissions).forEach((id) => + mapPermissions(id, this.extractPermissions(scopePermissions[id]), wireKey, target), + ); + }); + } + + /** + * Build the `pn-projections` meta payload from DataSync projection parameters. + * + * Each projection scope is encoded into a flat composite key (`datasync::`) mapped to + * the projection name. The `res` / `pat` sub-objects are omitted when empty. + * + * @returns Encoded projections payload, or `undefined` when no projections are set. + */ + private buildProjections(): ProjectionsPayload | undefined { + const projections = 'dataSyncProjections' in this.parameters ? this.parameters.dataSyncProjections : undefined; + if (!projections) return undefined; + + const encodeScope = (scope?: PAM.DataSyncProjectionScope) => { + const encoded: Record = {}; + if (!scope) return encoded; + + (['entities', 'relationships', 'memberships'] as const).forEach((type) => { + const assignments = scope[type]; + if (assignments) + Object.keys(assignments).forEach((id) => (encoded[`datasync:${type}:${id}`] = assignments[id])); + }); + + return encoded; + }; + + const result = {} as ProjectionsPayload; + const res = encodeScope(projections.resources); + const pat = encodeScope(projections.patterns); + if (Object.keys(res).length > 0) result.res = res; + if (Object.keys(pat).length > 0) result.pat = pat; + + return Object.keys(result).length > 0 ? result : undefined; + } + /** * Extract permissions bit from permission configuration object. * @@ -232,13 +341,18 @@ export class GrantTokenRequest extends AbstractRequest | undefined { diff --git a/src/core/endpoints/subscribe.ts b/src/core/endpoints/subscribe.ts index 7e672057d..c31b93617 100644 --- a/src/core/endpoints/subscribe.ts +++ b/src/core/endpoints/subscribe.ts @@ -65,6 +65,13 @@ export enum PubNubEventType { * Files event. */ Files, + + /** + * DataSync object change event. + * + * **Note:** Value must equal `5` to match the service wire value (`e: 5`). + */ + DataSync, } /** @@ -417,6 +424,167 @@ export type VSPMembershipObjectData = ObjectData< export type AppContextObjectData = ChannelObjectData | UuidObjectData | MembershipObjectData; // endregion +// region DataSync service response +/** + * DataSync change event kinds. + */ +type DataSyncEventName = 'create' | 'update' | 'delete'; + +/** + * DataSync object kinds carried on the wire. + */ +type DataSyncObjectType = 'entity' | 'relationship'; + +/** + * DataSync entity change payload (create / update). + */ +export type DataSyncEntityData = { + /** + * Unique entity identifier. + */ + id: string; + + /** + * Lifecycle status. + */ + status?: string; + + /** + * User-defined JSON payload. + */ + payload?: Payload; + + /** + * Date and time the entity was created (ISO 8601). + */ + createdAt?: string; + + /** + * Date and time the entity was last updated (ISO 8601). + */ + updatedAt?: string; + + /** + * Content fingerprint for optimistic concurrency control. + */ + eTag?: string; + + /** + * Auto-deletion timestamp (ISO 8601). + */ + expiresAt?: string; + + /** + * Entity class name (last `:`-delimited segment of the wire `className`). + */ + entityClass?: string; + + /** + * Version of the entity class schema (parsed from the wire `classVersion`). + */ + entityClassVersion?: number; +}; + +/** + * DataSync relationship change payload (create / update). + */ +export type DataSyncRelationshipData = Omit & { + /** + * First entity id in the relationship. + */ + entityAId?: string; + + /** + * Second entity id in the relationship. + */ + entityBId?: string; + + /** + * Relationship class name (last `:`-delimited segment of the wire `className`). + */ + relationshipClass?: string; + + /** + * Version of the relationship class schema (parsed from the wire `classVersion`). + */ + relationshipClassVersion?: number; +}; + +/** + * DataSync delete change payload. + */ +export type DataSyncDeleteData = { + /** + * Unique identifier of the removed object. + */ + id: string; + + /** + * Date and time the object was removed (ISO 8601). + */ + deletedAt?: string; +}; + +/** + * Parsed DataSync change event (dispatched under `message`). + */ +export type DataSyncData = { + /** + * DataSync service payload version. + */ + version?: string; + + /** + * The type of change which happened to the object. + */ + event: DataSyncEventName; + + /** + * Name of the service which generated the update (always `data-sync`). + */ + source: string; + + /** + * DataSync object kind. + */ + type: DataSyncObjectType; + + /** + * Object class name (last `:`-delimited segment of the wire `className`). + */ + className?: string; + + /** + * Version of the object class schema (parsed from the wire `classVersion`). + */ + classVersion?: number; + + /** + * Changed object information. + * + * For `delete` events only `{ id, deletedAt }` is populated. + */ + data: DataSyncEntityData | DataSyncRelationshipData | DataSyncDeleteData; +}; + +/** + * Raw DataSync envelope payload (before parsing). + * + * @internal + */ +type DataSyncServiceData = { + version?: string; + metadata?: { + event?: DataSyncEventName; + source?: string; + type?: DataSyncObjectType; + className?: string; + classVersion?: string | number; + }; + data?: Record; +}; +// endregion + // region File service response /** * File service response. @@ -712,6 +880,13 @@ export class BaseSubscribeRequest extends AbstractRequest; + + let data: DataSyncData['data']; + if (metadata.event === 'delete') { + data = { id: raw.id as string, deletedAt: raw.deletedAt as string | undefined }; + } else if (metadata.type === 'relationship') { + data = { + ...raw, + relationshipClass: className, + relationshipClassVersion: classVersion, + } as DataSyncRelationshipData; + } else { + data = { ...raw, entityClass: className, entityClassVersion: classVersion } as DataSyncEntityData; + } + + return { + channel, + subscription, + timetoken: envelope.p.t, + message: { + version: payload.version, + event: metadata.event, + source: metadata.source, + type: metadata.type, + className, + classVersion, + data, + }, + }; + } + private fileFromEnvelope(envelope: Envelope): Subscription.File { const [channel, subscription] = this.subscriptionChannelFromEnvelope(envelope); const [file, decryptionError] = this.decryptedData(envelope.d); diff --git a/src/core/pubnub-common.ts b/src/core/pubnub-common.ts index 41f6f97f4..d1b799687 100644 --- a/src/core/pubnub-common.ts +++ b/src/core/pubnub-common.ts @@ -4745,6 +4745,18 @@ export class PubNubCore< } else throw new Error('Listener error: subscription module disabled'); } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener: ((event: Subscription.DataSyncObject) => void) | undefined) { + if (process.env.SUBSCRIBE_MODULE !== 'disabled') { + if (this.eventDispatcher) this.eventDispatcher.onDataSync = listener; + } else throw new Error('Listener error: subscription module disabled'); + } + /** * Set events handler. * diff --git a/src/core/types/api/access-manager.ts b/src/core/types/api/access-manager.ts index 991c1da3a..9559850dd 100644 --- a/src/core/types/api/access-manager.ts +++ b/src/core/types/api/access-manager.ts @@ -91,6 +91,108 @@ export type UuidTokenPermissions = { */ type UserTokenPermissions = UuidTokenPermissions; +/** + * DataSync entity-level token permissions. + * + * Applies to DataSync entities, relationships, and memberships. Only the CRUD-relevant operations + * are exposed. + */ +export type DataSyncTokenPermissions = { + /** + * Whether `create` operations are permitted for corresponding level or not. + */ + create?: boolean; + + /** + * Whether `get` operations are permitted for corresponding level or not. + */ + get?: boolean; + + /** + * Whether `update` operations are permitted for corresponding level or not. + */ + update?: boolean; + + /** + * Whether `delete` operations are permitted for corresponding level or not. + */ + delete?: boolean; +}; + +/** + * DataSync permission scopes. + * + * Carried in the grant token `resources` / `patterns` sections and serialized to the wire keys + * `datasync:entities` / `datasync:relationships` / `datasync:memberships`. + */ +export type DataSyncTokenScopes = { + /** + * Object containing DataSync `entity` permissions. + * + * Keys are concrete entity ids (e.g. `order-456`) for `resources` or RegEx patterns + * (e.g. `order-*`) for `patterns`. + */ + entities?: Record; + + /** + * Object containing DataSync `relationship` permissions. + * + * Keys are composite relationship ids (e.g. `user.A:channel.X`). + */ + relationships?: Record; + + /** + * Object containing DataSync `membership` permissions. + * + * Keys are composite membership ids (e.g. `user-123:channel-X`). + */ + memberships?: Record; +}; + +/** + * Per-resource DataSync projection assignment. + * + * Each id maps to the single projection name the principal is "looking through" for that resource + * (use `__default__` for the base projection). + */ +export type DataSyncProjectionScope = { + /** + * Entity id -> projection name. + * + * Keys are concrete entity ids (e.g. `user.A`) for `resources` or RegEx patterns + * (e.g. `user.*`) for `patterns`. + */ + entities?: Record; + + /** + * Relationship id -> projection name. + */ + relationships?: Record; + + /** + * Membership id -> projection name. + */ + memberships?: Record; +}; + +/** + * DataSync projection permissions for grant token requests. + * + * Encoded into the `pn-projections` key within the token's `meta` section. Exact (`res`) match + * takes priority over pattern (`pat`) match. + */ +export type DataSyncProjections = { + /** + * Projection assignments for concrete resources. + */ + resources?: DataSyncProjectionScope; + + /** + * Projection assignments for resources which match a RegEx pattern. + */ + patterns?: DataSyncProjectionScope; +}; + /** * Generate access token with permissions. * @@ -180,6 +282,11 @@ export type GrantTokenParameters = { * Object containing `channel group` permissions. */ groups?: Record; + + /** + * Object containing DataSync entity-level permissions. + */ + dataSync?: DataSyncTokenScopes; }; /** @@ -203,6 +310,12 @@ export type GrantTokenParameters = { * RegEx pattern. */ groups?: Record; + + /** + * Object containing DataSync entity-level permissions to apply to all DataSync resources + * matching the RegEx pattern. + */ + dataSync?: DataSyncTokenScopes; }; /** @@ -212,6 +325,13 @@ export type GrantTokenParameters = { */ meta?: Metadata; + /** + * DataSync projection permissions. + * + * Encoded into the `pn-projections` key within the token's `meta` section. + */ + dataSyncProjections?: DataSyncProjections; + /** * Single `uuid` which is authorized to use the token to make API requests to PubNub. */ diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 154951437..21fb8712a 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -483,7 +483,9 @@ export type CreateRelationshipProperties = { /** * Relationship properties for update (PUT) requests. * - * PUT is a full replacement — `entityAId` and `entityBId` are required. + * PUT is a full replacement — `entityAId`, `entityBId`, and `relationshipClassVersion` are required + * (`relationshipClass` is immutable after creation and therefore excluded). The server rejects a + * PUT that omits `relationshipClassVersion`. */ export type UpdateRelationshipProperties = { /** First entity ID in the relationship. */ @@ -492,6 +494,9 @@ export type UpdateRelationshipProperties = { /** Second entity ID in the relationship. */ entityBId: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + /** Optional lifecycle status. */ status?: string; diff --git a/src/core/types/api/subscription.ts b/src/core/types/api/subscription.ts index 2284c1b5d..f7926b134 100644 --- a/src/core/types/api/subscription.ts +++ b/src/core/types/api/subscription.ts @@ -7,8 +7,16 @@ import { SpaceObjectData, UserObjectData, PresenceData, + DataSyncData, FileData, } from '../../endpoints/subscribe'; + +export type { + DataSyncData, + DataSyncEntityData, + DataSyncRelationshipData, + DataSyncDeleteData, +} from '../../endpoints/subscribe'; import { AbortSignal } from '../../components/abort_signal'; import { Payload } from './index'; @@ -515,6 +523,37 @@ type FileEvent = { pn_mfp: string; }; // endregion + +// region DataSync event +/** + * DataSync object change real-time event. + */ +export type DataSyncObject = Event & { + /** + * Parsed DataSync change payload. + */ + message: DataSyncData; +}; + +/** + * Extended DataSync change real-time event. + * + * Type extended for listener manager support. + * + * @internal + */ +type DataSyncEvent = { + type: PubNubEventType.DataSync; + data: DataSyncObject; + + /** + * Received DataSync event fingerprint. + * + * @internal + */ + pn_mfp: string; +}; +// endregion // endregion // -------------------------------------------------------- @@ -596,6 +635,14 @@ export type SubscribeParameters = { */ export type SubscriptionResponse = { cursor: SubscriptionCursor; - messages: (PresenceEvent | MessageEvent | SignalEvent | MessageActionEvent | AppContextEvent | FileEvent)[]; + messages: ( + | PresenceEvent + | MessageEvent + | SignalEvent + | MessageActionEvent + | AppContextEvent + | FileEvent + | DataSyncEvent + )[]; }; // endregion diff --git a/src/entities/interfaces/event-emit-capable.ts b/src/entities/interfaces/event-emit-capable.ts index 656f97036..5f0f9f7fc 100644 --- a/src/entities/interfaces/event-emit-capable.ts +++ b/src/entities/interfaces/event-emit-capable.ts @@ -44,6 +44,13 @@ export interface EventEmitCapable { */ onFile?: (event: Subscription.File) => void; + /** + * Set a new DataSync event handler. + * + * Function, which will be called each time when a new DataSync event is received from the real-time network. + */ + onDataSync?: (event: Subscription.DataSyncObject) => void; + /** * Set events handler. * diff --git a/src/entities/subscription-base.ts b/src/entities/subscription-base.ts index b775bd417..474cbab35 100644 --- a/src/entities/subscription-base.ts +++ b/src/entities/subscription-base.ts @@ -299,6 +299,16 @@ export abstract class SubscriptionBase implements EventEmitCapable, EventHandleC this.eventDispatcher.onFile = listener; } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener: ((event: Subscription.DataSyncObject) => void) | undefined) { + this.eventDispatcher.onDataSync = listener; + } + /** * Set events handler. * From 25eb24dd094ee202ddadb679f99e9c0afb958e74 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 21 Jul 2026 14:10:51 +0530 Subject: [PATCH 15/19] remove `idempotencyKey` from datasync apis --- .../endpoints/data_sync/channel/create.ts | 2 - src/core/endpoints/data_sync/channel/patch.ts | 2 - src/core/endpoints/data_sync/entity/create.ts | 2 - src/core/endpoints/data_sync/entity/patch.ts | 2 - .../endpoints/data_sync/membership/create.ts | 2 - .../endpoints/data_sync/membership/patch.ts | 2 - .../data_sync/relationship/create.ts | 2 - .../endpoints/data_sync/relationship/patch.ts | 2 - src/core/endpoints/data_sync/user/create.ts | 2 - src/core/endpoints/data_sync/user/patch.ts | 2 - src/core/types/api/data-sync.ts | 56 +------------------ 11 files changed, 1 insertion(+), 75 deletions(-) diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts index 8162a32c0..6a563fd71 100644 --- a/src/core/endpoints/data_sync/channel/create.ts +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -52,8 +52,6 @@ export class CreateChannelRequest | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1', diff --git a/src/core/endpoints/data_sync/channel/patch.ts b/src/core/endpoints/data_sync/channel/patch.ts index 05c73b6ff..abc139f7f 100644 --- a/src/core/endpoints/data_sync/channel/patch.ts +++ b/src/core/endpoints/data_sync/channel/patch.ts @@ -63,8 +63,6 @@ export class PatchChannelRequest if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/json-patch+json', diff --git a/src/core/endpoints/data_sync/entity/create.ts b/src/core/endpoints/data_sync/entity/create.ts index ac265bbae..6162e9d17 100644 --- a/src/core/endpoints/data_sync/entity/create.ts +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -53,8 +53,6 @@ export class CreateEntityRequest protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1', diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/patch.ts index 48e093eaf..bd315dcd9 100644 --- a/src/core/endpoints/data_sync/entity/patch.ts +++ b/src/core/endpoints/data_sync/entity/patch.ts @@ -63,8 +63,6 @@ export class PatchEntityRequest e if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/json-patch+json', diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 40078a834..8cdf1d825 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -53,8 +53,6 @@ export class CreateMembershipRequest | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1', diff --git a/src/core/endpoints/data_sync/membership/patch.ts b/src/core/endpoints/data_sync/membership/patch.ts index 97549e2b4..1ebf75b11 100644 --- a/src/core/endpoints/data_sync/membership/patch.ts +++ b/src/core/endpoints/data_sync/membership/patch.ts @@ -63,8 +63,6 @@ export class PatchMembershipRequest | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1', diff --git a/src/core/endpoints/data_sync/relationship/patch.ts b/src/core/endpoints/data_sync/relationship/patch.ts index da188e510..13fc871fc 100644 --- a/src/core/endpoints/data_sync/relationship/patch.ts +++ b/src/core/endpoints/data_sync/relationship/patch.ts @@ -63,8 +63,6 @@ export class PatchRelationshipRequest ext protected get headers(): Record | undefined { let headers = super.headers ?? {}; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1', diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/patch.ts index 8bd5f77a0..6aba81049 100644 --- a/src/core/endpoints/data_sync/user/patch.ts +++ b/src/core/endpoints/data_sync/user/patch.ts @@ -60,8 +60,6 @@ export class PatchUserRequest exten if (this.parameters.ifMatchesEtag) headers = { ...headers, 'If-Match': this.parameters.ifMatchesEtag }; - if (this.parameters.idempotencyKey) headers = { ...headers, 'Idempotency-Key': this.parameters.idempotencyKey }; - return { ...headers, 'Content-Type': 'application/json-patch+json', diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 21fb8712a..41133443f 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -286,12 +286,6 @@ export type CreateEntityParameters = { */ id?: string; }; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** @@ -406,12 +400,6 @@ export type PatchEntityParameters = { * If provided, the patch only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** @@ -560,12 +548,6 @@ export type CreateRelationshipParameters = { */ id?: string; }; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** @@ -574,6 +556,7 @@ export type CreateRelationshipParameters = { export type GetRelationshipParameters = { /** Relationship ID. */ id: string; + }; /** @@ -678,12 +661,6 @@ export type PatchRelationshipParameters = { * If provided, the patch only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** @@ -786,12 +763,6 @@ export type CreateUserParameters = { */ id?: string; }; - - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** @@ -882,11 +853,6 @@ export type PatchUserParameters = { * ETag for optimistic concurrency control. */ ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; }; /** @@ -1002,11 +968,6 @@ export type CreateChannelParameters = { */ id?: string; }; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; }; /** @@ -1081,11 +1042,6 @@ export type PatchChannelParameters = { * ETag for optimistic concurrency control. */ ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; }; /** @@ -1226,11 +1182,6 @@ export type CreateMembershipParameters = { */ id?: string; }; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; }; /** @@ -1312,11 +1263,6 @@ export type PatchMembershipParameters = { * ETag for optimistic concurrency control. */ ifMatchesEtag?: string; - - /** - * UUIDv4 idempotency key for safe retries. - */ - idempotencyKey?: string; }; /** From 6d2d13723cbba8b526ba540d61e6696a129d5d85 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Wed, 22 Jul 2026 12:55:40 +0530 Subject: [PATCH 16/19] lint fixes --- src/core/endpoints/data_sync/channel/create.ts | 2 +- src/core/endpoints/data_sync/entity/create.ts | 2 +- src/core/endpoints/data_sync/membership/create.ts | 2 +- src/core/endpoints/data_sync/relationship/create.ts | 2 +- src/core/endpoints/data_sync/user/create.ts | 2 +- src/core/types/api/data-sync.ts | 1 - 6 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts index 6a563fd71..5c14547ea 100644 --- a/src/core/endpoints/data_sync/channel/create.ts +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -50,7 +50,7 @@ export class CreateChannelRequest | undefined { - let headers = super.headers ?? {}; + const headers = super.headers ?? {}; return { ...headers, diff --git a/src/core/endpoints/data_sync/entity/create.ts b/src/core/endpoints/data_sync/entity/create.ts index 6162e9d17..193089964 100644 --- a/src/core/endpoints/data_sync/entity/create.ts +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -51,7 +51,7 @@ export class CreateEntityRequest } protected get headers(): Record | undefined { - let headers = super.headers ?? {}; + const headers = super.headers ?? {}; return { ...headers, diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 8cdf1d825..38db20d0c 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -51,7 +51,7 @@ export class CreateMembershipRequest | undefined { - let headers = super.headers ?? {}; + const headers = super.headers ?? {}; return { ...headers, diff --git a/src/core/endpoints/data_sync/relationship/create.ts b/src/core/endpoints/data_sync/relationship/create.ts index 71c4ad201..14014c0b4 100644 --- a/src/core/endpoints/data_sync/relationship/create.ts +++ b/src/core/endpoints/data_sync/relationship/create.ts @@ -52,7 +52,7 @@ export class CreateRelationshipRequest | undefined { - let headers = super.headers ?? {}; + const headers = super.headers ?? {}; return { ...headers, diff --git a/src/core/endpoints/data_sync/user/create.ts b/src/core/endpoints/data_sync/user/create.ts index 6420417e7..f46073acf 100644 --- a/src/core/endpoints/data_sync/user/create.ts +++ b/src/core/endpoints/data_sync/user/create.ts @@ -50,7 +50,7 @@ export class CreateUserRequest ext } protected get headers(): Record | undefined { - let headers = super.headers ?? {}; + const headers = super.headers ?? {}; return { ...headers, diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 41133443f..a90591261 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -556,7 +556,6 @@ export type CreateRelationshipParameters = { export type GetRelationshipParameters = { /** Relationship ID. */ id: string; - }; /** From c5be6808101ea444df0814183bad17d8b3d42caf Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 23 Jul 2026 12:56:41 +0530 Subject: [PATCH 17/19] handling user/channel/membership events in subscription --- .../endpoints/data_sync/channel/create.ts | 8 +++ .../endpoints/data_sync/channel/get-all.ts | 8 +++ src/core/endpoints/data_sync/channel/get.ts | 8 +++ src/core/endpoints/data_sync/channel/patch.ts | 8 +++ .../endpoints/data_sync/channel/update.ts | 8 +++ src/core/endpoints/data_sync/entity/create.ts | 8 +++ .../endpoints/data_sync/entity/get-all.ts | 8 +++ src/core/endpoints/data_sync/entity/get.ts | 8 +++ src/core/endpoints/data_sync/entity/patch.ts | 8 +++ src/core/endpoints/data_sync/entity/update.ts | 8 +++ .../endpoints/data_sync/membership/create.ts | 8 +++ .../endpoints/data_sync/membership/get-all.ts | 8 +++ .../endpoints/data_sync/membership/get.ts | 8 +++ .../endpoints/data_sync/membership/patch.ts | 8 +++ .../endpoints/data_sync/membership/update.ts | 9 +++ .../data_sync/relationship/create.ts | 8 +++ .../data_sync/relationship/get-all.ts | 8 +++ .../endpoints/data_sync/relationship/get.ts | 8 +++ .../endpoints/data_sync/relationship/patch.ts | 8 +++ .../data_sync/relationship/update.ts | 8 +++ src/core/endpoints/data_sync/user/create.ts | 8 +++ src/core/endpoints/data_sync/user/get-all.ts | 8 +++ src/core/endpoints/data_sync/user/get.ts | 8 +++ src/core/endpoints/data_sync/user/patch.ts | 8 +++ src/core/endpoints/data_sync/user/update.ts | 8 +++ src/core/endpoints/subscribe.ts | 55 ++++++++++++++++++- src/core/types/api/data-sync.ts | 19 ++++--- src/core/types/api/subscription.ts | 1 + 28 files changed, 265 insertions(+), 11 deletions(-) diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts index 5c14547ea..a50c9fe31 100644 --- a/src/core/endpoints/data_sync/channel/create.ts +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -5,6 +5,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class CreateChannelRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.channel) return 'Channel cannot be empty'; if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) diff --git a/src/core/endpoints/data_sync/channel/get-all.ts b/src/core/endpoints/data_sync/channel/get-all.ts index 2c3df4edb..78b457f02 100644 --- a/src/core/endpoints/data_sync/channel/get-all.ts +++ b/src/core/endpoints/data_sync/channel/get-all.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -56,6 +57,13 @@ export class GetAllChannelsRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + protected get path(): string { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`; } diff --git a/src/core/endpoints/data_sync/channel/get.ts b/src/core/endpoints/data_sync/channel/get.ts index 1bcb5a06b..6642e2c37 100644 --- a/src/core/endpoints/data_sync/channel/get.ts +++ b/src/core/endpoints/data_sync/channel/get.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class GetChannelRequest ext return RequestOperation.PNGetChannelOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Channel id cannot be empty'; } diff --git a/src/core/endpoints/data_sync/channel/patch.ts b/src/core/endpoints/data_sync/channel/patch.ts index abc139f7f..4e5d31f49 100644 --- a/src/core/endpoints/data_sync/channel/patch.ts +++ b/src/core/endpoints/data_sync/channel/patch.ts @@ -9,6 +9,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -49,6 +50,13 @@ export class PatchChannelRequest return RequestOperation.PNPatchChannelOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Channel id cannot be empty'; diff --git a/src/core/endpoints/data_sync/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts index a2583c5a2..c4aef3c77 100644 --- a/src/core/endpoints/data_sync/channel/update.ts +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -7,6 +7,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -46,6 +47,13 @@ export class UpdateChannelRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Channel id cannot be empty'; if (!this.parameters.channel) return 'Channel cannot be empty'; diff --git a/src/core/endpoints/data_sync/entity/create.ts b/src/core/endpoints/data_sync/entity/create.ts index 193089964..8b6307f29 100644 --- a/src/core/endpoints/data_sync/entity/create.ts +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -5,6 +5,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class CreateEntityRequest return RequestOperation.PNCreateEntityOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.entity) return 'Entity cannot be empty'; if (!this.parameters.entity.entityClass) return 'Entity class cannot be empty'; diff --git a/src/core/endpoints/data_sync/entity/get-all.ts b/src/core/endpoints/data_sync/entity/get-all.ts index 5b43a6379..93d287613 100644 --- a/src/core/endpoints/data_sync/entity/get-all.ts +++ b/src/core/endpoints/data_sync/entity/get-all.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -56,6 +57,13 @@ export class GetAllEntitiesRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.entityClass) return 'Entity class cannot be empty'; } diff --git a/src/core/endpoints/data_sync/entity/get.ts b/src/core/endpoints/data_sync/entity/get.ts index 47ddcb28e..efbf6588d 100644 --- a/src/core/endpoints/data_sync/entity/get.ts +++ b/src/core/endpoints/data_sync/entity/get.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -40,6 +41,13 @@ export class GetEntityRequest exten return RequestOperation.PNGetEntityOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Entity id cannot be empty'; } diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/patch.ts index bd315dcd9..0a7f4a6d5 100644 --- a/src/core/endpoints/data_sync/entity/patch.ts +++ b/src/core/endpoints/data_sync/entity/patch.ts @@ -9,6 +9,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -49,6 +50,13 @@ export class PatchEntityRequest e return RequestOperation.PNPatchEntityOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Entity id cannot be empty'; diff --git a/src/core/endpoints/data_sync/entity/update.ts b/src/core/endpoints/data_sync/entity/update.ts index a5b36e4f2..1b957f40d 100644 --- a/src/core/endpoints/data_sync/entity/update.ts +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -8,6 +8,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -47,6 +48,13 @@ export class UpdateEntityRequest return RequestOperation.PNUpdateEntityOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Entity id cannot be empty'; if (!this.parameters.entity) return 'Entity cannot be empty'; diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 38db20d0c..00ecffea4 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -5,6 +5,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class CreateMembershipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.membership) return 'Membership cannot be empty'; if (!this.parameters.membership.userId) return 'User id cannot be empty'; diff --git a/src/core/endpoints/data_sync/membership/get-all.ts b/src/core/endpoints/data_sync/membership/get-all.ts index bfb490652..35e0c2681 100644 --- a/src/core/endpoints/data_sync/membership/get-all.ts +++ b/src/core/endpoints/data_sync/membership/get-all.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -56,6 +57,13 @@ export class GetAllMembershipsRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + protected get path(): string { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`; } diff --git a/src/core/endpoints/data_sync/membership/get.ts b/src/core/endpoints/data_sync/membership/get.ts index bd7ecb1cf..625b34d92 100644 --- a/src/core/endpoints/data_sync/membership/get.ts +++ b/src/core/endpoints/data_sync/membership/get.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class GetMembershipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Membership id cannot be empty'; } diff --git a/src/core/endpoints/data_sync/membership/patch.ts b/src/core/endpoints/data_sync/membership/patch.ts index 1ebf75b11..05f4f41bd 100644 --- a/src/core/endpoints/data_sync/membership/patch.ts +++ b/src/core/endpoints/data_sync/membership/patch.ts @@ -9,6 +9,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -49,6 +50,13 @@ export class PatchMembershipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Membership id cannot be empty'; diff --git a/src/core/endpoints/data_sync/membership/update.ts b/src/core/endpoints/data_sync/membership/update.ts index 8064893c5..eb0aeb62c 100644 --- a/src/core/endpoints/data_sync/membership/update.ts +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -7,6 +7,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -46,11 +47,19 @@ export class UpdateMembershipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Membership id cannot be empty'; if (!this.parameters.membership) return 'Membership cannot be empty'; if (!this.parameters.membership.userId) return 'User id cannot be empty'; if (!this.parameters.membership.channelId) return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) return 'Relationship class version cannot be empty'; } protected get headers(): Record | undefined { diff --git a/src/core/endpoints/data_sync/relationship/create.ts b/src/core/endpoints/data_sync/relationship/create.ts index 14014c0b4..063d7c1e5 100644 --- a/src/core/endpoints/data_sync/relationship/create.ts +++ b/src/core/endpoints/data_sync/relationship/create.ts @@ -5,6 +5,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class CreateRelationshipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.relationship) return 'Relationship cannot be empty'; if (!this.parameters.relationship.entityAId) return 'Entity A id cannot be empty'; diff --git a/src/core/endpoints/data_sync/relationship/get-all.ts b/src/core/endpoints/data_sync/relationship/get-all.ts index be6a1c797..773e6adb0 100644 --- a/src/core/endpoints/data_sync/relationship/get-all.ts +++ b/src/core/endpoints/data_sync/relationship/get-all.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -56,6 +57,13 @@ export class GetAllRelationshipsRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.relationshipClass) return 'Relationship class cannot be empty'; } diff --git a/src/core/endpoints/data_sync/relationship/get.ts b/src/core/endpoints/data_sync/relationship/get.ts index 5788e31c5..5a5a0f522 100644 --- a/src/core/endpoints/data_sync/relationship/get.ts +++ b/src/core/endpoints/data_sync/relationship/get.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class GetRelationshipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Relationship id cannot be empty'; } diff --git a/src/core/endpoints/data_sync/relationship/patch.ts b/src/core/endpoints/data_sync/relationship/patch.ts index 13fc871fc..6e14be759 100644 --- a/src/core/endpoints/data_sync/relationship/patch.ts +++ b/src/core/endpoints/data_sync/relationship/patch.ts @@ -9,6 +9,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -49,6 +50,13 @@ export class PatchRelationshipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Relationship id cannot be empty'; diff --git a/src/core/endpoints/data_sync/relationship/update.ts b/src/core/endpoints/data_sync/relationship/update.ts index 073a3c243..46efeef4d 100644 --- a/src/core/endpoints/data_sync/relationship/update.ts +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -7,6 +7,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -46,6 +47,13 @@ export class UpdateRelationshipRequest { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'Relationship id cannot be empty'; if (!this.parameters.relationship) return 'Relationship cannot be empty'; diff --git a/src/core/endpoints/data_sync/user/create.ts b/src/core/endpoints/data_sync/user/create.ts index f46073acf..ccfe9935b 100644 --- a/src/core/endpoints/data_sync/user/create.ts +++ b/src/core/endpoints/data_sync/user/create.ts @@ -5,6 +5,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -43,6 +44,13 @@ export class CreateUserRequest ext return RequestOperation.PNCreateUserOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.user) return 'User cannot be empty'; if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) diff --git a/src/core/endpoints/data_sync/user/get-all.ts b/src/core/endpoints/data_sync/user/get-all.ts index 2e8e08fb2..6a889f381 100644 --- a/src/core/endpoints/data_sync/user/get-all.ts +++ b/src/core/endpoints/data_sync/user/get-all.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -56,6 +57,13 @@ export class GetAllUsersRequest e return RequestOperation.PNGetAllUsersOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + protected get path(): string { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`; } diff --git a/src/core/endpoints/data_sync/user/get.ts b/src/core/endpoints/data_sync/user/get.ts index 93c4b105f..61f3438e9 100644 --- a/src/core/endpoints/data_sync/user/get.ts +++ b/src/core/endpoints/data_sync/user/get.ts @@ -4,6 +4,7 @@ * @internal */ +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -40,6 +41,13 @@ export class GetUserRequest extends A return RequestOperation.PNGetUserOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'User id cannot be empty'; } diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/patch.ts index 6aba81049..c04a92688 100644 --- a/src/core/endpoints/data_sync/user/patch.ts +++ b/src/core/endpoints/data_sync/user/patch.ts @@ -9,6 +9,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -46,6 +47,13 @@ export class PatchUserRequest exten return RequestOperation.PNPatchUserOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'User id cannot be empty'; diff --git a/src/core/endpoints/data_sync/user/update.ts b/src/core/endpoints/data_sync/user/update.ts index 333e0f677..acd641c16 100644 --- a/src/core/endpoints/data_sync/user/update.ts +++ b/src/core/endpoints/data_sync/user/update.ts @@ -7,6 +7,7 @@ */ import { TransportMethod } from '../../../types/transport-request'; +import { TransportResponse } from '../../../types/transport-response'; import { AbstractRequest } from '../../../components/request'; import RequestOperation from '../../../constants/operations'; import * as DataSync from '../../../types/api/data-sync'; @@ -46,6 +47,13 @@ export class UpdateUserRequest ext return RequestOperation.PNUpdateUserOperation; } + async parse(response: TransportResponse): Promise { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return { ...parsed, status: response.status } as Response; + } + validate(): string | undefined { if (!this.parameters.id) return 'User id cannot be empty'; if (!this.parameters.user) return 'User cannot be empty'; diff --git a/src/core/endpoints/subscribe.ts b/src/core/endpoints/subscribe.ts index c31b93617..214607284 100644 --- a/src/core/endpoints/subscribe.ts +++ b/src/core/endpoints/subscribe.ts @@ -431,10 +431,38 @@ export type AppContextObjectData = ChannelObjectData | UuidObjectData | Membersh type DataSyncEventName = 'create' | 'update' | 'delete'; /** - * DataSync object kinds carried on the wire. + * DataSync object kinds carried on the wire (raw service value). */ type DataSyncObjectType = 'entity' | 'relationship'; +/** + * Normalized DataSync object kind derived from the wire `className`. + * + * Users and Channels are backed by entity classes; Memberships by a relationship class. This + * discriminator lets consumers branch on the semantic kind in a `dataSync` listener without matching + * class-name strings. Falls back to the raw wire {@link DataSyncObjectType} for unrecognized classes. + */ +export type DataSyncNormalizedType = 'user' | 'channel' | 'membership' | 'entity' | 'relationship'; + +/** + * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * + * NOTE: the exact wire `className` for typed User/Channel/Membership resources must be confirmed by + * running the `ds-event-test` spike against an origin that emits DataSync events. Keys are compared + * case-insensitively after `className.split(':').pop()`. Best-guess values are derived from the create + * content-types (`application/vnd.pubnub.objects.{user,channel,membership}+json`). + * + * @internal + */ +const DATA_SYNC_RESERVED_CLASSES: Record = { + user: 'user', + channel: 'channel', + membership: 'membership', + pn_user: 'user', + pn_channel: 'channel', + pn_membership: 'membership', +}; + /** * DataSync entity change payload (create / update). */ @@ -545,10 +573,20 @@ export type DataSyncData = { source: string; /** - * DataSync object kind. + * Raw DataSync object kind as sent by the service. */ type: DataSyncObjectType; + /** + * Normalized DataSync object kind. + * + * Derived from {@link className}: reserved User/Channel/Membership classes map to `'user'` / + * `'channel'` / `'membership'`; everything else falls back to the raw wire {@link type} + * (`'entity'` / `'relationship'`). Use this to discriminate typed resources without knowing + * class-name strings. + */ + objectType: DataSyncNormalizedType; + /** * Object class name (last `:`-delimited segment of the wire `className`). */ @@ -1023,7 +1061,17 @@ export class BaseSubscribeRequest extends AbstractRequest::`: + // - typed User/Channel/Membership → `User::` / `Channel::` / `Membership::` (system in 1st segment) + // - generic entity / relationship → `::Customer` / `::REQUESTED_BY` (developer in last segment) + // The reserved system class (1st segment) drives `objectType`; the surfaced `className` is the + // developer class (last non-empty segment) when present, else the system class. + const classSegments = metadata.className ? metadata.className.split(':') : []; + const systemClass = classSegments.length > 0 ? classSegments[0] : undefined; + const nonEmptySegments = classSegments.filter((segment) => segment.length > 0); + const className = nonEmptySegments.length > 0 ? nonEmptySegments[nonEmptySegments.length - 1] : undefined; + const objectType: DataSyncNormalizedType = + (systemClass && DATA_SYNC_RESERVED_CLASSES[systemClass.toLowerCase()]) || metadata.type; const parsedVersion = metadata.classVersion !== undefined ? Number.parseInt(`${metadata.classVersion}`, 10) : NaN; const classVersion = Number.isNaN(parsedVersion) ? undefined : parsedVersion; const raw = (payload.data ?? {}) as Record; @@ -1050,6 +1098,7 @@ export class BaseSubscribeRequest extends AbstractRequest Date: Thu, 23 Jul 2026 12:57:11 +0530 Subject: [PATCH 18/19] lib files --- lib/core/components/event-dispatcher.js | 11 + lib/core/constants/operations.js | 72 + .../endpoints/access_manager/grant_token.js | 73 +- .../endpoints/data_sync/channel/create.js | 48 + .../endpoints/data_sync/channel/get-all.js | 47 + lib/core/endpoints/data_sync/channel/get.js | 38 + lib/core/endpoints/data_sync/channel/patch.js | 67 + .../endpoints/data_sync/channel/remove.js | 60 + .../endpoints/data_sync/channel/update.js | 55 + lib/core/endpoints/data_sync/entity/create.js | 6 +- .../endpoints/data_sync/entity/get-all.js | 2 +- lib/core/endpoints/data_sync/entity/get.js | 2 +- lib/core/endpoints/data_sync/entity/patch.js | 25 +- lib/core/endpoints/data_sync/entity/remove.js | 2 +- lib/core/endpoints/data_sync/entity/update.js | 2 +- .../endpoints/data_sync/membership/create.js | 52 + .../endpoints/data_sync/membership/get-all.js | 47 + .../endpoints/data_sync/membership/get.js | 38 + .../endpoints/data_sync/membership/patch.js | 67 + .../endpoints/data_sync/membership/remove.js | 60 + .../endpoints/data_sync/membership/update.js | 57 + .../data_sync/relationship/create.js | 10 +- .../data_sync/relationship/get-all.js | 10 +- .../endpoints/data_sync/relationship/get.js | 2 +- .../endpoints/data_sync/relationship/patch.js | 25 +- .../data_sync/relationship/remove.js | 2 +- .../data_sync/relationship/update.js | 4 +- lib/core/endpoints/data_sync/user/create.js | 48 + lib/core/endpoints/data_sync/user/get-all.js | 47 + lib/core/endpoints/data_sync/user/get.js | 38 + lib/core/endpoints/data_sync/user/patch.js | 67 + lib/core/endpoints/data_sync/user/remove.js | 60 + lib/core/endpoints/data_sync/user/update.js | 55 + lib/core/endpoints/subscribe.js | 78 + lib/core/pubnub-common.js | 14 + lib/core/pubnub-data-sync.js | 466 +- lib/core/types/api/data-sync.js | 16 +- lib/entities/subscription-base.js | 9 + lib/types/index.d.ts | 6071 ++++++++++------- 39 files changed, 5354 insertions(+), 2499 deletions(-) create mode 100644 lib/core/endpoints/data_sync/channel/create.js create mode 100644 lib/core/endpoints/data_sync/channel/get-all.js create mode 100644 lib/core/endpoints/data_sync/channel/get.js create mode 100644 lib/core/endpoints/data_sync/channel/patch.js create mode 100644 lib/core/endpoints/data_sync/channel/remove.js create mode 100644 lib/core/endpoints/data_sync/channel/update.js create mode 100644 lib/core/endpoints/data_sync/membership/create.js create mode 100644 lib/core/endpoints/data_sync/membership/get-all.js create mode 100644 lib/core/endpoints/data_sync/membership/get.js create mode 100644 lib/core/endpoints/data_sync/membership/patch.js create mode 100644 lib/core/endpoints/data_sync/membership/remove.js create mode 100644 lib/core/endpoints/data_sync/membership/update.js create mode 100644 lib/core/endpoints/data_sync/user/create.js create mode 100644 lib/core/endpoints/data_sync/user/get-all.js create mode 100644 lib/core/endpoints/data_sync/user/get.js create mode 100644 lib/core/endpoints/data_sync/user/patch.js create mode 100644 lib/core/endpoints/data_sync/user/remove.js create mode 100644 lib/core/endpoints/data_sync/user/update.js diff --git a/lib/core/components/event-dispatcher.js b/lib/core/components/event-dispatcher.js index 21319f463..1ac14f73c 100644 --- a/lib/core/components/event-dispatcher.js +++ b/lib/core/components/event-dispatcher.js @@ -98,6 +98,15 @@ class EventDispatcher { set onFile(listener) { this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'file' }); } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'dataSync' }); + } /** * Dispatch received a real-time update. * @@ -140,6 +149,8 @@ class EventDispatcher { this.announce('messageAction', event.data); else if (event.type === subscribe_1.PubNubEventType.Files) this.announce('file', event.data); + else if (event.type === subscribe_1.PubNubEventType.DataSync) + this.announce('dataSync', event.data); } /** * Dispatch received connection status change. diff --git a/lib/core/constants/operations.js b/lib/core/constants/operations.js index 204fd25a1..0a9a86dea 100644 --- a/lib/core/constants/operations.js +++ b/lib/core/constants/operations.js @@ -195,6 +195,78 @@ var RequestOperation; * Remove relationship REST API operation. */ RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + /** + * Create user REST API operation. + */ + RequestOperation["PNCreateUserOperation"] = "PNCreateUserOperation"; + /** + * Get user REST API operation. + */ + RequestOperation["PNGetUserOperation"] = "PNGetUserOperation"; + /** + * Get all users REST API operation. + */ + RequestOperation["PNGetAllUsersOperation"] = "PNGetAllUsersOperation"; + /** + * Update user REST API operation. + */ + RequestOperation["PNUpdateUserOperation"] = "PNUpdateUserOperation"; + /** + * Patch user REST API operation. + */ + RequestOperation["PNPatchUserOperation"] = "PNPatchUserOperation"; + /** + * Remove user REST API operation. + */ + RequestOperation["PNRemoveUserOperation"] = "PNRemoveUserOperation"; + /** + * Create channel REST API operation. + */ + RequestOperation["PNCreateChannelOperation"] = "PNCreateChannelOperation"; + /** + * Get channel REST API operation. + */ + RequestOperation["PNGetChannelOperation"] = "PNGetChannelOperation"; + /** + * Get all channels REST API operation. + */ + RequestOperation["PNGetAllChannelsOperation"] = "PNGetAllChannelsOperation"; + /** + * Update channel REST API operation. + */ + RequestOperation["PNUpdateChannelOperation"] = "PNUpdateChannelOperation"; + /** + * Patch channel REST API operation. + */ + RequestOperation["PNPatchChannelOperation"] = "PNPatchChannelOperation"; + /** + * Remove channel REST API operation. + */ + RequestOperation["PNRemoveChannelOperation"] = "PNRemoveChannelOperation"; + /** + * Create membership REST API operation. + */ + RequestOperation["PNCreateMembershipOperation"] = "PNCreateMembershipOperation"; + /** + * Get membership REST API operation. + */ + RequestOperation["PNGetMembershipOperation"] = "PNGetMembershipOperation"; + /** + * Get all memberships REST API operation. + */ + RequestOperation["PNGetAllMembershipsOperation"] = "PNGetAllMembershipsOperation"; + /** + * Update membership REST API operation. + */ + RequestOperation["PNUpdateMembershipOperation"] = "PNUpdateMembershipOperation"; + /** + * Patch membership REST API operation. + */ + RequestOperation["PNPatchMembershipOperation"] = "PNPatchMembershipOperation"; + /** + * Remove membership REST API operation. + */ + RequestOperation["PNRemoveMembershipOperation"] = "PNRemoveMembershipOperation"; // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- diff --git a/lib/core/endpoints/access_manager/grant_token.js b/lib/core/endpoints/access_manager/grant_token.js index 8d6230e74..a8133967a 100644 --- a/lib/core/endpoints/access_manager/grant_token.js +++ b/lib/core/endpoints/access_manager/grant_token.js @@ -43,13 +43,16 @@ class GrantTokenRequest extends request_1.AbstractRequest { validate() { var _a, _b, _c, _d, _e, _f; const { keySet: { subscribeKey, publishKey, secretKey }, resources, patterns, } = this.parameters; + // DataSync projections are a standalone grant target — a request carrying only projections + // (no resources / patterns permissions) is still valid. + const hasProjections = this.buildProjections() !== undefined; if (!subscribeKey) return 'Missing Subscribe Key'; if (!publishKey) return 'Missing Publish Key'; if (!secretKey) return 'Missing Secret Key'; - if (!resources && !patterns) + if (!resources && !patterns && !hasProjections) return 'Missing either Resources or Patterns'; if (this.isVspPermissions(this.parameters) && ('channels' in ((_a = this.parameters.resources) !== null && _a !== void 0 ? _a : {}) || @@ -70,7 +73,7 @@ class GrantTokenRequest extends request_1.AbstractRequest { } }); }); - if (permissionsEmpty) + if (permissionsEmpty && !hasProjections) return 'Missing values for either Resources or Patterns'; } parse(response) { @@ -133,15 +136,77 @@ class GrantTokenRequest extends request_1.AbstractRequest { Object.keys(channelsPermissions).forEach((channel) => mapPermissions(channel, this.extractPermissions(channelsPermissions[channel]), 'channels', target)); Object.keys(channelGroupsPermissions).forEach((groups) => mapPermissions(groups, this.extractPermissions(channelGroupsPermissions[groups]), 'groups', target)); Object.keys(uuidsPermissions).forEach((uuids) => mapPermissions(uuids, this.extractPermissions(uuidsPermissions[uuids]), 'uuids', target)); + if (refPerm && 'dataSync' in refPerm) + this.mapDataSyncPermissions(refPerm.dataSync, target, mapPermissions); }); if (uuid) permissions.uuid = `${uuid}`; permissions.resources = resourcePermissions; permissions.patterns = patternPermissions; - permissions.meta = meta !== null && meta !== void 0 ? meta : {}; + // Merge DataSync projections into `meta` under `pn-projections`, preserving user-supplied meta. + // `pn-projections` is omitted entirely when no projections are set. + const projections = this.buildProjections(); + permissions.meta = Object.assign(Object.assign({}, (meta !== null && meta !== void 0 ? meta : {})), (projections ? { 'pn-projections': projections } : {})); body.permissions = permissions; return JSON.stringify(body); } + /** + * Serialize DataSync entity-level permissions into a resources / patterns target. + * + * The `datasync:*` wire keys are only written when their scope map is non-empty, so tokens that + * don't use DataSync stay byte-for-byte identical. + * + * @param dataSync - User provided DataSync permission scopes. + * @param target - Resources or patterns payload to populate. + * @param mapPermissions - Helper which writes a single bit-encoded permission into the target. + */ + mapDataSyncPermissions(dataSync, target, mapPermissions) { + if (!dataSync) + return; + const dataSyncScopes = [ + ['entities', 'datasync:entities'], + ['relationships', 'datasync:relationships'], + ['memberships', 'datasync:memberships'], + ]; + dataSyncScopes.forEach(([scope, wireKey]) => { + const scopePermissions = dataSync[scope]; + if (!scopePermissions) + return; + Object.keys(scopePermissions).forEach((id) => mapPermissions(id, this.extractPermissions(scopePermissions[id]), wireKey, target)); + }); + } + /** + * Build the `pn-projections` meta payload from DataSync projection parameters. + * + * Each projection scope is encoded into a flat composite key (`datasync::`) mapped to + * the projection name. The `res` / `pat` sub-objects are omitted when empty. + * + * @returns Encoded projections payload, or `undefined` when no projections are set. + */ + buildProjections() { + const projections = 'dataSyncProjections' in this.parameters ? this.parameters.dataSyncProjections : undefined; + if (!projections) + return undefined; + const encodeScope = (scope) => { + const encoded = {}; + if (!scope) + return encoded; + ['entities', 'relationships', 'memberships'].forEach((type) => { + const assignments = scope[type]; + if (assignments) + Object.keys(assignments).forEach((id) => (encoded[`datasync:${type}:${id}`] = assignments[id])); + }); + return encoded; + }; + const result = {}; + const res = encodeScope(projections.resources); + const pat = encodeScope(projections.patterns); + if (Object.keys(res).length > 0) + result.res = res; + if (Object.keys(pat).length > 0) + result.pat = pat; + return Object.keys(result).length > 0 ? result : undefined; + } /** * Extract permissions bit from permission configuration object. * @@ -157,6 +222,8 @@ class GrantTokenRequest extends request_1.AbstractRequest { permissionsResult |= 64; if ('get' in permissions && permissions.get) permissionsResult |= 32; + if ('create' in permissions && permissions.create) + permissionsResult |= 16; if ('delete' in permissions && permissions.delete) permissionsResult |= 8; if ('manage' in permissions && permissions.manage) diff --git a/lib/core/endpoints/data_sync/channel/create.js b/lib/core/endpoints/data_sync/channel/create.js new file mode 100644 index 000000000..70052251c --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/create.js @@ -0,0 +1,48 @@ +"use strict"; +/** + * Create Channel REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateChannelRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// endregion +/** + * Create Channel request. + * + * @internal + */ +class CreateChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNCreateChannelOperation; + } + validate() { + if (!this.parameters.channel) + return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/channels`; + } + get body() { + return JSON.stringify({ data: this.parameters.channel }); + } +} +exports.CreateChannelRequest = CreateChannelRequest; diff --git a/lib/core/endpoints/data_sync/channel/get-all.js b/lib/core/endpoints/data_sync/channel/get-all.js new file mode 100644 index 000000000..1cf77d7bb --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/get-all.js @@ -0,0 +1,47 @@ +"use strict"; +/** + * Get All Channels REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetAllChannelsRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion +/** + * Get All Channels request. + * + * @internal + */ +class GetAllChannelsRequest extends request_1.AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return operations_1.default.PNGetAllChannelsOperation; + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`; + } + get queryParameters() { + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } +} +exports.GetAllChannelsRequest = GetAllChannelsRequest; diff --git a/lib/core/endpoints/data_sync/channel/get.js b/lib/core/endpoints/data_sync/channel/get.js new file mode 100644 index 000000000..4a7604b90 --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/get.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * Get Channel REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetChannelRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Get Channel request. + * + * @internal + */ +class GetChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNGetChannelOperation; + } + validate() { + if (!this.parameters.id) + return 'Channel id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${(0, utils_1.encodeString)(id)}`; + } +} +exports.GetChannelRequest = GetChannelRequest; diff --git a/lib/core/endpoints/data_sync/channel/patch.js b/lib/core/endpoints/data_sync/channel/patch.js new file mode 100644 index 000000000..59234a96d --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/patch.js @@ -0,0 +1,67 @@ +"use strict"; +/** + * Patch Channel REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PatchChannelRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const data_sync_1 = require("../../../types/api/data-sync"); +const utils_1 = require("../../../utils"); +// endregion +/** + * Patch Channel request. + * + * @internal + */ +class PatchChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNPatchChannelOperation; + } + validate() { + if (!this.parameters.id) + return 'Channel id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${(0, utils_1.encodeString)(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} +exports.PatchChannelRequest = PatchChannelRequest; diff --git a/lib/core/endpoints/data_sync/channel/remove.js b/lib/core/endpoints/data_sync/channel/remove.js new file mode 100644 index 000000000..648f5d014 --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/remove.js @@ -0,0 +1,60 @@ +"use strict"; +/** + * Remove Channel REST API module. + * + * @internal + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RemoveChannelRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Remove Channel request. + * + * @internal + */ +class RemoveChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNRemoveChannelOperation; + } + validate() { + if (!this.parameters.id) + return 'Channel id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${(0, utils_1.encodeString)(id)}`; + } +} +exports.RemoveChannelRequest = RemoveChannelRequest; diff --git a/lib/core/endpoints/data_sync/channel/update.js b/lib/core/endpoints/data_sync/channel/update.js new file mode 100644 index 000000000..530e0558c --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/update.js @@ -0,0 +1,55 @@ +"use strict"; +/** + * Update Channel REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UpdateChannelRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Update Channel request. + * + * @internal + */ +class UpdateChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNUpdateChannelOperation; + } + validate() { + if (!this.parameters.id) + return 'Channel id cannot be empty'; + if (!this.parameters.channel) + return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${(0, utils_1.encodeString)(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.channel }); + } +} +exports.UpdateChannelRequest = UpdateChannelRequest; diff --git a/lib/core/endpoints/data_sync/entity/create.js b/lib/core/endpoints/data_sync/entity/create.js index 5cfb59db5..5e5e626e4 100644 --- a/lib/core/endpoints/data_sync/entity/create.js +++ b/lib/core/endpoints/data_sync/entity/create.js @@ -36,14 +36,12 @@ class CreateEntityRequest extends request_1.AbstractRequest { } get headers() { var _a; - let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); } get path() { const { keySet: { subscribeKey }, } = this.parameters; - return `/subkeys/${subscribeKey}/entities`; + return `/v1/datasync/subkeys/${subscribeKey}/entities`; } get body() { return JSON.stringify({ data: this.parameters.entity }); diff --git a/lib/core/endpoints/data_sync/entity/get-all.js b/lib/core/endpoints/data_sync/entity/get-all.js index 5d02092fc..8611a3691 100644 --- a/lib/core/endpoints/data_sync/entity/get-all.js +++ b/lib/core/endpoints/data_sync/entity/get-all.js @@ -41,7 +41,7 @@ class GetAllEntitiesRequest extends request_1.AbstractRequest { return 'Entity class cannot be empty'; } get path() { - return `/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/entities`; } get queryParameters() { const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; diff --git a/lib/core/endpoints/data_sync/entity/get.js b/lib/core/endpoints/data_sync/entity/get.js index 25a62ab40..89c9fe919 100644 --- a/lib/core/endpoints/data_sync/entity/get.js +++ b/lib/core/endpoints/data_sync/entity/get.js @@ -32,7 +32,7 @@ class GetEntityRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; } } exports.GetEntityRequest = GetEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/patch.js b/lib/core/endpoints/data_sync/entity/patch.js index 1b1452ca1..e26581132 100644 --- a/lib/core/endpoints/data_sync/entity/patch.js +++ b/lib/core/endpoints/data_sync/entity/patch.js @@ -3,8 +3,8 @@ * Patch Entity REST API module. * * Partial update via JSON Patch (RFC 6902). - * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) - * and converts them to JSON Patch operations on the wire. + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. * * @internal */ @@ -35,33 +35,32 @@ class PatchEntityRequest extends request_1.AbstractRequest { validate() { if (!this.parameters.id) return 'Entity id cannot be empty'; - const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; - if (!hasSet && !hasRemove) - return 'At least one of set or remove must be provided'; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; } get headers() { var _a; let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; } get body() { // Prefix all field paths with 'payload.' so users write simple field names // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. - const prefixedSet = this.parameters.set - ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) - : undefined; + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; - // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). - const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedSet, prefixedRemove); + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedAdd, prefixedReplace, prefixedRemove); return JSON.stringify(jsonPatchOps); } } diff --git a/lib/core/endpoints/data_sync/entity/remove.js b/lib/core/endpoints/data_sync/entity/remove.js index ad2d9e88f..9979e5c0e 100644 --- a/lib/core/endpoints/data_sync/entity/remove.js +++ b/lib/core/endpoints/data_sync/entity/remove.js @@ -54,7 +54,7 @@ class RemoveEntityRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; } } exports.RemoveEntityRequest = RemoveEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/update.js b/lib/core/endpoints/data_sync/entity/update.js index bb9896be0..59a10cbd5 100644 --- a/lib/core/endpoints/data_sync/entity/update.js +++ b/lib/core/endpoints/data_sync/entity/update.js @@ -47,7 +47,7 @@ class UpdateEntityRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${(0, utils_1.encodeString)(id)}`; } get body() { return JSON.stringify({ data: this.parameters.entity }); diff --git a/lib/core/endpoints/data_sync/membership/create.js b/lib/core/endpoints/data_sync/membership/create.js new file mode 100644 index 000000000..5f0465700 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/create.js @@ -0,0 +1,52 @@ +"use strict"; +/** + * Create Membership REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateMembershipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// endregion +/** + * Create Membership request. + * + * @internal + */ +class CreateMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNCreateMembershipOperation; + } + validate() { + if (!this.parameters.membership) + return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) + return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) + return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) + return 'Relationship class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships`; + } + get body() { + return JSON.stringify({ data: this.parameters.membership }); + } +} +exports.CreateMembershipRequest = CreateMembershipRequest; diff --git a/lib/core/endpoints/data_sync/membership/get-all.js b/lib/core/endpoints/data_sync/membership/get-all.js new file mode 100644 index 000000000..24eed2965 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/get-all.js @@ -0,0 +1,47 @@ +"use strict"; +/** + * Get All Memberships REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetAllMembershipsRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion +/** + * Get All Memberships request. + * + * @internal + */ +class GetAllMembershipsRequest extends request_1.AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return operations_1.default.PNGetAllMembershipsOperation; + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`; + } + get queryParameters() { + const { userId, channelId, relationshipClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (userId ? { user_id: userId } : {})), (channelId ? { channel_id: channelId } : {})), (relationshipClassVersion !== undefined ? { relationship_class_version: `${relationshipClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } +} +exports.GetAllMembershipsRequest = GetAllMembershipsRequest; diff --git a/lib/core/endpoints/data_sync/membership/get.js b/lib/core/endpoints/data_sync/membership/get.js new file mode 100644 index 000000000..1c813b804 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/get.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * Get Membership REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetMembershipRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Get Membership request. + * + * @internal + */ +class GetMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNGetMembershipOperation; + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${(0, utils_1.encodeString)(id)}`; + } +} +exports.GetMembershipRequest = GetMembershipRequest; diff --git a/lib/core/endpoints/data_sync/membership/patch.js b/lib/core/endpoints/data_sync/membership/patch.js new file mode 100644 index 000000000..54e3576d7 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/patch.js @@ -0,0 +1,67 @@ +"use strict"; +/** + * Patch Membership REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PatchMembershipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const data_sync_1 = require("../../../types/api/data-sync"); +const utils_1 = require("../../../utils"); +// endregion +/** + * Patch Membership request. + * + * @internal + */ +class PatchMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNPatchMembershipOperation; + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${(0, utils_1.encodeString)(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} +exports.PatchMembershipRequest = PatchMembershipRequest; diff --git a/lib/core/endpoints/data_sync/membership/remove.js b/lib/core/endpoints/data_sync/membership/remove.js new file mode 100644 index 000000000..339d6f0bf --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/remove.js @@ -0,0 +1,60 @@ +"use strict"; +/** + * Remove Membership REST API module. + * + * @internal + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RemoveMembershipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Remove Membership request. + * + * @internal + */ +class RemoveMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNRemoveMembershipOperation; + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${(0, utils_1.encodeString)(id)}`; + } +} +exports.RemoveMembershipRequest = RemoveMembershipRequest; diff --git a/lib/core/endpoints/data_sync/membership/update.js b/lib/core/endpoints/data_sync/membership/update.js new file mode 100644 index 000000000..12d096a57 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/update.js @@ -0,0 +1,57 @@ +"use strict"; +/** + * Update Membership REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UpdateMembershipRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Update Membership request. + * + * @internal + */ +class UpdateMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNUpdateMembershipOperation; + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + if (!this.parameters.membership) + return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) + return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) + return 'Channel id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${(0, utils_1.encodeString)(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.membership }); + } +} +exports.UpdateMembershipRequest = UpdateMembershipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/create.js b/lib/core/endpoints/data_sync/relationship/create.js index 15db5ddef..85e216e2f 100644 --- a/lib/core/endpoints/data_sync/relationship/create.js +++ b/lib/core/endpoints/data_sync/relationship/create.js @@ -33,17 +33,19 @@ class CreateRelationshipRequest extends request_1.AbstractRequest { return 'Entity A id cannot be empty'; if (!this.parameters.relationship.entityBId) return 'Entity B id cannot be empty'; + if (!this.parameters.relationship.relationshipClass) + return 'Relationship class cannot be empty'; + if (!this.parameters.relationship.relationshipClassVersion) + return 'Relationship class version cannot be empty'; } get headers() { var _a; - let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); } get path() { const { keySet: { subscribeKey }, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships`; + return `/v1/datasync/subkeys/${subscribeKey}/relationships`; } get body() { return JSON.stringify({ data: this.parameters.relationship }); diff --git a/lib/core/endpoints/data_sync/relationship/get-all.js b/lib/core/endpoints/data_sync/relationship/get-all.js index 4e60df6f9..191bd8537 100644 --- a/lib/core/endpoints/data_sync/relationship/get-all.js +++ b/lib/core/endpoints/data_sync/relationship/get-all.js @@ -36,12 +36,16 @@ class GetAllRelationshipsRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllRelationshipsOperation; } + validate() { + if (!this.parameters.relationshipClass) + return 'Relationship class cannot be empty'; + } get path() { - return `/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; } get queryParameters() { - const { entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + const { relationshipClass, relationshipClassVersion, entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced, } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ relationship_class: relationshipClass }, (relationshipClassVersion !== undefined ? { relationship_class_version: `${relationshipClassVersion}` } : {})), (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } exports.GetAllRelationshipsRequest = GetAllRelationshipsRequest; diff --git a/lib/core/endpoints/data_sync/relationship/get.js b/lib/core/endpoints/data_sync/relationship/get.js index 9edc65cd6..88e6fb306 100644 --- a/lib/core/endpoints/data_sync/relationship/get.js +++ b/lib/core/endpoints/data_sync/relationship/get.js @@ -32,7 +32,7 @@ class GetRelationshipRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; } } exports.GetRelationshipRequest = GetRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/patch.js b/lib/core/endpoints/data_sync/relationship/patch.js index 6e25fb9ac..c335d955c 100644 --- a/lib/core/endpoints/data_sync/relationship/patch.js +++ b/lib/core/endpoints/data_sync/relationship/patch.js @@ -3,8 +3,8 @@ * Patch Relationship REST API module. * * Partial update via JSON Patch (RFC 6902). - * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) - * and converts them to JSON Patch operations on the wire. + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. * * @internal */ @@ -35,33 +35,32 @@ class PatchRelationshipRequest extends request_1.AbstractRequest { validate() { if (!this.parameters.id) return 'Relationship id cannot be empty'; - const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; - if (!hasSet && !hasRemove) - return 'At least one of set or remove must be provided'; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; } get headers() { var _a; let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; } get body() { // Prefix all field paths with 'payload.' so users write simple field names // (e.g., 'role') and the SDK produces '/payload/role' on the wire. - const prefixedSet = this.parameters.set - ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) - : undefined; + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; - // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). - const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedSet, prefixedRemove); + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedAdd, prefixedReplace, prefixedRemove); return JSON.stringify(jsonPatchOps); } } diff --git a/lib/core/endpoints/data_sync/relationship/remove.js b/lib/core/endpoints/data_sync/relationship/remove.js index 25bc77d84..74cc8d527 100644 --- a/lib/core/endpoints/data_sync/relationship/remove.js +++ b/lib/core/endpoints/data_sync/relationship/remove.js @@ -54,7 +54,7 @@ class RemoveRelationshipRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; } } exports.RemoveRelationshipRequest = RemoveRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/update.js b/lib/core/endpoints/data_sync/relationship/update.js index 0d6928c4a..77e6e1ee0 100644 --- a/lib/core/endpoints/data_sync/relationship/update.js +++ b/lib/core/endpoints/data_sync/relationship/update.js @@ -38,6 +38,8 @@ class UpdateRelationshipRequest extends request_1.AbstractRequest { return 'Entity A id cannot be empty'; if (!this.parameters.relationship.entityBId) return 'Entity B id cannot be empty'; + if (!this.parameters.relationship.relationshipClassVersion) + return 'Relationship class version cannot be empty'; } get headers() { var _a; @@ -48,7 +50,7 @@ class UpdateRelationshipRequest extends request_1.AbstractRequest { } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; } get body() { return JSON.stringify({ data: this.parameters.relationship }); diff --git a/lib/core/endpoints/data_sync/user/create.js b/lib/core/endpoints/data_sync/user/create.js new file mode 100644 index 000000000..0d6cca6fa --- /dev/null +++ b/lib/core/endpoints/data_sync/user/create.js @@ -0,0 +1,48 @@ +"use strict"; +/** + * Create User REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.CreateUserRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// endregion +/** + * Create User request. + * + * @internal + */ +class CreateUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNCreateUserOperation; + } + validate() { + if (!this.parameters.user) + return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/users`; + } + get body() { + return JSON.stringify({ data: this.parameters.user }); + } +} +exports.CreateUserRequest = CreateUserRequest; diff --git a/lib/core/endpoints/data_sync/user/get-all.js b/lib/core/endpoints/data_sync/user/get-all.js new file mode 100644 index 000000000..ebf470d5e --- /dev/null +++ b/lib/core/endpoints/data_sync/user/get-all.js @@ -0,0 +1,47 @@ +"use strict"; +/** + * Get All Users REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetAllUsersRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +// -------------------------------------------------------- +// ----------------------- Defaults ----------------------- +// -------------------------------------------------------- +// region Defaults +/** + * Default number of items per page. + */ +const DEFAULT_LIMIT = 20; +// endregion +/** + * Get All Users request. + * + * @internal + */ +class GetAllUsersRequest extends request_1.AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return operations_1.default.PNGetAllUsersOperation; + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`; + } + get queryParameters() { + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } +} +exports.GetAllUsersRequest = GetAllUsersRequest; diff --git a/lib/core/endpoints/data_sync/user/get.js b/lib/core/endpoints/data_sync/user/get.js new file mode 100644 index 000000000..b7037038f --- /dev/null +++ b/lib/core/endpoints/data_sync/user/get.js @@ -0,0 +1,38 @@ +"use strict"; +/** + * Get User REST API module. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GetUserRequest = void 0; +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Get User request. + * + * @internal + */ +class GetUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNGetUserOperation; + } + validate() { + if (!this.parameters.id) + return 'User id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/users/${(0, utils_1.encodeString)(id)}`; + } +} +exports.GetUserRequest = GetUserRequest; diff --git a/lib/core/endpoints/data_sync/user/patch.js b/lib/core/endpoints/data_sync/user/patch.js new file mode 100644 index 000000000..360c7fdac --- /dev/null +++ b/lib/core/endpoints/data_sync/user/patch.js @@ -0,0 +1,67 @@ +"use strict"; +/** + * Patch User REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.PatchUserRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const data_sync_1 = require("../../../types/api/data-sync"); +const utils_1 = require("../../../utils"); +// endregion +/** + * Patch User request. + * + * @internal + */ +class PatchUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNPatchUserOperation; + } + validate() { + if (!this.parameters.id) + return 'User id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/users/${(0, utils_1.encodeString)(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } +} +exports.PatchUserRequest = PatchUserRequest; diff --git a/lib/core/endpoints/data_sync/user/remove.js b/lib/core/endpoints/data_sync/user/remove.js new file mode 100644 index 000000000..b2d7aa1f4 --- /dev/null +++ b/lib/core/endpoints/data_sync/user/remove.js @@ -0,0 +1,60 @@ +"use strict"; +/** + * Remove User REST API module. + * + * @internal + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.RemoveUserRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Remove User request. + * + * @internal + */ +class RemoveUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNRemoveUserOperation; + } + validate() { + if (!this.parameters.id) + return 'User id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/users/${(0, utils_1.encodeString)(id)}`; + } +} +exports.RemoveUserRequest = RemoveUserRequest; diff --git a/lib/core/endpoints/data_sync/user/update.js b/lib/core/endpoints/data_sync/user/update.js new file mode 100644 index 000000000..8fd35528e --- /dev/null +++ b/lib/core/endpoints/data_sync/user/update.js @@ -0,0 +1,55 @@ +"use strict"; +/** + * Update User REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.UpdateUserRequest = void 0; +const transport_request_1 = require("../../../types/transport-request"); +const request_1 = require("../../../components/request"); +const operations_1 = __importDefault(require("../../../constants/operations")); +const utils_1 = require("../../../utils"); +// endregion +/** + * Update User request. + * + * @internal + */ +class UpdateUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNUpdateUserOperation; + } + validate() { + if (!this.parameters.id) + return 'User id cannot be empty'; + if (!this.parameters.user) + return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/users/${(0, utils_1.encodeString)(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.user }); + } +} +exports.UpdateUserRequest = UpdateUserRequest; diff --git a/lib/core/endpoints/subscribe.js b/lib/core/endpoints/subscribe.js index fbcdea493..ef98e4f42 100644 --- a/lib/core/endpoints/subscribe.js +++ b/lib/core/endpoints/subscribe.js @@ -64,7 +64,31 @@ var PubNubEventType; * Files event. */ PubNubEventType[PubNubEventType["Files"] = 4] = "Files"; + /** + * DataSync object change event. + * + * **Note:** Value must equal `5` to match the service wire value (`e: 5`). + */ + PubNubEventType[PubNubEventType["DataSync"] = 5] = "DataSync"; })(PubNubEventType || (exports.PubNubEventType = PubNubEventType = {})); +/** + * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * + * NOTE: the exact wire `className` for typed User/Channel/Membership resources must be confirmed by + * running the `ds-event-test` spike against an origin that emits DataSync events. Keys are compared + * case-insensitively after `className.split(':').pop()`. Best-guess values are derived from the create + * content-types (`application/vnd.pubnub.objects.{user,channel,membership}+json`). + * + * @internal + */ +const DATA_SYNC_RESERVED_CLASSES = { + user: 'user', + channel: 'channel', + membership: 'membership', + pn_user: 'user', + pn_channel: 'channel', + pn_membership: 'membership', +}; // endregion /** * Base subscription request implementation. @@ -172,6 +196,13 @@ class BaseSubscribeRequest extends request_1.AbstractRequest { pn_mfp, }; } + else if (eventType === PubNubEventType.DataSync) { + const dataSync = this.dataSyncFromEnvelope(envelope); + // Guard: only treat as DataSync when the service marks it so; otherwise fall back to message. + if (dataSync) + return { type: PubNubEventType.DataSync, data: dataSync, pn_mfp }; + return { type: PubNubEventType.Message, data: this.messageFromEnvelope(envelope), pn_mfp }; + } return { type: PubNubEventType.Files, data: this.fileFromEnvelope(envelope), @@ -277,6 +308,53 @@ class BaseSubscribeRequest extends request_1.AbstractRequest { message: object, }; } + dataSyncFromEnvelope(envelope) { + var _a; + const [channel, subscription] = this.subscriptionChannelFromEnvelope(envelope); + const payload = envelope.d; + const metadata = payload === null || payload === void 0 ? void 0 : payload.metadata; + // Only treat the envelope as DataSync when the service marks it and carries the required fields. + if (!metadata || metadata.source !== 'data-sync' || !metadata.event || !metadata.type) + return undefined; + // Wire `className` is a positional composite `::`: + // - typed User/Channel/Membership → `User::` / `Channel::` / `Membership::` (system in 1st segment) + // - generic entity / relationship → `::Customer` / `::REQUESTED_BY` (developer in last segment) + // The reserved system class (1st segment) drives `objectType`; the surfaced `className` is the + // developer class (last non-empty segment) when present, else the system class. + const classSegments = metadata.className ? metadata.className.split(':') : []; + const systemClass = classSegments.length > 0 ? classSegments[0] : undefined; + const nonEmptySegments = classSegments.filter((segment) => segment.length > 0); + const className = nonEmptySegments.length > 0 ? nonEmptySegments[nonEmptySegments.length - 1] : undefined; + const objectType = (systemClass && DATA_SYNC_RESERVED_CLASSES[systemClass.toLowerCase()]) || metadata.type; + const parsedVersion = metadata.classVersion !== undefined ? Number.parseInt(`${metadata.classVersion}`, 10) : NaN; + const classVersion = Number.isNaN(parsedVersion) ? undefined : parsedVersion; + const raw = ((_a = payload.data) !== null && _a !== void 0 ? _a : {}); + let data; + if (metadata.event === 'delete') { + data = { id: raw.id, deletedAt: raw.deletedAt }; + } + else if (metadata.type === 'relationship') { + data = Object.assign(Object.assign({}, raw), { relationshipClass: className, relationshipClassVersion: classVersion }); + } + else { + data = Object.assign(Object.assign({}, raw), { entityClass: className, entityClassVersion: classVersion }); + } + return { + channel, + subscription, + timetoken: envelope.p.t, + message: { + version: payload.version, + event: metadata.event, + source: metadata.source, + type: metadata.type, + objectType, + className, + classVersion, + data, + }, + }; + } fileFromEnvelope(envelope) { const [channel, subscription] = this.subscriptionChannelFromEnvelope(envelope); const [file, decryptionError] = this.decryptedData(envelope.d); diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index 4ecda0e9b..abea51bc6 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -3092,6 +3092,20 @@ class PubNubCore { else throw new Error('Listener error: subscription module disabled'); } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + if (process.env.SUBSCRIBE_MODULE !== 'disabled') { + if (this.eventDispatcher) + this.eventDispatcher.onDataSync = listener; + } + else + throw new Error('Listener error: subscription module disabled'); + } /** * Set events handler. * diff --git a/lib/core/pubnub-data-sync.js b/lib/core/pubnub-data-sync.js index eaf88b758..012511b56 100644 --- a/lib/core/pubnub-data-sync.js +++ b/lib/core/pubnub-data-sync.js @@ -12,18 +12,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -const create_1 = require("./endpoints/data_sync/relationship/create"); -const get_all_1 = require("./endpoints/data_sync/relationship/get-all"); -const update_1 = require("./endpoints/data_sync/relationship/update"); -const remove_1 = require("./endpoints/data_sync/relationship/remove"); -const patch_1 = require("./endpoints/data_sync/relationship/patch"); -const get_1 = require("./endpoints/data_sync/relationship/get"); -const create_2 = require("./endpoints/data_sync/entity/create"); -const get_all_2 = require("./endpoints/data_sync/entity/get-all"); -const update_2 = require("./endpoints/data_sync/entity/update"); -const remove_2 = require("./endpoints/data_sync/entity/remove"); -const patch_2 = require("./endpoints/data_sync/entity/patch"); -const get_2 = require("./endpoints/data_sync/entity/get"); +const create_1 = require("./endpoints/data_sync/user/create"); +const get_all_1 = require("./endpoints/data_sync/user/get-all"); +const update_1 = require("./endpoints/data_sync/user/update"); +const remove_1 = require("./endpoints/data_sync/user/remove"); +const patch_1 = require("./endpoints/data_sync/user/patch"); +const get_1 = require("./endpoints/data_sync/user/get"); +const create_2 = require("./endpoints/data_sync/channel/create"); +const get_all_2 = require("./endpoints/data_sync/channel/get-all"); +const update_2 = require("./endpoints/data_sync/channel/update"); +const remove_2 = require("./endpoints/data_sync/channel/remove"); +const patch_2 = require("./endpoints/data_sync/channel/patch"); +const get_2 = require("./endpoints/data_sync/channel/get"); +const create_3 = require("./endpoints/data_sync/membership/create"); +const get_all_3 = require("./endpoints/data_sync/membership/get-all"); +const update_3 = require("./endpoints/data_sync/membership/update"); +const remove_3 = require("./endpoints/data_sync/membership/remove"); +const patch_3 = require("./endpoints/data_sync/membership/patch"); +const get_3 = require("./endpoints/data_sync/membership/get"); +const create_4 = require("./endpoints/data_sync/relationship/create"); +const get_all_4 = require("./endpoints/data_sync/relationship/get-all"); +const update_4 = require("./endpoints/data_sync/relationship/update"); +const remove_4 = require("./endpoints/data_sync/relationship/remove"); +const patch_4 = require("./endpoints/data_sync/relationship/patch"); +const get_4 = require("./endpoints/data_sync/relationship/get"); +const create_5 = require("./endpoints/data_sync/entity/create"); +const get_all_5 = require("./endpoints/data_sync/entity/get-all"); +const update_5 = require("./endpoints/data_sync/entity/update"); +const remove_5 = require("./endpoints/data_sync/entity/remove"); +const patch_5 = require("./endpoints/data_sync/entity/patch"); +const get_5 = require("./endpoints/data_sync/entity/get"); /** * PubNub DataSync API interface. */ @@ -68,7 +86,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Create Entity with parameters:', })); - const request = new create_2.CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new create_5.CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -89,7 +107,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Get Entity with parameters:', })); - const request = new get_2.GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_5.GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -110,7 +128,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Get all Entities with parameters:', })); - const request = new get_all_2.GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_5.GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -131,7 +149,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Update Entity with parameters:', })); - const request = new update_2.UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new update_5.UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -140,7 +158,7 @@ class PubNubDataSync { /** * Patch an Entity (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -154,7 +172,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Patch Entity with parameters:', })); - const request = new patch_2.PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new patch_5.PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -175,7 +193,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Remove Entity with parameters:', })); - const request = new remove_2.RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new remove_5.RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -196,7 +214,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Create Relationship with parameters:', })); - const request = new create_1.CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new create_4.CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -217,7 +235,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Get Relationship with parameters:', })); - const request = new get_1.GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_4.GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -226,21 +244,19 @@ class PubNubDataSync { /** * Fetch a paginated list of Relationships. * - * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. */ - getAllRelationships(parametersOrCallback, callback) { + getAllRelationships(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { - const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; - callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), details: 'Get all Relationships with parameters:', })); - const request = new get_all_1.GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_4.GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -261,7 +277,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Update Relationship with parameters:', })); - const request = new update_1.UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new update_4.UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -270,7 +286,7 @@ class PubNubDataSync { /** * Patch a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -284,7 +300,7 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Patch Relationship with parameters:', })); - const request = new patch_1.PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new patch_4.PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -305,7 +321,397 @@ class PubNubDataSync { message: Object.assign({}, parameters), details: 'Remove Relationship with parameters:', })); - const request = new remove_1.RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new remove_4.RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create user response or `void` in case if `callback` provided. + */ + createUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create User with parameters:', + })); + const request = new create_1.CreateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get user response or `void` in case if `callback` provided. + */ + getUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get User with parameters:', + })); + const request = new get_1.GetUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Users. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all users response or `void` in case if `callback` provided. + */ + getAllUsers(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Users with parameters:', + })); + const request = new get_all_1.GetAllUsersRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a User (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update user response or `void` in case if `callback` provided. + */ + updateUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update User with parameters:', + })); + const request = new update_1.UpdateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch user response or `void` in case if `callback` provided. + */ + patchUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch User with parameters:', + })); + const request = new patch_1.PatchUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove user response or `void` in case if `callback` provided. + */ + removeUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove User with parameters:', + })); + const request = new remove_1.RemoveUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create channel response or `void` in case if `callback` provided. + */ + createChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Channel with parameters:', + })); + const request = new create_2.CreateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get channel response or `void` in case if `callback` provided. + */ + getChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Channel with parameters:', + })); + const request = new get_2.GetChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Channels. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all channels response or `void` in case if `callback` provided. + */ + getAllChannels(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Channels with parameters:', + })); + const request = new get_all_2.GetAllChannelsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update channel response or `void` in case if `callback` provided. + */ + updateChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Channel with parameters:', + })); + const request = new update_2.UpdateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch channel response or `void` in case if `callback` provided. + */ + patchChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Channel with parameters:', + })); + const request = new patch_2.PatchChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove channel response or `void` in case if `callback` provided. + */ + removeChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Channel with parameters:', + })); + const request = new remove_2.RemoveChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create membership response or `void` in case if `callback` provided. + */ + createMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Membership with parameters:', + })); + const request = new create_3.CreateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get membership response or `void` in case if `callback` provided. + */ + getMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Membership with parameters:', + })); + const request = new get_3.GetMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Memberships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all memberships response or `void` in case if `callback` provided. + */ + getAllMemberships(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Memberships with parameters:', + })); + const request = new get_all_3.GetAllMembershipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update membership response or `void` in case if `callback` provided. + */ + updateMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Membership with parameters:', + })); + const request = new update_3.UpdateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch membership response or `void` in case if `callback` provided. + */ + patchMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Membership with parameters:', + })); + const request = new patch_3.PatchMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove membership response or `void` in case if `callback` provided. + */ + removeMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Membership with parameters:', + })); + const request = new remove_3.RemoveMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); diff --git a/lib/core/types/api/data-sync.js b/lib/core/types/api/data-sync.js index becbd26ae..4c0b549d5 100644 --- a/lib/core/types/api/data-sync.js +++ b/lib/core/types/api/data-sync.js @@ -19,20 +19,26 @@ function toJsonPointer(dotPath) { return '/' + dotPath.split('.').join('/'); } /** - * Convert `set` and `remove` parameters to JSON Patch operations (wire format). + * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). * - * - Each key in `set` becomes a "replace" operation. + * - Each key in `add` becomes an "add" operation. + * - Each key in `replace` becomes a "replace" operation. * - Each entry in `remove` becomes a "remove" operation. * * @internal */ -function toJsonPatchOperations(set, remove) { +function toJsonPatchOperations(add, replace, remove) { const ops = []; - if (set) { - for (const [dotPath, value] of Object.entries(set)) { + if (add) { + for (const [dotPath, value] of Object.entries(add)) { ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); } } + if (replace) { + for (const [dotPath, value] of Object.entries(replace)) { + ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); + } + } if (remove) { for (const dotPath of remove) { ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); diff --git a/lib/entities/subscription-base.js b/lib/entities/subscription-base.js index 6db037bd0..904ee319f 100644 --- a/lib/entities/subscription-base.js +++ b/lib/entities/subscription-base.js @@ -236,6 +236,15 @@ class SubscriptionBase { set onFile(listener) { this.eventDispatcher.onFile = listener; } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + this.eventDispatcher.onDataSync = listener; + } /** * Set events handler. * diff --git a/lib/types/index.d.ts b/lib/types/index.d.ts index 03b3dcec6..711a35094 100644 --- a/lib/types/index.d.ts +++ b/lib/types/index.d.ts @@ -1387,6 +1387,13 @@ declare class PubNubCore< * is received from the real-time network. */ set onFile(listener: ((event: PubNub.Subscription.File) => void) | undefined); + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener: ((event: PubNub.Subscription.DataSyncObject) => void) | undefined); /** * Set events handler. * @@ -2091,6 +2098,78 @@ declare namespace PubNub { * Remove relationship REST API operation. */ PNRemoveRelationshipOperation = 'PNRemoveRelationshipOperation', + /** + * Create user REST API operation. + */ + PNCreateUserOperation = 'PNCreateUserOperation', + /** + * Get user REST API operation. + */ + PNGetUserOperation = 'PNGetUserOperation', + /** + * Get all users REST API operation. + */ + PNGetAllUsersOperation = 'PNGetAllUsersOperation', + /** + * Update user REST API operation. + */ + PNUpdateUserOperation = 'PNUpdateUserOperation', + /** + * Patch user REST API operation. + */ + PNPatchUserOperation = 'PNPatchUserOperation', + /** + * Remove user REST API operation. + */ + PNRemoveUserOperation = 'PNRemoveUserOperation', + /** + * Create channel REST API operation. + */ + PNCreateChannelOperation = 'PNCreateChannelOperation', + /** + * Get channel REST API operation. + */ + PNGetChannelOperation = 'PNGetChannelOperation', + /** + * Get all channels REST API operation. + */ + PNGetAllChannelsOperation = 'PNGetAllChannelsOperation', + /** + * Update channel REST API operation. + */ + PNUpdateChannelOperation = 'PNUpdateChannelOperation', + /** + * Patch channel REST API operation. + */ + PNPatchChannelOperation = 'PNPatchChannelOperation', + /** + * Remove channel REST API operation. + */ + PNRemoveChannelOperation = 'PNRemoveChannelOperation', + /** + * Create membership REST API operation. + */ + PNCreateMembershipOperation = 'PNCreateMembershipOperation', + /** + * Get membership REST API operation. + */ + PNGetMembershipOperation = 'PNGetMembershipOperation', + /** + * Get all memberships REST API operation. + */ + PNGetAllMembershipsOperation = 'PNGetAllMembershipsOperation', + /** + * Update membership REST API operation. + */ + PNUpdateMembershipOperation = 'PNUpdateMembershipOperation', + /** + * Patch membership REST API operation. + */ + PNPatchMembershipOperation = 'PNPatchMembershipOperation', + /** + * Remove membership REST API operation. + */ + PNRemoveMembershipOperation = 'PNRemoveMembershipOperation', /** * Fetch list of files sent to the channel REST API operation. */ @@ -3580,6 +3659,12 @@ declare namespace PubNub { * @param file - Shared file information. */ file?: (file: Subscription.File) => void; + /** + * Real-time DataSync change events listener. + * + * @param event - Changed DataSync object information. + */ + dataSync?: (event: Subscription.DataSyncObject) => void; /** * Real-time PubNub client status change event. * @@ -3642,6 +3727,12 @@ declare namespace PubNub { * Files event. */ Files = 4, + /** + * DataSync object change event. + * + * **Note:** Value must equal `5` to match the service wire value (`e: 5`). + */ + DataSync = 5, } /** @@ -3933,6 +4024,148 @@ declare namespace PubNub { */ export type AppContextObjectData = ChannelObjectData | UuidObjectData | MembershipObjectData; + /** + * DataSync change event kinds. + */ + type DataSyncEventName = 'create' | 'update' | 'delete'; + + /** + * DataSync object kinds carried on the wire (raw service value). + */ + type DataSyncObjectType = 'entity' | 'relationship'; + + /** + * Normalized DataSync object kind derived from the wire `className`. + * + * Users and Channels are backed by entity classes; Memberships by a relationship class. This + * discriminator lets consumers branch on the semantic kind in a `dataSync` listener without matching + * class-name strings. Falls back to the raw wire {@link DataSyncObjectType} for unrecognized classes. + */ + export type DataSyncNormalizedType = 'user' | 'channel' | 'membership' | 'entity' | 'relationship'; + + /** + * DataSync entity change payload (create / update). + */ + export type DataSyncEntityData = { + /** + * Unique entity identifier. + */ + id: string; + /** + * Lifecycle status. + */ + status?: string; + /** + * User-defined JSON payload. + */ + payload?: Payload; + /** + * Date and time the entity was created (ISO 8601). + */ + createdAt?: string; + /** + * Date and time the entity was last updated (ISO 8601). + */ + updatedAt?: string; + /** + * Content fingerprint for optimistic concurrency control. + */ + eTag?: string; + /** + * Auto-deletion timestamp (ISO 8601). + */ + expiresAt?: string; + /** + * Entity class name (last `:`-delimited segment of the wire `className`). + */ + entityClass?: string; + /** + * Version of the entity class schema (parsed from the wire `classVersion`). + */ + entityClassVersion?: number; + }; + + /** + * DataSync relationship change payload (create / update). + */ + export type DataSyncRelationshipData = Omit & { + /** + * First entity id in the relationship. + */ + entityAId?: string; + /** + * Second entity id in the relationship. + */ + entityBId?: string; + /** + * Relationship class name (last `:`-delimited segment of the wire `className`). + */ + relationshipClass?: string; + /** + * Version of the relationship class schema (parsed from the wire `classVersion`). + */ + relationshipClassVersion?: number; + }; + + /** + * DataSync delete change payload. + */ + export type DataSyncDeleteData = { + /** + * Unique identifier of the removed object. + */ + id: string; + /** + * Date and time the object was removed (ISO 8601). + */ + deletedAt?: string; + }; + + /** + * Parsed DataSync change event (dispatched under `message`). + */ + export type DataSyncData = { + /** + * DataSync service payload version. + */ + version?: string; + /** + * The type of change which happened to the object. + */ + event: DataSyncEventName; + /** + * Name of the service which generated the update (always `data-sync`). + */ + source: string; + /** + * Raw DataSync object kind as sent by the service. + */ + type: DataSyncObjectType; + /** + * Normalized DataSync object kind. + * + * Derived from {@link className}: reserved User/Channel/Membership classes map to `'user'` / + * `'channel'` / `'membership'`; everything else falls back to the raw wire {@link type} + * (`'entity'` / `'relationship'`). Use this to discriminate typed resources without knowing + * class-name strings. + */ + objectType: DataSyncNormalizedType; + /** + * Object class name (last `:`-delimited segment of the wire `className`). + */ + className?: string; + /** + * Version of the object class schema (parsed from the wire `classVersion`). + */ + classVersion?: number; + /** + * Changed object information. + * + * For `delete` events only `{ id, deletedAt }` is populated. + */ + data: DataSyncEntityData | DataSyncRelationshipData | DataSyncDeleteData; + }; + /** * File service response. */ @@ -4628,6 +4861,12 @@ declare namespace PubNub { * Function, which will be called each time when a new file is received from the real-time network. */ onFile?: (event: Subscription.File) => void; + /** + * Set a new DataSync event handler. + * + * Function, which will be called each time when a new DataSync event is received from the real-time network. + */ + onDataSync?: (event: Subscription.DataSyncObject) => void; /** * Set events handler. * @@ -4794,6 +5033,13 @@ declare namespace PubNub { * is received from the real-time network. */ set onFile(listener: ((event: Subscription.File) => void) | undefined); + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener: ((event: Subscription.DataSyncObject) => void) | undefined); /** * Set events handler. * @@ -5629,7 +5875,7 @@ declare namespace PubNub { /** * Patch an Entity (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -5641,7 +5887,7 @@ declare namespace PubNub { /** * Patch an Entity (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @@ -5702,12 +5948,6 @@ declare namespace PubNub { * @returns Asynchronous get relationship response. */ getRelationship(parameters: DataSync.GetRelationshipParameters): Promise; - /** - * Fetch a paginated list of Relationships. - * - * @param callback - Request completion handler callback. - */ - getAllRelationships(callback: ResultCallback): void; /** * Fetch a paginated list of Relationships. * @@ -5721,12 +5961,12 @@ declare namespace PubNub { /** * Fetch a paginated list of Relationships. * - * @param [parameters] - Request configuration parameters. + * @param parameters - Request configuration parameters. * * @returns Asynchronous get all relationships response. */ getAllRelationships( - parameters?: DataSync.GetAllRelationshipsParameters, + parameters: DataSync.GetAllRelationshipsParameters, ): Promise; /** * Update a Relationship (full replacement via PUT). @@ -5749,7 +5989,7 @@ declare namespace PubNub { /** * Patch a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -5761,7 +6001,7 @@ declare namespace PubNub { /** * Patch a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @@ -5786,647 +6026,1001 @@ declare namespace PubNub { * @returns Asynchronous remove relationship response. */ removeRelationship(parameters: DataSync.RemoveRelationshipParameters): Promise; - } - - /** - * Logging module manager. - * - * Manager responsible for log requests handling and forwarding to the registered {@link Logger logger} implementations. - */ - export class LoggerManager {} - - export namespace Subscription { /** - * Time cursor. + * Create a new User. * - * Cursor used by subscription loop to identify point in time after which updates will be - * delivered. + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type SubscriptionCursor = { - /** - * PubNub high-precision timestamp. - * - * Aside of specifying exact time of receiving data / event this token used to catchup / - * follow on real-time updates. - */ - timetoken: string; - /** - * Data center region for which `timetoken` has been generated. - */ - region?: number; - }; - + createUser(parameters: DataSync.CreateUserParameters, callback: ResultCallback): void; /** - * Common real-time event. + * Create a new User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create user response. */ - type Event = { - /** - * Channel to which real-time event has been sent. - */ - channel: string; - /** - * Actual subscription at which real-time event has been received. - * - * PubNub client provide various ways to subscribe to the real-time stream: channel groups, - * wildcard subscription, and spaces. - * - * **Note:** Value will be `null` if it is the same as {@link channel}. - */ - subscription: string | null; - /** - * High-precision PubNub timetoken with time when event has been received by PubNub services. - */ - timetoken: string; - }; - + createUser(parameters: DataSync.CreateUserParameters): Promise; /** - * Common legacy real-time event for backward compatibility. + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type LegacyEvent = Event & { - /** - * Channel to which real-time event has been sent. - * - * @deprecated Use {@link channel} field instead. - */ - actualChannel?: string | null; - /** - * Actual subscription at which real-time event has been received. - * - * @deprecated Use {@link subscription} field instead. - */ - subscribedChannel?: string; - }; - + getUser(parameters: DataSync.GetUserParameters, callback: ResultCallback): void; /** - * Presence change real-time event. + * Fetch a specific User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get user response. */ - export type Presence = LegacyEvent & PresenceData; - + getUser(parameters: DataSync.GetUserParameters): Promise; /** - * Extended presence real-time event. + * Fetch a paginated list of Users. * - * Type extended for listener manager support. + * @param callback - Request completion handler callback. */ - type PresenceEvent = { - type: PubNubEventType.Presence; - data: Presence; - }; - + getAllUsers(callback: ResultCallback): void; /** - * Common published data information. + * Fetch a paginated list of Users. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type PublishedData = { - /** - * Unique identifier of the user which sent data. - */ - publisher?: string; - /** - * Additional user-provided metadata which can be used with real-time filtering expression. - */ - userMetadata?: { - [p: string]: Payload; - }; - /** - * User-provided message type. - */ - customMessageType?: string; - /** - * Sent data. - */ - message: Payload; - }; - + getAllUsers( + parameters: DataSync.GetAllUsersParameters, + callback: ResultCallback, + ): void; /** - * Real-time message event. + * Fetch a paginated list of Users. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all users response. */ - export type Message = LegacyEvent & - PublishedData & { - /** - * Decryption error message in case of failure. - */ - error?: string; - }; - + getAllUsers(parameters?: DataSync.GetAllUsersParameters): Promise; /** - * Extended real-time message event. + * Update a User (full replacement via PUT). * - * Type extended for listener manager support. + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type MessageEvent = { - type: PubNubEventType.Message; - data: Message; - }; - + updateUser(parameters: DataSync.UpdateUserParameters, callback: ResultCallback): void; /** - * Real-time signal event. + * Update a User (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update user response. */ - export type Signal = Event & PublishedData; - + updateUser(parameters: DataSync.UpdateUserParameters): Promise; /** - * Extended real-time signal event. + * Patch a User (partial update via JSON Patch RFC 6902). * - * Type extended for listener manager support. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type SignalEvent = { - type: PubNubEventType.Signal; - data: Signal; - }; - + patchUser(parameters: DataSync.PatchUserParameters, callback: ResultCallback): void; /** - * Message action real-time event. + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch user response. */ - export type MessageAction = Event & - Omit & { - /** - * Unique identifier of the user which added message reaction. - * - * @deprecated Use `data.uuid` field instead. - */ - publisher?: string; - data: MessageActionData['data'] & { - /** - * Unique identifier of the user which added message reaction. - */ - uuid: string; - }; - }; - + patchUser(parameters: DataSync.PatchUserParameters): Promise; /** - * Extended message action real-time event. + * Remove a User. * - * Type extended for listener manager support. + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type MessageActionEvent = { - type: PubNubEventType.MessageAction; - data: MessageAction; - }; - + removeUser(parameters: DataSync.RemoveUserParameters, callback: ResultCallback): void; /** - * App Context Object change real-time event. + * Remove a User. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove user response. */ - export type AppContextObject = Event & { - /** - * Information about App Context object for which event received. - */ - message: AppContextObjectData; - }; - + removeUser(parameters: DataSync.RemoveUserParameters): Promise; /** - * `User` App Context Object change real-time event. + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type UserAppContextObject = Omit & { - /** - * Space to which real-time event has been sent. - */ - spaceId: string; - /** - * Information about User Object for which event received. - */ - message: UserObjectData; - }; - + createChannel( + parameters: DataSync.CreateChannelParameters, + callback: ResultCallback, + ): void; /** - * `Space` App Context Object change real-time event. + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create channel response. */ - export type SpaceAppContextObject = Omit & { - /** - * Space to which real-time event has been sent. - */ - spaceId: string; - /** - * Information about `Space` Object for which event received. - */ - message: SpaceObjectData; - }; - + createChannel(parameters: DataSync.CreateChannelParameters): Promise; /** - * VSP `Membership` App Context Object change real-time event. + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type VSPMembershipAppContextObject = Omit & { - /** - * Space to which real-time event has been sent. - */ - spaceId: string; - /** - * Information about `Membership` Object for which event received. - */ - message: VSPMembershipObjectData; - }; - + getChannel(parameters: DataSync.GetChannelParameters, callback: ResultCallback): void; /** - * Extended App Context Object change real-time event. + * Fetch a specific Channel. * - * Type extended for listener manager support. + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get channel response. */ - type AppContextEvent = { - type: PubNubEventType.AppContext; - data: AppContextObject; - }; - + getChannel(parameters: DataSync.GetChannelParameters): Promise; /** - * File real-time event. + * Fetch a paginated list of Channels. + * + * @param callback - Request completion handler callback. */ - export type File = Event & - Omit & - Omit & { - /** - * Message which has been associated with uploaded file. - */ - message?: Payload; - /** - * Information about uploaded file. - */ - file?: FileData['file'] & { - /** - * File download url. - */ - url: string; - }; - /** - * Decryption error message in case of failure. - */ - error?: string; - }; - + getAllChannels(callback: ResultCallback): void; /** - * Extended File real-time event. + * Fetch a paginated list of Channels. * - * Type extended for listener manager support. + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - type FileEvent = { - type: PubNubEventType.Files; - data: File; - }; - + getAllChannels( + parameters: DataSync.GetAllChannelsParameters, + callback: ResultCallback, + ): void; /** - * Subscribe request parameters. + * Fetch a paginated list of Channels. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all channels response. */ - export type SubscribeParameters = { - /** - * List of channels from which real-time events should be delivered. - * - * @default `,` if {@link channelGroups} is set. - */ - channels?: string[]; - /** - * List of channel groups from which real-time events should be retrieved. - */ - channelGroups?: string[]; - /** - * Next subscription loop timetoken. - */ - timetoken?: string | number; - /** - * Whether should subscribe to channels / groups presence announcements or not. - * - * @default `false` - */ - withPresence?: boolean; - /** - * Presence information which should be associated with `userId`. - * - * `state` information will be associated with `userId` on channels mentioned as keys in - * this object. - * - * @deprecated Use set state methods to specify associated user's data instead of passing to - * subscribe. - */ - state?: Record; - /** - * Whether should subscribe to channels / groups presence announcements or not. - * - * @default `false` - */ - withHeartbeats?: boolean; - }; - + getAllChannels(parameters?: DataSync.GetAllChannelsParameters): Promise; /** - * Service success response. + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type SubscriptionResponse = { - cursor: SubscriptionCursor; - messages: (PresenceEvent | MessageEvent | SignalEvent | MessageActionEvent | AppContextEvent | FileEvent)[]; - }; - } - - export namespace AppContext { + updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback: ResultCallback, + ): void; /** - * Partial nullability helper type. + * Update a Channel (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update channel response. */ - type PartialNullable = { - [P in keyof T]?: T[P] | null; - }; - + updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; /** - * Custom data which should be associated with metadata objects or their relation. + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type CustomData = { - [key: string]: string | number | boolean | null; - }; - + patchChannel( + parameters: DataSync.PatchChannelParameters, + callback: ResultCallback, + ): void; /** - * Type provides shape of App Context parameters which is common to the all objects types to - * be updated. + * Patch a Channel (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch channel response. */ - type ObjectParameters = { - custom?: Custom; - }; - + patchChannel(parameters: DataSync.PatchChannelParameters): Promise; /** - * Type provides shape of App Context object which is common to the all objects types received - * from the PubNub service. + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. */ - export type ObjectData = { - /** - * Unique App Context object identifier. - * - * **Important:** For channel it is different from the channel metadata object name. - */ - id: string; - /** - * Last date and time when App Context object has been updated. - * - * String built from date using ISO 8601. - */ - updated: string; + removeChannel( + parameters: DataSync.RemoveChannelParameters, + callback: ResultCallback, + ): void; + /** + * Remove a Channel. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove channel response. + */ + removeChannel(parameters: DataSync.RemoveChannelParameters): Promise; + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + createMembership( + parameters: DataSync.CreateMembershipParameters, + callback: ResultCallback, + ): void; + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous create membership response. + */ + createMembership(parameters: DataSync.CreateMembershipParameters): Promise; + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getMembership( + parameters: DataSync.GetMembershipParameters, + callback: ResultCallback, + ): void; + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous get membership response. + */ + getMembership(parameters: DataSync.GetMembershipParameters): Promise; + /** + * Fetch a paginated list of Memberships. + * + * @param callback - Request completion handler callback. + */ + getAllMemberships(callback: ResultCallback): void; + /** + * Fetch a paginated list of Memberships. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + getAllMemberships( + parameters: DataSync.GetAllMembershipsParameters, + callback: ResultCallback, + ): void; + /** + * Fetch a paginated list of Memberships. + * + * @param [parameters] - Request configuration parameters. + * + * @returns Asynchronous get all memberships response. + */ + getAllMemberships(parameters?: DataSync.GetAllMembershipsParameters): Promise; + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback: ResultCallback, + ): void; + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous update membership response. + */ + updateMembership(parameters: DataSync.UpdateMembershipParameters): Promise; + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + patchMembership( + parameters: DataSync.PatchMembershipParameters, + callback: ResultCallback, + ): void; + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous patch membership response. + */ + patchMembership(parameters: DataSync.PatchMembershipParameters): Promise; + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * @param callback - Request completion handler callback. + */ + removeMembership( + parameters: DataSync.RemoveMembershipParameters, + callback: ResultCallback, + ): void; + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * + * @returns Asynchronous remove membership response. + */ + removeMembership(parameters: DataSync.RemoveMembershipParameters): Promise; + } + + /** + * Logging module manager. + * + * Manager responsible for log requests handling and forwarding to the registered {@link Logger logger} implementations. + */ + export class LoggerManager {} + + export namespace Subscription { + /** + * Time cursor. + * + * Cursor used by subscription loop to identify point in time after which updates will be + * delivered. + */ + export type SubscriptionCursor = { /** - * App Context version hash. + * PubNub high-precision timestamp. + * + * Aside of specifying exact time of receiving data / event this token used to catchup / + * follow on real-time updates. */ - eTag: string; + timetoken: string; /** - * Additional data associated with App Context object. - * - * **Important:** Values must be scalars; only arrays or objects are supported. - * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|App Context - * filtering language} doesn’t support filtering by custom properties. + * Data center region for which `timetoken` has been generated. */ - custom?: Custom | null; + region?: number; }; /** - * Type provides shape of object which let establish relation between metadata objects. + * Common real-time event. */ - type ObjectsRelation = { - /** - * App Context object unique identifier. - */ - id: string; + type Event = { /** - * App Context objects relation status. + * Channel to which real-time event has been sent. */ - status?: string; + channel: string; /** - * App Context objects relation type. + * Actual subscription at which real-time event has been received. + * + * PubNub client provide various ways to subscribe to the real-time stream: channel groups, + * wildcard subscription, and spaces. + * + * **Note:** Value will be `null` if it is the same as {@link channel}. */ - type?: string; + subscription: string | null; /** - * Additional data associated with App Context object relation (membership or members). - * - * **Important:** Values must be scalars; only arrays or objects are supported. - * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|App Context - * filtering language} doesn’t support filtering by custom properties. + * High-precision PubNub timetoken with time when event has been received by PubNub services. */ - custom?: Custom; + timetoken: string; }; /** - * Response page cursor. + * Common legacy real-time event for backward compatibility. */ - type Page = { + type LegacyEvent = Event & { /** - * Random string returned from the server, indicating a specific position in a data set. + * Channel to which real-time event has been sent. * - * Used for forward pagination, it fetches the next page, allowing you to continue from where - * you left off. + * @deprecated Use {@link channel} field instead. */ - next?: string; + actualChannel?: string | null; /** - * Random string returned from the server, indicating a specific position in a data set. - * - * Used for backward pagination, it fetches the previous page, enabling access to earlier - * data. + * Actual subscription at which real-time event has been received. * - * **Important:** Ignored if the `next` parameter is supplied. + * @deprecated Use {@link subscription} field instead. */ - prev?: string; + subscribedChannel?: string; }; /** - * Metadata objects include options. + * Presence change real-time event. + */ + export type Presence = LegacyEvent & PresenceData; + + /** + * Extended presence real-time event. * - * Allows to configure what additional information should be included into service response. + * Type extended for listener manager support. */ - type IncludeOptions = { - /** - * Whether to include total number of App Context objects in the response. - * - * @default `false` - */ - totalCount?: boolean; - /** - * Whether to include App Context object `custom` field in the response. - * - * @default `false` - */ - customFields?: boolean; + type PresenceEvent = { + type: PubNubEventType.Presence; + data: Presence; }; /** - * Membership objects include options. - * - * Allows to configure what additional information should be included into service response. + * Common published data information. */ - type MembershipsIncludeOptions = IncludeOptions & { - /** - * Whether to include all {@link ChannelMetadata} fields in the response. - * - * @default `false` - */ - channelFields?: boolean; - /** - * Whether to include {@link ChannelMetadata} `custom` field in the response. - * - * @default `false` - */ - customChannelFields?: boolean; + type PublishedData = { /** - * Whether to include the membership's `status` field in the response. - * - * @default `false` + * Unique identifier of the user which sent data. */ - statusField?: boolean; + publisher?: string; /** - * Whether to include the membership's `type` field in the response. - * - * @default `false` + * Additional user-provided metadata which can be used with real-time filtering expression. */ - typeField?: boolean; + userMetadata?: { + [p: string]: Payload; + }; /** - * Whether to include the channel's status field in the response. - * - * @default `false` + * User-provided message type. */ - channelStatusField?: boolean; + customMessageType?: string; /** - * Whether to include channel's type fields in the response. - * - * @default `false` + * Sent data. */ - channelTypeField?: boolean; + message: Payload; }; /** - * Members objects include options. + * Real-time message event. + */ + export type Message = LegacyEvent & + PublishedData & { + /** + * Decryption error message in case of failure. + */ + error?: string; + }; + + /** + * Extended real-time message event. * - * Allows to configure what additional information should be included into service response. + * Type extended for listener manager support. */ - type MembersIncludeOptions = IncludeOptions & { - /** - * Whether to include all {@link UUIMetadata} fields in the response. - * - * @default `false` - */ - UUIDFields?: boolean; - /** - * Whether to include {@link UUIMetadata} `custom` field in the response. - * - * @default `false` - */ - customUUIDFields?: boolean; - /** - * Whether to include the member's `status` field in the response. - * - * @default `false` - */ - statusField?: boolean; + type MessageEvent = { + type: PubNubEventType.Message; + data: Message; + }; + + /** + * Real-time signal event. + */ + export type Signal = Event & PublishedData; + + /** + * Extended real-time signal event. + * + * Type extended for listener manager support. + */ + type SignalEvent = { + type: PubNubEventType.Signal; + data: Signal; + }; + + /** + * Message action real-time event. + */ + export type MessageAction = Event & + Omit & { + /** + * Unique identifier of the user which added message reaction. + * + * @deprecated Use `data.uuid` field instead. + */ + publisher?: string; + data: MessageActionData['data'] & { + /** + * Unique identifier of the user which added message reaction. + */ + uuid: string; + }; + }; + + /** + * Extended message action real-time event. + * + * Type extended for listener manager support. + */ + type MessageActionEvent = { + type: PubNubEventType.MessageAction; + data: MessageAction; + }; + + /** + * App Context Object change real-time event. + */ + export type AppContextObject = Event & { /** - * Whether to include the member's `type` field in the response. - * - * @default `false` + * Information about App Context object for which event received. */ - typeField?: boolean; + message: AppContextObjectData; + }; + + /** + * `User` App Context Object change real-time event. + */ + export type UserAppContextObject = Omit & { /** - * Whether to include the user's status field in the response. - * - * @default `false` + * Space to which real-time event has been sent. */ - UUIDStatusField?: boolean; + spaceId: string; /** - * Whether to include user's type fields in the response. - * - * @default `false` + * Information about User Object for which event received. */ - UUIDTypeField?: boolean; + message: UserObjectData; }; /** - * Type provides shape of App Context parameters which is common to the all objects types to - * fetch them by pages. + * `Space` App Context Object change real-time event. */ - type PagedRequestParameters = { - /** - * Fields which can be additionally included into response. - */ - include?: Include; + export type SpaceAppContextObject = Omit & { /** - * Expression used to filter the results. - * - * Only objects whose properties satisfy the given expression are returned. The filter language is - * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|defined here}. + * Space to which real-time event has been sent. */ - filter?: string; + spaceId: string; /** - * Fetched App Context objects sorting options. + * Information about `Space` Object for which event received. */ - sort?: Sort; + message: SpaceObjectData; + }; + + /** + * VSP `Membership` App Context Object change real-time event. + */ + export type VSPMembershipAppContextObject = Omit & { /** - * Number of objects to return in response. - * - * **Important:** Maximum for this API is `100` objects per-response. - * - * @default `100` + * Space to which real-time event has been sent. */ - limit?: number; + spaceId: string; /** - * Response pagination configuration. + * Information about `Membership` Object for which event received. */ - page?: Page; + message: VSPMembershipObjectData; }; /** - * Type provides shape of App Context object fetch response which is common to the all objects - * types received from the PubNub service. + * Extended App Context Object change real-time event. + * + * Type extended for listener manager support. */ - type ObjectResponse = { - /** - * App Context objects list fetch result status code. - */ - status: number; + type AppContextEvent = { + type: PubNubEventType.AppContext; + data: AppContextObject; + }; + + /** + * File real-time event. + */ + export type File = Event & + Omit & + Omit & { + /** + * Message which has been associated with uploaded file. + */ + message?: Payload; + /** + * Information about uploaded file. + */ + file?: FileData['file'] & { + /** + * File download url. + */ + url: string; + }; + /** + * Decryption error message in case of failure. + */ + error?: string; + }; + + /** + * Extended File real-time event. + * + * Type extended for listener manager support. + */ + type FileEvent = { + type: PubNubEventType.Files; + data: File; + }; + + /** + * DataSync object change real-time event. + */ + export type DataSyncObject = Event & { /** - * Received App Context object information. + * Parsed DataSync change payload. */ - data: ObjectType; + message: DataSyncData; }; /** - * Type provides shape of App Context objects fetch response which is common to the all - * objects types received from the PubNub service. + * Subscribe request parameters. */ - type PagedResponse = ObjectResponse & { + export type SubscribeParameters = { /** - * Total number of App Context objects in the response. + * List of channels from which real-time events should be delivered. + * + * @default `,` if {@link channelGroups} is set. */ - totalCount?: number; + channels?: string[]; /** - * Random string returned from the server, indicating a specific position in a data set. + * List of channel groups from which real-time events should be retrieved. + */ + channelGroups?: string[]; + /** + * Next subscription loop timetoken. + */ + timetoken?: string | number; + /** + * Whether should subscribe to channels / groups presence announcements or not. * - * Used for forward pagination, it fetches the next page, allowing you to continue from where - * you left off. + * @default `false` */ - next?: string; + withPresence?: boolean; /** - * Random string returned from the server, indicating a specific position in a data set. + * Presence information which should be associated with `userId`. * - * Used for backward pagination, it fetches the previous page, enabling access to earlier - * data. + * `state` information will be associated with `userId` on channels mentioned as keys in + * this object. * - * **Important:** Ignored if the `next` parameter is supplied. + * @deprecated Use set state methods to specify associated user's data instead of passing to + * subscribe. */ - prev?: string; + state?: Record; + /** + * Whether should subscribe to channels / groups presence announcements or not. + * + * @default `false` + */ + withHeartbeats?: boolean; }; /** - * Key-value pair of a property to sort by, and a sort direction. + * Service success response. */ - type MetadataSortingOptions = - | keyof Omit - | ({ - [K in keyof Omit]?: 'asc' | 'desc' | null; - } & { - [key: `custom.${string}`]: 'asc' | 'desc' | null; - }); + export type SubscriptionResponse = { + cursor: SubscriptionCursor; + messages: ( + | PresenceEvent + | MessageEvent + | SignalEvent + | MessageActionEvent + | AppContextEvent + | FileEvent + | DataSyncEvent + )[]; + }; + } + export namespace AppContext { /** - * Key-value pair of a property to sort by, and a sort direction. + * Partial nullability helper type. */ - type MembershipsSortingOptions = - | 'channel.id' - | 'channel.name' - | 'channel.description' - | 'channel.updated' - | 'channel.status' - | 'channel.type' - | 'space.id' - | 'space.name' - | 'space.description' - | 'space.updated' - | 'updated' - | 'status' - | 'type' - | { - /** - * Sort results by channel's `id` in ascending (`asc`) or descending (`desc`) order. - * + type PartialNullable = { + [P in keyof T]?: T[P] | null; + }; + + /** + * Custom data which should be associated with metadata objects or their relation. + */ + export type CustomData = { + [key: string]: string | number | boolean | null; + }; + + /** + * Type provides shape of App Context parameters which is common to the all objects types to + * be updated. + */ + type ObjectParameters = { + custom?: Custom; + }; + + /** + * Type provides shape of App Context object which is common to the all objects types received + * from the PubNub service. + */ + export type ObjectData = { + /** + * Unique App Context object identifier. + * + * **Important:** For channel it is different from the channel metadata object name. + */ + id: string; + /** + * Last date and time when App Context object has been updated. + * + * String built from date using ISO 8601. + */ + updated: string; + /** + * App Context version hash. + */ + eTag: string; + /** + * Additional data associated with App Context object. + * + * **Important:** Values must be scalars; only arrays or objects are supported. + * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|App Context + * filtering language} doesn’t support filtering by custom properties. + */ + custom?: Custom | null; + }; + + /** + * Type provides shape of object which let establish relation between metadata objects. + */ + type ObjectsRelation = { + /** + * App Context object unique identifier. + */ + id: string; + /** + * App Context objects relation status. + */ + status?: string; + /** + * App Context objects relation type. + */ + type?: string; + /** + * Additional data associated with App Context object relation (membership or members). + * + * **Important:** Values must be scalars; only arrays or objects are supported. + * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|App Context + * filtering language} doesn’t support filtering by custom properties. + */ + custom?: Custom; + }; + + /** + * Response page cursor. + */ + type Page = { + /** + * Random string returned from the server, indicating a specific position in a data set. + * + * Used for forward pagination, it fetches the next page, allowing you to continue from where + * you left off. + */ + next?: string; + /** + * Random string returned from the server, indicating a specific position in a data set. + * + * Used for backward pagination, it fetches the previous page, enabling access to earlier + * data. + * + * **Important:** Ignored if the `next` parameter is supplied. + */ + prev?: string; + }; + + /** + * Metadata objects include options. + * + * Allows to configure what additional information should be included into service response. + */ + type IncludeOptions = { + /** + * Whether to include total number of App Context objects in the response. + * + * @default `false` + */ + totalCount?: boolean; + /** + * Whether to include App Context object `custom` field in the response. + * + * @default `false` + */ + customFields?: boolean; + }; + + /** + * Membership objects include options. + * + * Allows to configure what additional information should be included into service response. + */ + type MembershipsIncludeOptions = IncludeOptions & { + /** + * Whether to include all {@link ChannelMetadata} fields in the response. + * + * @default `false` + */ + channelFields?: boolean; + /** + * Whether to include {@link ChannelMetadata} `custom` field in the response. + * + * @default `false` + */ + customChannelFields?: boolean; + /** + * Whether to include the membership's `status` field in the response. + * + * @default `false` + */ + statusField?: boolean; + /** + * Whether to include the membership's `type` field in the response. + * + * @default `false` + */ + typeField?: boolean; + /** + * Whether to include the channel's status field in the response. + * + * @default `false` + */ + channelStatusField?: boolean; + /** + * Whether to include channel's type fields in the response. + * + * @default `false` + */ + channelTypeField?: boolean; + }; + + /** + * Members objects include options. + * + * Allows to configure what additional information should be included into service response. + */ + type MembersIncludeOptions = IncludeOptions & { + /** + * Whether to include all {@link UUIMetadata} fields in the response. + * + * @default `false` + */ + UUIDFields?: boolean; + /** + * Whether to include {@link UUIMetadata} `custom` field in the response. + * + * @default `false` + */ + customUUIDFields?: boolean; + /** + * Whether to include the member's `status` field in the response. + * + * @default `false` + */ + statusField?: boolean; + /** + * Whether to include the member's `type` field in the response. + * + * @default `false` + */ + typeField?: boolean; + /** + * Whether to include the user's status field in the response. + * + * @default `false` + */ + UUIDStatusField?: boolean; + /** + * Whether to include user's type fields in the response. + * + * @default `false` + */ + UUIDTypeField?: boolean; + }; + + /** + * Type provides shape of App Context parameters which is common to the all objects types to + * fetch them by pages. + */ + type PagedRequestParameters = { + /** + * Fields which can be additionally included into response. + */ + include?: Include; + /** + * Expression used to filter the results. + * + * Only objects whose properties satisfy the given expression are returned. The filter language is + * {@link /docs/sdks/javascript/api-reference/objects#app-context-filtering-language-definition|defined here}. + */ + filter?: string; + /** + * Fetched App Context objects sorting options. + */ + sort?: Sort; + /** + * Number of objects to return in response. + * + * **Important:** Maximum for this API is `100` objects per-response. + * + * @default `100` + */ + limit?: number; + /** + * Response pagination configuration. + */ + page?: Page; + }; + + /** + * Type provides shape of App Context object fetch response which is common to the all objects + * types received from the PubNub service. + */ + type ObjectResponse = { + /** + * App Context objects list fetch result status code. + */ + status: number; + /** + * Received App Context object information. + */ + data: ObjectType; + }; + + /** + * Type provides shape of App Context objects fetch response which is common to the all + * objects types received from the PubNub service. + */ + type PagedResponse = ObjectResponse & { + /** + * Total number of App Context objects in the response. + */ + totalCount?: number; + /** + * Random string returned from the server, indicating a specific position in a data set. + * + * Used for forward pagination, it fetches the next page, allowing you to continue from where + * you left off. + */ + next?: string; + /** + * Random string returned from the server, indicating a specific position in a data set. + * + * Used for backward pagination, it fetches the previous page, enabling access to earlier + * data. + * + * **Important:** Ignored if the `next` parameter is supplied. + */ + prev?: string; + }; + + /** + * Key-value pair of a property to sort by, and a sort direction. + */ + type MetadataSortingOptions = + | keyof Omit + | ({ + [K in keyof Omit]?: 'asc' | 'desc' | null; + } & { + [key: `custom.${string}`]: 'asc' | 'desc' | null; + }); + + /** + * Key-value pair of a property to sort by, and a sort direction. + */ + type MembershipsSortingOptions = + | 'channel.id' + | 'channel.name' + | 'channel.description' + | 'channel.updated' + | 'channel.status' + | 'channel.type' + | 'space.id' + | 'space.name' + | 'space.description' + | 'space.updated' + | 'updated' + | 'status' + | 'type' + | { + /** + * Sort results by channel's `id` in ascending (`asc`) or descending (`desc`) order. + * * Specify `null` for default sorting direction (ascending). */ 'channel.id'?: 'asc' | 'desc' | null; @@ -6603,67 +7197,365 @@ declare namespace PubNub { }; /** - * Fetch All UUID or Channel Metadata request parameters. + * Fetch All UUID or Channel Metadata request parameters. + */ + export type GetAllMetadataParameters = PagedRequestParameters< + IncludeOptions, + MetadataSortingOptions + >; + + /** + * Type which describes own UUID metadata object fields. + */ + type UUIDMetadataFields = { + /** + * Display name for the user. + */ + name?: string; + /** + * The user's email address. + */ + email?: string; + /** + * User's identifier in an external system. + */ + externalId?: string; + /** + * The URL of the user's profile picture. + */ + profileUrl?: string; + /** + * User's object type information. + */ + type?: string; + /** + * User's object status. + */ + status?: string; + }; + + /** + * Updated UUID metadata object. + * + * Type represents updated UUID metadata object which will be pushed to the PubNub service. + */ + type UUIDMetadata = ObjectParameters & Partial; + + /** + * Received UUID metadata object. + * + * Type represents UUID metadata retrieved from the PubNub service. + */ + export type UUIDMetadataObject = ObjectData & + PartialNullable; + + /** + * Response with fetched page of UUID metadata objects. + */ + export type GetAllUUIDMetadataResponse = PagedResponse>; + + /** + * Fetch UUID Metadata request parameters. + */ + export type GetUUIDMetadataParameters = { + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `uuid`. + */ + uuid?: string; + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `userId`. + * + * @deprecated Use `getUUIDMetadata()` method instead. + */ + userId?: string; + /** + * Fields which can be additionally included into response. + */ + include?: Omit; + }; + + /** + * Response with requested UUID metadata object. */ - export type GetAllMetadataParameters = PagedRequestParameters< - IncludeOptions, - MetadataSortingOptions - >; + export type GetUUIDMetadataResponse = ObjectResponse>; /** - * Type which describes own UUID metadata object fields. + * Update UUID Metadata request parameters. */ - type UUIDMetadataFields = { + export type SetUUIDMetadataParameters = { /** - * Display name for the user. + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `uuid`. */ - name?: string; + uuid?: string; /** - * The user's email address. + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `userId`. + * + * @deprecated Use `setUUIDMetadata()` method instead. */ - email?: string; + userId?: string; /** - * User's identifier in an external system. + * Metadata, which should be associated with UUID. */ - externalId?: string; + data: UUIDMetadata; /** - * The URL of the user's profile picture. + * Fields which can be additionally included into response. */ - profileUrl?: string; + include?: Omit; /** - * User's object type information. + * Optional entity tag from a previously received `PNUUIDMetadata`. The request + * will fail if this parameter is specified and the ETag value on the server doesn't match. + */ + ifMatchesEtag?: string; + }; + + /** + * Response with result of the UUID metadata object update. + */ + export type SetUUIDMetadataResponse = ObjectResponse>; + + /** + * Remove UUID Metadata request parameters. + */ + export type RemoveUUIDMetadataParameters = { + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `uuid`. + */ + uuid?: string; + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `userId`. + * + * @deprecated Use `removeUUIDMetadata()` method instead. + */ + userId?: string; + }; + + /** + * Response with result of the UUID metadata removal. + */ + export type RemoveUUIDMetadataResponse = ObjectResponse>; + + /** + * Type which describes own Channel metadata object fields. + */ + type ChannelMetadataFields = { + /** + * Name of a channel. + */ + name?: string; + /** + * Description of a channel. + */ + description?: string; + /** + * Channel's object type information. */ type?: string; /** - * User's object status. + * Channel's object status. */ status?: string; }; /** - * Updated UUID metadata object. + * Updated channel metadata object. * - * Type represents updated UUID metadata object which will be pushed to the PubNub service. + * Type represents updated channel metadata object which will be pushed to the PubNub service. */ - type UUIDMetadata = ObjectParameters & Partial; + type ChannelMetadata = ObjectParameters & Partial; /** - * Received UUID metadata object. + * Received channel metadata object. * - * Type represents UUID metadata retrieved from the PubNub service. + * Type represents chanel metadata retrieved from the PubNub service. */ - export type UUIDMetadataObject = ObjectData & - PartialNullable; + export type ChannelMetadataObject = ObjectData & + PartialNullable; /** - * Response with fetched page of UUID metadata objects. + * Response with fetched page of channel metadata objects. + */ + export type GetAllChannelMetadataResponse = PagedResponse>; + + /** + * Fetch Channel Metadata request parameters. + */ + export type GetChannelMetadataParameters = { + /** + * Channel name. + */ + channel: string; + /** + * Space identifier. + * + * @deprecated Use `getChannelMetadata()` method instead. + */ + spaceId?: string; + /** + * Fields which can be additionally included into response. + */ + include?: Omit; + }; + + /** + * Response with requested channel metadata object. + */ + export type GetChannelMetadataResponse = ObjectResponse>; + + /** + * Update Channel Metadata request parameters. + */ + export type SetChannelMetadataParameters = { + /** + * Channel name. + */ + channel: string; + /** + * Space identifier. + * + * @deprecated Use `setChannelMetadata()` method instead. + */ + spaceId?: string; + /** + * Metadata, which should be associated with UUID. + */ + data: ChannelMetadata; + /** + * Fields which can be additionally included into response. + */ + include?: Omit; + /** + * Optional entity tag from a previously received `PNUUIDMetadata`. The request + * will fail if this parameter is specified and the ETag value on the server doesn't match. + */ + ifMatchesEtag?: string; + }; + + /** + * Response with result of the channel metadata object update. + */ + export type SetChannelMetadataResponse = ObjectResponse>; + + /** + * Remove Channel Metadata request parameters. + */ + export type RemoveChannelMetadataParameters = { + /** + * Channel name. + */ + channel: string; + /** + * Space identifier. + * + * @deprecated Use `removeChannelMetadata()` method instead. + */ + spaceId?: string; + }; + + /** + * Response with result of the channel metadata removal. + */ + export type RemoveChannelMetadataResponse = ObjectResponse>; + + /** + * Related channel metadata object. + * + * Type represents chanel metadata which has been used to create membership relation with UUID. + */ + type MembershipsObject = Omit< + ObjectData, + 'id' + > & { + /** + * User's membership status. + */ + status?: string; + /** + * User's membership type. + */ + type?: string; + /** + * Channel for which `user` has membership. + */ + channel: + | ChannelMetadataObject + | { + id: string; + }; + }; + + /** + * Response with fetched page of UUID membership objects. + */ + type MembershipsResponse = PagedResponse< + MembershipsObject + >; + + /** + * Fetch Memberships request parameters. + */ + export type GetMembershipsParameters = PagedRequestParameters< + MembershipsIncludeOptions, + MembershipsSortingOptions + > & { + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `uuid`. + */ + uuid?: string; + /** + * Unique user identifier. + * + * **Important:** If not supplied then current user's uuid is used. + * + * @default Current `uuidId`. + * + * @deprecated Use `uuid` field instead. + */ + userId?: string; + }; + + /** + * Response with requested channel memberships information. */ - export type GetAllUUIDMetadataResponse = PagedResponse>; + export type GetMembershipsResponse< + MembershipCustom extends CustomData, + ChannelCustom extends CustomData, + > = MembershipsResponse; /** - * Fetch UUID Metadata request parameters. + * Update Memberships request parameters. */ - export type GetUUIDMetadataParameters = { + export type SetMembershipsParameters = PagedRequestParameters< + MembershipsIncludeOptions, + MembershipsSortingOptions + > & { /** * Unique user identifier. * @@ -6679,24 +7571,44 @@ declare namespace PubNub { * * @default Current `userId`. * - * @deprecated Use `getUUIDMetadata()` method instead. + * @deprecated Use `uuid` field instead. */ userId?: string; /** - * Fields which can be additionally included into response. + * List of channels with which UUID membership should be established. */ - include?: Omit; + channels: Array>; + /** + * List of channels with which UUID membership should be established. + * + * @deprecated Use `channels` field instead. + */ + spaces?: Array< + | string + | (Omit, 'id'> & { + /** + * Unique Space object identifier. + */ + spaceId: string; + }) + >; }; /** - * Response with requested UUID metadata object. + * Response with requested channel memberships information change. */ - export type GetUUIDMetadataResponse = ObjectResponse>; + export type SetMembershipsResponse< + MembershipCustom extends CustomData, + ChannelCustom extends CustomData, + > = MembershipsResponse; /** - * Update UUID Metadata request parameters. + * Remove Memberships request parameters. */ - export type SetUUIDMetadataParameters = { + export type RemoveMembershipsParameters = PagedRequestParameters< + MembershipsIncludeOptions, + MembershipsSortingOptions + > & { /** * Unique user identifier. * @@ -6712,2642 +7624,3029 @@ declare namespace PubNub { * * @default Current `userId`. * - * @deprecated Use `setUUIDMetadata()` method instead. + * @deprecated Use {@link uuid} field instead. */ userId?: string; /** - * Metadata, which should be associated with UUID. + * List of channels for which membership which UUID should be removed. */ - data: UUIDMetadata; + channels: string[]; /** - * Fields which can be additionally included into response. + * List of space names for which membership which UUID should be removed. + * + * @deprecated Use {@link channels} field instead. */ - include?: Omit; + spaceIds?: string[]; + }; + + /** + * Response with remaining memberships. + */ + export type RemoveMembershipsResponse< + MembershipCustom extends CustomData, + ChannelCustom extends CustomData, + > = MembershipsResponse; + + /** + * Related UUID metadata object. + * + * Type represents UUID metadata which has been used to when added members to the channel. + */ + type MembersObject = Omit< + ObjectData, + 'id' + > & { /** - * Optional entity tag from a previously received `PNUUIDMetadata`. The request - * will fail if this parameter is specified and the ETag value on the server doesn't match. + * Channel's member status. */ - ifMatchesEtag?: string; + status?: string; + /** + * Channel's member type. + */ + type?: string; + /** + * Member of the `channel`. + */ + uuid: + | UUIDMetadataObject + | { + id: string; + }; }; /** - * Response with result of the UUID metadata object update. + * Response with fetched page of channel member objects. */ - export type SetUUIDMetadataResponse = ObjectResponse>; + type MembersResponse = PagedResponse< + MembersObject + >; /** - * Remove UUID Metadata request parameters. + * Fetch Members request parameters. */ - export type RemoveUUIDMetadataParameters = { + export type GetMembersParameters = PagedRequestParameters & { /** - * Unique user identifier. - * - * **Important:** If not supplied then current user's uuid is used. - * - * @default Current `uuid`. + * Channel name. */ - uuid?: string; + channel: string; /** - * Unique user identifier. + * Space identifier. * - * **Important:** If not supplied then current user's uuid is used. + * @deprecated Use `channel` field instead. + */ + spaceId?: string; + }; + + /** + * Response with requested channel memberships information. + */ + export type GetMembersResponse = MembersResponse< + MembersCustom, + UUIDCustom + >; + + /** + * Update Members request parameters. + */ + export type SetChannelMembersParameters = PagedRequestParameters< + MembersIncludeOptions, + MembersSortingOptions + > & { + /** + * Channel name. + */ + channel: string; + /** + * Space identifier. * - * @default Current `userId`. + * @deprecated Use `channel` field instead. + */ + spaceId?: string; + /** + * List of UUIDs which should be added as `channel` members. + */ + uuids: Array>; + /** + * List of UUIDs which should be added as `channel` members. * - * @deprecated Use `removeUUIDMetadata()` method instead. + * @deprecated Use `uuids` field instead. */ - userId?: string; + users?: Array< + | string + | (Omit, 'id'> & { + /** + * Unique User object identifier. + */ + userId: string; + }) + >; }; /** - * Response with result of the UUID metadata removal. + * Response with requested channel members information change. */ - export type RemoveUUIDMetadataResponse = ObjectResponse>; + export type SetMembersResponse = MembersResponse< + MemberCustom, + UUIDCustom + >; /** - * Type which describes own Channel metadata object fields. + * Remove Members request parameters. */ - type ChannelMetadataFields = { + export type RemoveMembersParameters = PagedRequestParameters & { /** - * Name of a channel. + * Channel name. */ - name?: string; + channel: string; /** - * Description of a channel. + * Space identifier. + * + * @deprecated Use {@link channel} field instead. */ - description?: string; + spaceId?: string; /** - * Channel's object type information. + * List of UUIDs which should be removed from the `channel` members list. + * removed. */ - type?: string; + uuids: string[]; /** - * Channel's object status. + * List of user identifiers which should be removed from the `channel` members list. + * removed. + * + * @deprecated Use {@link uuids} field instead. */ - status?: string; + userIds?: string[]; }; /** - * Updated channel metadata object. - * - * Type represents updated channel metadata object which will be pushed to the PubNub service. + * Response with remaining members. */ - type ChannelMetadata = ObjectParameters & Partial; + export type RemoveMembersResponse = MembersResponse< + MemberCustom, + UUIDCustom + >; /** - * Received channel metadata object. + * Related User metadata object. * - * Type represents chanel metadata retrieved from the PubNub service. + * Type represents User metadata which has been used to when added members to the Space. */ - export type ChannelMetadataObject = ObjectData & - PartialNullable; + type UserMembersObject = Omit< + ObjectData, + 'id' + > & { + user: + | UUIDMetadataObject + | { + id: string; + }; + }; /** - * Response with fetched page of channel metadata objects. + * Response with fetched page of Space member objects. */ - export type GetAllChannelMetadataResponse = PagedResponse>; + export type UserMembersResponse = PagedResponse< + UserMembersObject + >; + + type SpaceMembershipObject = Omit< + ObjectData, + 'id' + > & { + space: + | ChannelMetadataObject + | { + id: string; + }; + }; /** - * Fetch Channel Metadata request parameters. + * Response with fetched page of User membership objects. */ - export type GetChannelMetadataParameters = { - /** - * Channel name. - */ - channel: string; + export type SpaceMembershipsResponse< + MembershipCustom extends CustomData, + ChannelCustom extends CustomData, + > = PagedResponse>; + } + + export namespace ChannelGroups { + /** + * Add or remove Channels to the channel group request parameters. + */ + export type ManageChannelGroupChannelsParameters = { /** - * Space identifier. - * - * @deprecated Use `getChannelMetadata()` method instead. + * Name of the channel group for which channels list should be changed. */ - spaceId?: string; + channelGroup: string; /** - * Fields which can be additionally included into response. + * List of channels to be added or removed. */ - include?: Omit; + channels: string[]; }; /** - * Response with requested channel metadata object. + * Channel group channels list manage response. */ - export type GetChannelMetadataResponse = ObjectResponse>; + export type ManageChannelGroupChannelsResponse = Record; /** - * Update Channel Metadata request parameters. + * Response with result of the all channel groups list. */ - export type SetChannelMetadataParameters = { - /** - * Channel name. - */ - channel: string; - /** - * Space identifier. - * - * @deprecated Use `setChannelMetadata()` method instead. - */ - spaceId?: string; - /** - * Metadata, which should be associated with UUID. - */ - data: ChannelMetadata; - /** - * Fields which can be additionally included into response. - */ - include?: Omit; + export type ListAllChannelGroupsResponse = { /** - * Optional entity tag from a previously received `PNUUIDMetadata`. The request - * will fail if this parameter is specified and the ETag value on the server doesn't match. + * All channel groups with channels. */ - ifMatchesEtag?: string; + groups: string[]; }; /** - * Response with result of the channel metadata object update. + * List Channel Group Channels request parameters. */ - export type SetChannelMetadataResponse = ObjectResponse>; + export type ListChannelGroupChannelsParameters = { + /** + * Name of the channel group for which list of channels should be retrieved. + */ + channelGroup: string; + }; /** - * Remove Channel Metadata request parameters. + * Response with result of the list channel group channels. */ - export type RemoveChannelMetadataParameters = { + export type ListChannelGroupChannelsResponse = { /** - * Channel name. + * List of the channels registered withing specified channel group. */ - channel: string; + channels: string[]; + }; + + /** + * Delete Channel Group request parameters. + */ + export type DeleteChannelGroupParameters = { /** - * Space identifier. - * - * @deprecated Use `removeChannelMetadata()` method instead. + * Name of the channel group which should be removed. */ - spaceId?: string; + channelGroup: string; }; /** - * Response with result of the channel metadata removal. + * Delete channel group response. */ - export type RemoveChannelMetadataResponse = ObjectResponse>; + export type DeleteChannelGroupResponse = Record; + } + export namespace Publish { /** - * Related channel metadata object. - * - * Type represents chanel metadata which has been used to create membership relation with UUID. + * Request configuration parameters. */ - type MembershipsObject = Omit< - ObjectData, - 'id' - > & { + export type PublishParameters = { /** - * User's membership status. + * Channel name to publish messages to. */ - status?: string; + channel: string; /** - * User's membership type. + * Data which should be sent to the `channel`. + * + * The message may be any valid JSON type including objects, arrays, strings, and numbers. */ - type?: string; + message: Payload; /** - * Channel for which `user` has membership. + * User-specified message type. + * + * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only + * `-` and `_` special characters allowed. */ - channel: - | ChannelMetadataObject - | { - id: string; - }; - }; - - /** - * Response with fetched page of UUID membership objects. - */ - type MembershipsResponse = PagedResponse< - MembershipsObject - >; - - /** - * Fetch Memberships request parameters. - */ - export type GetMembershipsParameters = PagedRequestParameters< - MembershipsIncludeOptions, - MembershipsSortingOptions - > & { + customMessageType?: string; /** - * Unique user identifier. + * Whether published data should be available with `Storage API` later or not. * - * **Important:** If not supplied then current user's uuid is used. + * @default `true` + */ + storeInHistory?: boolean; + /** + * Whether message should be sent as part of request POST body or not. * - * @default Current `uuid`. + * @default `false` */ - uuid?: string; + sendByPost?: boolean; /** - * Unique user identifier. + * Metadata, which should be associated with published data. * - * **Important:** If not supplied then current user's uuid is used. + * Associated metadata can be utilized by message filtering feature. + */ + meta?: Payload; + /** + * Specify duration during which data will be available with `Storage API`. * - * @default Current `uuidId`. + * - If `storeInHistory` = `true`, and `ttl` = `0`, the `message` is stored with no expiry time. + * - If `storeInHistory` = `true` and `ttl` = `X` (`X` is an Integer value), the `message` is + * stored with an expiry time of `X` hours. + * - If `storeInHistory` = `false`, the `ttl` parameter is ignored. + * - If `ttl` is not specified, then expiration of the `message` defaults back to the expiry value + * for the key. + */ + ttl?: number; + /** + * Whether published data should be replicated across all data centers or not. * - * @deprecated Use `uuid` field instead. + * @default `true` + * @deprecated */ - userId?: string; + replicate?: boolean; }; /** - * Response with requested channel memberships information. + * Service success response. */ - export type GetMembershipsResponse< - MembershipCustom extends CustomData, - ChannelCustom extends CustomData, - > = MembershipsResponse; + export type PublishResponse = { + /** + * High-precision time when published data has been received by the PubNub service. + */ + timetoken: string; + }; + } + export namespace Signal { /** - * Update Memberships request parameters. + * Request configuration parameters. */ - export type SetMembershipsParameters = PagedRequestParameters< - MembershipsIncludeOptions, - MembershipsSortingOptions - > & { + export type SignalParameters = { /** - * Unique user identifier. - * - * **Important:** If not supplied then current user's uuid is used. - * - * @default Current `uuid`. + * Channel name to publish signal to. */ - uuid?: string; + channel: string; /** - * Unique user identifier. - * - * **Important:** If not supplied then current user's uuid is used. - * - * @default Current `userId`. + * Data which should be sent to the `channel`. * - * @deprecated Use `uuid` field instead. - */ - userId?: string; - /** - * List of channels with which UUID membership should be established. + * The message may be any valid JSON type including objects, arrays, strings, and numbers. */ - channels: Array>; + message: Payload; /** - * List of channels with which UUID membership should be established. + * User-specified message type. * - * @deprecated Use `channels` field instead. + * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only + * `-` and `_` special characters allowed. */ - spaces?: Array< - | string - | (Omit, 'id'> & { - /** - * Unique Space object identifier. - */ - spaceId: string; - }) - >; + customMessageType?: string; }; /** - * Response with requested channel memberships information change. + * Service success response. */ - export type SetMembershipsResponse< - MembershipCustom extends CustomData, - ChannelCustom extends CustomData, - > = MembershipsResponse; + export type SignalResponse = { + /** + * High-precision time when published data has been received by the PubNub service. + */ + timetoken: string; + }; + } + export namespace Presence { /** - * Remove Memberships request parameters. + * Associated presence state fetch parameters. */ - export type RemoveMembershipsParameters = PagedRequestParameters< - MembershipsIncludeOptions, - MembershipsSortingOptions - > & { + export type GetPresenceStateParameters = { /** - * Unique user identifier. - * - * **Important:** If not supplied then current user's uuid is used. + * The subscriber uuid to get the current state. * - * @default Current `uuid`. + * @default `current uuid` */ uuid?: string; /** - * Unique user identifier. - * - * **Important:** If not supplied then current user's uuid is used. - * - * @default Current `userId`. + * List of channels for which state associated with {@link uuid} should be retrieved. * - * @deprecated Use {@link uuid} field instead. - */ - userId?: string; - /** - * List of channels for which membership which UUID should be removed. + * **Important:** Either {@link channels} or {@link channelGroups} should be provided; */ - channels: string[]; + channels?: string[]; /** - * List of space names for which membership which UUID should be removed. + * List of channel groups for which state associated with {@link uuid} should be retrieved. * - * @deprecated Use {@link channels} field instead. + * **Important:** Either {@link channels} or {@link channelGroups} should be provided; */ - spaceIds?: string[]; + channelGroups?: string[]; }; /** - * Response with remaining memberships. + * Associated presence state fetch response. */ - export type RemoveMembershipsResponse< - MembershipCustom extends CustomData, - ChannelCustom extends CustomData, - > = MembershipsResponse; + export type GetPresenceStateResponse = { + /** + * Channels map to state which `uuid` has associated with them. + */ + channels: Record; + }; /** - * Related UUID metadata object. - * - * Type represents UUID metadata which has been used to when added members to the channel. + * Associate presence state parameters. */ - type MembersObject = Omit< - ObjectData, - 'id' - > & { + export type SetPresenceStateParameters = { /** - * Channel's member status. + * List of channels for which state should be associated with {@link uuid}. */ - status?: string; + channels?: string[]; /** - * Channel's member type. + * List of channel groups for which state should be associated with {@link uuid}. */ - type?: string; + channelGroups?: string[]; /** - * Member of the `channel`. + * State which should be associated with `uuid` on provided list of {@link channels} and {@link channelGroups}. */ - uuid: - | UUIDMetadataObject - | { - id: string; - }; + state: Payload; }; /** - * Response with fetched page of channel member objects. - */ - type MembersResponse = PagedResponse< - MembersObject - >; - - /** - * Fetch Members request parameters. + * Associate presence state parameters using heartbeat. */ - export type GetMembersParameters = PagedRequestParameters & { + export type SetPresenceStateWithHeartbeatParameters = { /** - * Channel name. + * List of channels for which state should be associated with {@link uuid}. */ - channel: string; + channels?: string[]; /** - * Space identifier. + * State which should be associated with `uuid` on provided list of {@link channels}. + */ + state: Payload; + /** + * Whether `presence/heartbeat` REST API should be used to manage state or not. * - * @deprecated Use `channel` field instead. + * @default `false` */ - spaceId?: string; + withHeartbeat: boolean; }; /** - * Response with requested channel memberships information. + * Associate presence state response. */ - export type GetMembersResponse = MembersResponse< - MembersCustom, - UUIDCustom - >; + export type SetPresenceStateResponse = { + /** + * State which has been associated with `uuid` on provided list of channels and groups. + */ + state: Payload; + }; /** - * Update Members request parameters. + * Announce heartbeat parameters. */ - export type SetChannelMembersParameters = PagedRequestParameters< - MembersIncludeOptions, - MembersSortingOptions - > & { + export type PresenceHeartbeatParameters = { /** - * Channel name. + * How long the server will consider the client alive for presence.The value is in seconds. */ - channel: string; + heartbeat: number; /** - * Space identifier. - * - * @deprecated Use `channel` field instead. + * List of channels for which heartbeat should be announced for {@link uuid}. */ - spaceId?: string; + channels?: string[]; /** - * List of UUIDs which should be added as `channel` members. + * List of channel groups for which heartbeat should be announced for {@link uuid}. */ - uuids: Array>; + channelGroups?: string[]; /** - * List of UUIDs which should be added as `channel` members. - * - * @deprecated Use `uuids` field instead. + * State which should be associated with `uuid` on provided list of {@link channels} and {@link channelGroups}. */ - users?: Array< - | string - | (Omit, 'id'> & { - /** - * Unique User object identifier. - */ - userId: string; - }) - >; + state?: Payload; }; /** - * Response with requested channel members information change. + * Announce heartbeat response. */ - export type SetMembersResponse = MembersResponse< - MemberCustom, - UUIDCustom - >; + export type PresenceHeartbeatResponse = Record; /** - * Remove Members request parameters. + * Presence leave parameters. */ - export type RemoveMembersParameters = PagedRequestParameters & { + export type PresenceLeaveParameters = { /** - * Channel name. + * List of channels for which `uuid` should be marked as `offline`. */ - channel: string; + channels?: string[]; /** - * Space identifier. + /** + * List of channel groups for which `uuid` should be marked as `offline`. + */ + channelGroups?: string[]; + }; + + /** + * Presence leave response. + */ + export type PresenceLeaveResponse = Record; + + /** + * Channel / channel group presence fetch parameters.. + */ + export type HereNowParameters = { + /** + * List of channels for which presence should be retrieved. + */ + channels?: string[]; + /** + * List of channel groups for which presence should be retrieved. + */ + channelGroups?: string[]; + /** + * Whether `uuid` information should be included in response or not. * - * @deprecated Use {@link channel} field instead. + * **Note:** Only occupancy information will be returned if both {@link includeUUIDs} and {@link includeState} is + * set to `false`. + * + * @default `true` */ - spaceId?: string; + includeUUIDs?: boolean; /** - * List of UUIDs which should be removed from the `channel` members list. - * removed. + * Whether state associated with `uuid` should be included in response or not. + * + * @default `false`. */ - uuids: string[]; + includeState?: boolean; /** - * List of user identifiers which should be removed from the `channel` members list. - * removed. + * Limit the number of results returned. * - * @deprecated Use {@link uuids} field instead. + * @default `1000`. */ - userIds?: string[]; + limit?: number; + /** + * Zero-based starting index for pagination. + */ + offset?: number; + /** + * Additional query parameters. + */ + queryParameters?: Record; }; /** - * Response with remaining members. - */ - export type RemoveMembersResponse = MembersResponse< - MemberCustom, - UUIDCustom - >; - - /** - * Related User metadata object. - * - * Type represents User metadata which has been used to when added members to the Space. + * `uuid` where now response. */ - type UserMembersObject = Omit< - ObjectData, - 'id' - > & { - user: - | UUIDMetadataObject - | { - id: string; - }; + export type HereNowResponse = { + /** + * Total number of channels for which presence information received. + */ + totalChannels: number; + /** + * Total occupancy for all retrieved channels. + */ + totalOccupancy: number; + /** + * List of channels to which `uuid` currently subscribed. + */ + channels: { + [p: string]: { + /** + * List of received channel subscribers. + * + * **Note:** Field is missing if `uuid` and `state` not included. + */ + occupants: { + uuid: string; + state?: Payload | null; + }[]; + /** + * Name of channel for which presence information retrieved. + */ + name: string; + /** + * Total number of active subscribers in single channel. + */ + occupancy: number; + }; + }; }; /** - * Response with fetched page of Space member objects. + * `uuid` where now parameters. */ - export type UserMembersResponse = PagedResponse< - UserMembersObject - >; - - type SpaceMembershipObject = Omit< - ObjectData, - 'id' - > & { - space: - | ChannelMetadataObject - | { - id: string; - }; + export type WhereNowParameters = { + /** + * The subscriber uuid to get the current state. + * + * @default `current uuid` + */ + uuid?: string; }; /** - * Response with fetched page of User membership objects. + * `uuid` where now response. */ - export type SpaceMembershipsResponse< - MembershipCustom extends CustomData, - ChannelCustom extends CustomData, - > = PagedResponse>; + export type WhereNowResponse = { + /** + * Channels map to state which `uuid` has associated with them. + */ + channels: string[]; + }; } - export namespace ChannelGroups { + export namespace History { /** - * Add or remove Channels to the channel group request parameters. + * Get history request parameters. */ - export type ManageChannelGroupChannelsParameters = { + export type GetHistoryParameters = { /** - * Name of the channel group for which channels list should be changed. + * Channel to return history messages from. */ - channelGroup: string; + channel: string; /** - * List of channels to be added or removed. + * Specifies the number of historical messages to return. + * + * **Note:** Maximum `100` messages can be returned in single response. + * + * @default `100` */ - channels: string[]; + count?: number; + /** + * Whether message `meta` information should be fetched or not. + * + * @default `false` + */ + includeMeta?: boolean; + /** + * Timetoken delimiting the `start` of `time` slice (exclusive) to pull messages from. + */ + start?: string; + /** + * Timetoken delimiting the `end` of `time` slice (inclusive) to pull messages from. + */ + end?: string; + /** + * Whether timeline should traverse in reverse starting with the oldest message first or not. + * + * If both `start` and `end` arguments are provided, `reverse` is ignored and messages are + * returned starting with the newest message. + */ + reverse?: boolean; + /** + * Whether message timetokens should be stringified or not. + * + * @default `false` + */ + stringifiedTimeToken?: boolean; }; /** - * Channel group channels list manage response. - */ - export type ManageChannelGroupChannelsResponse = Record; - - /** - * Response with result of the all channel groups list. + * Get history response. */ - export type ListAllChannelGroupsResponse = { + export type GetHistoryResponse = { /** - * All channel groups with channels. + * List of previously published messages. */ - groups: string[]; + messages: { + /** + * Message payload (decrypted). + */ + entry: Payload; + /** + * When message has been received by PubNub service. + */ + timetoken: string | number; + /** + * Additional data which has been published along with message to be used with real-time + * events filter expression. + */ + meta?: Payload; + /** + * Message decryption error (if attempt has been done). + */ + error?: string; + }[]; + /** + * Received messages timeline start. + */ + startTimeToken: string | number; + /** + * Received messages timeline end. + */ + endTimeToken: string | number; }; /** - * List Channel Group Channels request parameters. + * PubNub-defined message type. + * + * Types of messages which can be retrieved with fetch messages REST API. */ - export type ListChannelGroupChannelsParameters = { + export enum PubNubMessageType { /** - * Name of the channel group for which list of channels should be retrieved. + * Regular message. */ - channelGroup: string; - }; + Message = -1, + /** + * File message. + */ + Files = 4, + } /** - * Response with result of the list channel group channels. + * Per-message actions information. */ - export type ListChannelGroupChannelsResponse = { + export type Actions = { /** - * List of the channels registered withing specified channel group. + * Message action type. */ - channels: string[]; + [t: string]: { + /** + * Message action value. + */ + [v: string]: { + /** + * Unique identifier of the user which reacted on message. + */ + uuid: string; + /** + * High-precision PubNub timetoken with time when {@link uuid} reacted on message. + */ + actionTimetoken: string; + }[]; + }; }; /** - * Delete Channel Group request parameters. + * Additional message actions fetch information. */ - export type DeleteChannelGroupParameters = { + export type MoreActions = { /** - * Name of the channel group which should be removed. + * Prepared fetch messages with actions REST API URL. */ - channelGroup: string; + url: string; + /** + * Next page time offset. + */ + start: string; + /** + * Number of messages to retrieve with next page. + */ + max: number; }; /** - * Delete channel group response. - */ - export type DeleteChannelGroupResponse = Record; - } - - export namespace Publish { - /** - * Request configuration parameters. + * Common content of the fetched message. */ - export type PublishParameters = { + type BaseFetchedMessage = { /** - * Channel name to publish messages to. + * Name of channel for which message has been retrieved. */ channel: string; /** - * Data which should be sent to the `channel`. - * - * The message may be any valid JSON type including objects, arrays, strings, and numbers. + * When message has been received by PubNub service. */ - message: Payload; + timetoken: string | number; /** - * User-specified message type. - * - * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only - * `-` and `_` special characters allowed. + * Message publisher unique identifier. */ - customMessageType?: string; + uuid?: string; /** - * Whether published data should be available with `Storage API` later or not. - * - * @default `true` + * Additional data which has been published along with message to be used with real-time + * events filter expression. */ - storeInHistory?: boolean; + meta?: Payload; /** - * Whether message should be sent as part of request POST body or not. - * - * @default `false` + * Message decryption error (if attempt has been done). */ - sendByPost?: boolean; + error?: string; + }; + + /** + * Regular message published to the channel. + */ + export type RegularMessage = BaseFetchedMessage & { /** - * Metadata, which should be associated with published data. - * - * Associated metadata can be utilized by message filtering feature. + * Message payload (decrypted). */ - meta?: Payload; + message: Payload; /** - * Specify duration during which data will be available with `Storage API`. - * - * - If `storeInHistory` = `true`, and `ttl` = `0`, the `message` is stored with no expiry time. - * - If `storeInHistory` = `true` and `ttl` = `X` (`X` is an Integer value), the `message` is - * stored with an expiry time of `X` hours. - * - If `storeInHistory` = `false`, the `ttl` parameter is ignored. - * - If `ttl` is not specified, then expiration of the `message` defaults back to the expiry value - * for the key. + * PubNub-defined message type. + */ + messageType?: PubNubMessageType.Message; + /** + * User-provided message type. + */ + customMessageType?: string; + }; + + /** + * File message published to the channel. + */ + export type FileMessage = BaseFetchedMessage & { + /** + * Message payload (decrypted). + */ + message: { + /** + * File annotation message. + */ + message?: Payload; + /** + * File information. + */ + file: { + /** + * Unique file identifier. + */ + id: string; + /** + * Name with which file has been stored. + */ + name: string; + /** + * File's content mime-type. + */ + 'mime-type': string; + /** + * Stored file size. + */ + size: number; + /** + * Pre-computed file download Url. + */ + url: string; + }; + }; + /** + * PubNub-defined message type. */ - ttl?: number; + messageType?: PubNubMessageType.Files; /** - * Whether published data should be replicated across all data centers or not. - * - * @default `true` - * @deprecated + * User-provided message type. */ - replicate?: boolean; + customMessageType?: string; }; /** - * Service success response. + * Fetched message entry in channel messages list. */ - export type PublishResponse = { - /** - * High-precision time when published data has been received by the PubNub service. - */ - timetoken: string; - }; - } + export type FetchedMessage = RegularMessage | FileMessage; - export namespace Signal { /** - * Request configuration parameters. + * Fetched with actions message entry in channel messages list. */ - export type SignalParameters = { - /** - * Channel name to publish signal to. - */ - channel: string; + export type FetchedMessageWithActions = FetchedMessage & { /** - * Data which should be sent to the `channel`. - * - * The message may be any valid JSON type including objects, arrays, strings, and numbers. + * List of message reactions. */ - message: Payload; + actions?: Actions; /** - * User-specified message type. + * List of message reactions. * - * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only - * `-` and `_` special characters allowed. + * @deprecated Use {@link actions} field instead. */ - customMessageType?: string; + data?: Actions; }; /** - * Service success response. + * Fetch messages request parameters. */ - export type SignalResponse = { + export type FetchMessagesParameters = { /** - * High-precision time when published data has been received by the PubNub service. + * Specifies channels to return history messages from. + * + * **Note:** Maximum of `500` channels are allowed. */ - timetoken: string; - }; - } - - export namespace Presence { - /** - * Associated presence state fetch parameters. - */ - export type GetPresenceStateParameters = { + channels: string[]; /** - * The subscriber uuid to get the current state. + * Specifies the number of historical messages to return per channel. * - * @default `current uuid` + * **Note:** Default is `100` per single channel and `25` per multiple channels or per + * single channel if {@link includeMessageActions} is used. + * + * @default `100` or `25` */ - uuid?: string; + count?: number; /** - * List of channels for which state associated with {@link uuid} should be retrieved. + * Include messages' custom type flag. * - * **Important:** Either {@link channels} or {@link channelGroups} should be provided; + * Message / signal and file messages may contain user-provided type. */ - channels?: string[]; + includeCustomMessageType?: boolean; /** - * List of channel groups for which state associated with {@link uuid} should be retrieved. + * Whether message type should be returned with each history message or not. * - * **Important:** Either {@link channels} or {@link channelGroups} should be provided; + * @default `true` */ - channelGroups?: string[]; - }; - - /** - * Associated presence state fetch response. - */ - export type GetPresenceStateResponse = { + includeMessageType?: boolean; /** - * Channels map to state which `uuid` has associated with them. + * Whether publisher `uuid` should be returned with each history message or not. + * + * @default `true` */ - channels: Record; - }; - - /** - * Associate presence state parameters. - */ - export type SetPresenceStateParameters = { + includeUUID?: boolean; /** - * List of channels for which state should be associated with {@link uuid}. + * Whether publisher `uuid` should be returned with each history message or not. + * + * @deprecated Use {@link includeUUID} property instead. */ - channels?: string[]; + includeUuid?: boolean; /** - * List of channel groups for which state should be associated with {@link uuid}. + * Whether message `meta` information should be fetched or not. + * + * @default `false` */ - channelGroups?: string[]; + includeMeta?: boolean; /** - * State which should be associated with `uuid` on provided list of {@link channels} and {@link channelGroups}. + * Whether message-added message actions should be fetched or not. + * + * If used, the limit of messages retrieved will be `25` per single channel. + * + * Each message can have a maximum of `25000` actions attached to it. Consider the example of + * querying for 10 messages. The first five messages have 5000 actions attached to each of + * them. The API will return the first 5 messages and all their 25000 actions. The response + * will also include a `more` link to get the remaining 5 messages. + * + * **Important:** Truncation will happen if the number of actions on the messages returned + * is > 25000. + * + * @default `false` + * + * @throws Exception if API is called with more than one channel. */ - state: Payload; - }; - - /** - * Associate presence state parameters using heartbeat. - */ - export type SetPresenceStateWithHeartbeatParameters = { + includeMessageActions?: boolean; /** - * List of channels for which state should be associated with {@link uuid}. + * Timetoken delimiting the `start` of `time` slice (exclusive) to pull messages from. */ - channels?: string[]; + start?: string; /** - * State which should be associated with `uuid` on provided list of {@link channels}. + * Timetoken delimiting the `end` of `time` slice (inclusive) to pull messages from. */ - state: Payload; + end?: string; /** - * Whether `presence/heartbeat` REST API should be used to manage state or not. + * Whether message timetokens should be stringified or not. * * @default `false` */ - withHeartbeat: boolean; + stringifiedTimeToken?: boolean; }; /** - * Associate presence state response. + * Fetch messages response. */ - export type SetPresenceStateResponse = { + export type FetchMessagesForChannelsResponse = { /** - * State which has been associated with `uuid` on provided list of channels and groups. + * List of previously published messages per requested channel. */ - state: Payload; + channels: { + [p: string]: FetchedMessage[]; + }; }; /** - * Announce heartbeat parameters. + * Fetch messages with reactions response. */ - export type PresenceHeartbeatParameters = { + export type FetchMessagesWithActionsResponse = { + channels: { + [p: string]: FetchedMessageWithActions[]; + }; /** - * How long the server will consider the client alive for presence.The value is in seconds. + * Additional message actions fetch information. */ - heartbeat: number; + more: MoreActions; + }; + + /** + * Fetch messages response. + */ + export type FetchMessagesResponse = FetchMessagesForChannelsResponse | FetchMessagesWithActionsResponse; + + /** + * Message count request parameters. + */ + export type MessageCountParameters = { /** - * List of channels for which heartbeat should be announced for {@link uuid}. + * The channels to fetch the message count. */ - channels?: string[]; + channels: string[]; /** - * List of channel groups for which heartbeat should be announced for {@link uuid}. + * List of timetokens, in order of the {@link channels} list. + * + * Specify a single timetoken to apply it to all channels. Otherwise, the list of timetokens + * must be the same length as the list of {@link channels}, or the function returns an error + * flag. */ - channelGroups?: string[]; + channelTimetokens?: string[]; /** - * State which should be associated with `uuid` on provided list of {@link channels} and {@link channelGroups}. + * High-precision PubNub timetoken starting from which number of messages should be counted. + * + * Same timetoken will be used to count messages for each passed {@link channels}. + * + * @deprecated Use {@link channelTimetokens} field instead. */ - state?: Payload; + timetoken?: string; }; /** - * Announce heartbeat response. + * Message count response. */ - export type PresenceHeartbeatResponse = Record; + export type MessageCountResponse = { + /** + * Map of channel names to the number of counted messages. + */ + channels: Record; + }; /** - * Presence leave parameters. + * Delete messages from channel parameters. */ - export type PresenceLeaveParameters = { + export type DeleteMessagesParameters = { /** - * List of channels for which `uuid` should be marked as `offline`. + * Specifies channel messages to be deleted from history. */ - channels?: string[]; + channel: string; /** - /** - * List of channel groups for which `uuid` should be marked as `offline`. + * Timetoken delimiting the start of time slice (exclusive) to delete messages from. */ - channelGroups?: string[]; + start?: string; + /** + * Timetoken delimiting the end of time slice (inclusive) to delete messages from. + */ + end?: string; }; /** - * Presence leave response. + * Delete messages from channel response. */ - export type PresenceLeaveResponse = Record; + export type DeleteMessagesResponse = Record; + } + export namespace MessageAction { /** - * Channel / channel group presence fetch parameters.. + * Message reaction object type. */ - export type HereNowParameters = { - /** - * List of channels for which presence should be retrieved. - */ - channels?: string[]; - /** - * List of channel groups for which presence should be retrieved. - */ - channelGroups?: string[]; - /** - * Whether `uuid` information should be included in response or not. - * - * **Note:** Only occupancy information will be returned if both {@link includeUUIDs} and {@link includeState} is - * set to `false`. - * - * @default `true` + export type MessageAction = { + /** + * What feature this message action represents. */ - includeUUIDs?: boolean; + type: string; /** - * Whether state associated with `uuid` should be included in response or not. - * - * @default `false`. + * Value which should be stored along with message action. */ - includeState?: boolean; + value: string; /** - * Limit the number of results returned. - * - * @default `1000`. + * Unique identifier of the user which added message action. */ - limit?: number; + uuid: string; /** - * Zero-based starting index for pagination. + * Timetoken of when message reaction has been added. + * + * **Note:** This token required when it will be required to remove reaction. */ - offset?: number; + actionTimetoken: string; /** - * Additional query parameters. + * Timetoken of message to which `action` has been added. */ - queryParameters?: Record; + messageTimetoken: string; }; /** - * `uuid` where now response. + * More message actions fetch information. */ - export type HereNowResponse = { + export type MoreMessageActions = { /** - * Total number of channels for which presence information received. + * Prepared REST API url to fetch next page with message actions. */ - totalChannels: number; + url: string; /** - * Total occupancy for all retrieved channels. + * Message action timetoken denoting the start of the range requested with next page. + * + * **Note:** Return values will be less than {@link start}. */ - totalOccupancy: number; + start: string; /** - * List of channels to which `uuid` currently subscribed. + * Message action timetoken denoting the end of the range requested with next page. + * + * **Note:** Return values will be greater than or equal to {@link end}. */ - channels: { - [p: string]: { - /** - * List of received channel subscribers. - * - * **Note:** Field is missing if `uuid` and `state` not included. - */ - occupants: { - uuid: string; - state?: Payload | null; - }[]; - /** - * Name of channel for which presence information retrieved. - */ - name: string; - /** - * Total number of active subscribers in single channel. - */ - occupancy: number; - }; - }; + end: string; + /** + * Number of message actions to return in next response. + */ + limit: number; }; /** - * `uuid` where now parameters. + * Add Message Action request parameters. */ - export type WhereNowParameters = { + export type AddMessageActionParameters = { /** - * The subscriber uuid to get the current state. - * - * @default `current uuid` + * Name of channel which stores the message for which {@link action} should be added. */ - uuid?: string; + channel: string; + /** + * Timetoken of message for which {@link action} should be added. + */ + messageTimetoken: string; + /** + * Message `action` information. + */ + action: { + /** + * What feature this message action represents. + */ + type: string; + /** + * Value which should be stored along with message action. + */ + value: string; + }; }; /** - * `uuid` where now response. + * Response with added message action object. */ - export type WhereNowResponse = { - /** - * Channels map to state which `uuid` has associated with them. - */ - channels: string[]; + export type AddMessageActionResponse = { + data: MessageAction; }; - } - export namespace History { /** - * Get history request parameters. + * Get Message Actions request parameters. */ - export type GetHistoryParameters = { + export type GetMessageActionsParameters = { /** - * Channel to return history messages from. + * Name of channel from which list of messages `actions` should be retrieved. */ channel: string; /** - * Specifies the number of historical messages to return. - * - * **Note:** Maximum `100` messages can be returned in single response. - * - * @default `100` - */ - count?: number; - /** - * Whether message `meta` information should be fetched or not. + * Message action timetoken denoting the start of the range requested. * - * @default `false` - */ - includeMeta?: boolean; - /** - * Timetoken delimiting the `start` of `time` slice (exclusive) to pull messages from. + * **Note:** Return values will be less than {@link start}. */ start?: string; /** - * Timetoken delimiting the `end` of `time` slice (inclusive) to pull messages from. - */ - end?: string; - /** - * Whether timeline should traverse in reverse starting with the oldest message first or not. + * Message action timetoken denoting the end of the range requested. * - * If both `start` and `end` arguments are provided, `reverse` is ignored and messages are - * returned starting with the newest message. + * **Note:** Return values will be greater than or equal to {@link end}. */ - reverse?: boolean; + end?: string; /** - * Whether message timetokens should be stringified or not. - * - * @default `false` + * Number of message actions to return in response. */ - stringifiedTimeToken?: boolean; + limit?: number; }; /** - * Get history response. + * Response with message actions in specific `channel`. */ - export type GetHistoryResponse = { + export type GetMessageActionsResponse = { /** - * List of previously published messages. + * Retrieved list of message actions. */ - messages: { - /** - * Message payload (decrypted). - */ - entry: Payload; - /** - * When message has been received by PubNub service. - */ - timetoken: string | number; - /** - * Additional data which has been published along with message to be used with real-time - * events filter expression. - */ - meta?: Payload; - /** - * Message decryption error (if attempt has been done). - */ - error?: string; - }[]; + data: MessageAction[]; /** - * Received messages timeline start. + * Received message actions time frame start. */ - startTimeToken: string | number; + start: string | null; /** - * Received messages timeline end. + * Received message actions time frame end. */ - endTimeToken: string | number; + end: string | null; + /** + * More message actions fetch information. + */ + more?: MoreMessageActions; }; /** - * PubNub-defined message type. - * - * Types of messages which can be retrieved with fetch messages REST API. + * Remove Message Action request parameters. */ - export enum PubNubMessageType { + export type RemoveMessageActionParameters = { /** - * Regular message. + * Name of channel which store message for which `action` should be removed. */ - Message = -1, + channel: string; /** - * File message. + * Timetoken of message for which `action` should be removed. */ - Files = 4, - } - - /** - * Per-message actions information. - */ - export type Actions = { + messageTimetoken: string; /** - * Message action type. + * Action addition timetoken. */ - [t: string]: { - /** - * Message action value. - */ - [v: string]: { - /** - * Unique identifier of the user which reacted on message. - */ - uuid: string; - /** - * High-precision PubNub timetoken with time when {@link uuid} reacted on message. - */ - actionTimetoken: string; - }[]; - }; + actionTimetoken: string; }; /** - * Additional message actions fetch information. + * Response with message remove result. */ - export type MoreActions = { - /** - * Prepared fetch messages with actions REST API URL. - */ - url: string; - /** - * Next page time offset. - */ - start: string; - /** - * Number of messages to retrieve with next page. - */ - max: number; + export type RemoveMessageActionResponse = { + data: Record; }; + } + export namespace FileSharing { /** - * Common content of the fetched message. + * Shared file object. */ - type BaseFetchedMessage = { - /** - * Name of channel for which message has been retrieved. - */ - channel: string; + export type SharedFile = { /** - * When message has been received by PubNub service. + * Name with which file has been stored. */ - timetoken: string | number; + name: string; /** - * Message publisher unique identifier. + * Unique service-assigned file identifier. */ - uuid?: string; + id: string; /** - * Additional data which has been published along with message to be used with real-time - * events filter expression. + * Shared file size. */ - meta?: Payload; + size: number; /** - * Message decryption error (if attempt has been done). + * ISO 8601 time string when file has been shared. */ - error?: string; + created: string; }; /** - * Regular message published to the channel. + * List Files request parameters. */ - export type RegularMessage = BaseFetchedMessage & { + export type ListFilesParameters = { /** - * Message payload (decrypted). + * Name of channel for which list of files should be requested. */ - message: Payload; + channel: string; /** - * PubNub-defined message type. + * How many entries return with single response. */ - messageType?: PubNubMessageType.Message; + limit?: number; /** - * User-provided message type. + * Next files list page token. */ - customMessageType?: string; + next?: string; }; /** - * File message published to the channel. + * List Files request response. */ - export type FileMessage = BaseFetchedMessage & { + export type ListFilesResponse = { /** - * Message payload (decrypted). + * Files list fetch result status code. */ - message: { - /** - * File annotation message. - */ - message?: Payload; - /** - * File information. - */ - file: { - /** - * Unique file identifier. - */ - id: string; - /** - * Name with which file has been stored. - */ - name: string; - /** - * File's content mime-type. - */ - 'mime-type': string; - /** - * Stored file size. - */ - size: number; - /** - * Pre-computed file download Url. - */ - url: string; - }; - }; + status: number; /** - * PubNub-defined message type. + * List of fetched file objects. */ - messageType?: PubNubMessageType.Files; + data: SharedFile[]; /** - * User-provided message type. + * Next files list page token. */ - customMessageType?: string; + next: string; + /** + * Number of retrieved files. + */ + count: number; }; /** - * Fetched message entry in channel messages list. - */ - export type FetchedMessage = RegularMessage | FileMessage; - - /** - * Fetched with actions message entry in channel messages list. + * Send File request parameters. */ - export type FetchedMessageWithActions = FetchedMessage & { + export type SendFileParameters = Omit & { /** - * List of message reactions. + * Channel to send the file to. */ - actions?: Actions; + channel: string; /** - * List of message reactions. - * - * @deprecated Use {@link actions} field instead. + * File to send. */ - data?: Actions; + file: FileParameters; }; /** - * Fetch messages request parameters. + * Send File request response. */ - export type FetchMessagesParameters = { - /** - * Specifies channels to return history messages from. - * - * **Note:** Maximum of `500` channels are allowed. - */ - channels: string[]; - /** - * Specifies the number of historical messages to return per channel. - * - * **Note:** Default is `100` per single channel and `25` per multiple channels or per - * single channel if {@link includeMessageActions} is used. - * - * @default `100` or `25` - */ - count?: number; + export type SendFileResponse = PublishFileMessageResponse & { /** - * Include messages' custom type flag. - * - * Message / signal and file messages may contain user-provided type. + * Send file request processing status code. */ - includeCustomMessageType?: boolean; + status: number; /** - * Whether message type should be returned with each history message or not. + * Actual file name under which file has been stored. * - * @default `true` - */ - includeMessageType?: boolean; - /** - * Whether publisher `uuid` should be returned with each history message or not. + * File name and unique {@link id} can be used to download file from the channel later. * - * @default `true` + * **Important:** Actual file name may be different from the one which has been used during file + * upload. */ - includeUUID?: boolean; + name: string; /** - * Whether publisher `uuid` should be returned with each history message or not. + * Unique file identifier. * - * @deprecated Use {@link includeUUID} property instead. + * Unique file identifier, and it's {@link name} can be used to download file from the channel + * later. */ - includeUuid?: boolean; + id: string; + }; + + /** + * Upload File request parameters. + */ + export type UploadFileParameters = { /** - * Whether message `meta` information should be fetched or not. + * Unique file identifier. * - * @default `false` + * Unique file identifier, and it's {@link fileName} can be used to download file from the channel + * later. */ - includeMeta?: boolean; + fileId: string; /** - * Whether message-added message actions should be fetched or not. - * - * If used, the limit of messages retrieved will be `25` per single channel. - * - * Each message can have a maximum of `25000` actions attached to it. Consider the example of - * querying for 10 messages. The first five messages have 5000 actions attached to each of - * them. The API will return the first 5 messages and all their 25000 actions. The response - * will also include a `more` link to get the remaining 5 messages. - * - * **Important:** Truncation will happen if the number of actions on the messages returned - * is > 25000. + * Actual file name under which file has been stored. * - * @default `false` + * File name and unique {@link fileId} can be used to download file from the channel later. * - * @throws Exception if API is called with more than one channel. + * **Note:** Actual file name may be different from the one which has been used during file + * upload. */ - includeMessageActions?: boolean; + fileName: string; /** - * Timetoken delimiting the `start` of `time` slice (exclusive) to pull messages from. + * File which should be uploaded. */ - start?: string; + file: PubNubFileInterface; /** - * Timetoken delimiting the `end` of `time` slice (inclusive) to pull messages from. + * Pre-signed file upload Url. */ - end?: string; + uploadUrl: string; /** - * Whether message timetokens should be stringified or not. + * An array of form fields to be used in the pre-signed POST request. * - * @default `false` + * **Important:** Form data fields should be passed in exact same order as received from + * the PubNub service. */ - stringifiedTimeToken?: boolean; + formFields: { + /** + * Form data field name. + */ + name: string; + /** + * Form data field value. + */ + value: string; + }[]; }; /** - * Fetch messages response. + * Upload File request response. */ - export type FetchMessagesForChannelsResponse = { + export type UploadFileResponse = { /** - * List of previously published messages per requested channel. + * Upload File request processing status code. */ - channels: { - [p: string]: FetchedMessage[]; - }; + status: number; + /** + * Service processing result response. + */ + message: Payload; }; /** - * Fetch messages with reactions response. + * Generate File Upload URL request parameters. */ - export type FetchMessagesWithActionsResponse = { - channels: { - [p: string]: FetchedMessageWithActions[]; - }; + export type GenerateFileUploadUrlParameters = { /** - * Additional message actions fetch information. + * Name of channel to which file should be uploaded. */ - more: MoreActions; + channel: string; + /** + * Actual name of the file which should be uploaded. + */ + name: string; }; /** - * Fetch messages response. - */ - export type FetchMessagesResponse = FetchMessagesForChannelsResponse | FetchMessagesWithActionsResponse; - - /** - * Message count request parameters. + * Generation File Upload URL request response. */ - export type MessageCountParameters = { + export type GenerateFileUploadUrlResponse = { /** - * The channels to fetch the message count. + * Unique file identifier. + * + * Unique file identifier, and it's {@link name} can be used to download file from the channel + * later. */ - channels: string[]; + id: string; /** - * List of timetokens, in order of the {@link channels} list. + * Actual file name under which file has been stored. * - * Specify a single timetoken to apply it to all channels. Otherwise, the list of timetokens - * must be the same length as the list of {@link channels}, or the function returns an error - * flag. + * File name and unique {@link id} can be used to download file from the channel later. + * + * **Note:** Actual file name may be different from the one which has been used during file + * upload. + */ + name: string; + /** + * Pre-signed URL for file upload. */ - channelTimetokens?: string[]; + url: string; /** - * High-precision PubNub timetoken starting from which number of messages should be counted. - * - * Same timetoken will be used to count messages for each passed {@link channels}. + * An array of form fields to be used in the pre-signed POST request. * - * @deprecated Use {@link channelTimetokens} field instead. + * **Important:** Form data fields should be passed in exact same order as received from + * the PubNub service. */ - timetoken?: string; + formFields: { + /** + * Form data field name. + */ + name: string; + /** + * Form data field value. + */ + value: string; + }[]; }; /** - * Message count response. + * Publish File Message request parameters. */ - export type MessageCountResponse = { + export type PublishFileMessageParameters = { /** - * Map of channel names to the number of counted messages. + * Name of channel to which file has been sent. */ - channels: Record; - }; - - /** - * Delete messages from channel parameters. - */ - export type DeleteMessagesParameters = { + channel: string; /** - * Specifies channel messages to be deleted from history. + * File annotation message. */ - channel: string; + message?: Payload; /** - * Timetoken delimiting the start of time slice (exclusive) to delete messages from. + * User-specified message type. + * + * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only + * `-` and `_` special characters allowed. */ - start?: string; + customMessageType?: string; /** - * Timetoken delimiting the end of time slice (inclusive) to delete messages from. + * Custom file and message encryption key. + * + * @deprecated Use {@link Configuration#cryptoModule|cryptoModule} configured for PubNub client + * instance or encrypt file prior {@link PubNub#sendFile|sendFile} method call. */ - end?: string; - }; - - /** - * Delete messages from channel response. - */ - export type DeleteMessagesResponse = Record; - } - - export namespace MessageAction { - /** - * Message reaction object type. - */ - export type MessageAction = { + cipherKey?: string; /** - * What feature this message action represents. + * Unique file identifier. + * + * Unique file identifier, and it's {@link fileName} can be used to download file from the channel + * later. */ - type: string; + fileId: string; /** - * Value which should be stored along with message action. + * Actual file name under which file has been stored. + * + * File name and unique {@link fileId} can be used to download file from the channel later. + * + * **Note:** Actual file name may be different from the one which has been used during file + * upload. */ - value: string; + fileName: string; /** - * Unique identifier of the user which added message action. + * Whether published file messages should be stored in the channel's history. + * + * **Note:** If `storeInHistory` not specified, then the history configuration on the key is + * used. + * + * @default `true` */ - uuid: string; + storeInHistory?: boolean; /** - * Timetoken of when message reaction has been added. + * How long the message should be stored in the channel's history. * - * **Note:** This token required when it will be required to remove reaction. + * **Note:** If not specified, defaults to the key set's retention value. + * + * @default `0` */ - actionTimetoken: string; + ttl?: number; /** - * Timetoken of message to which `action` has been added. + * Metadata, which should be associated with published file. + * + * Associated metadata can be utilized by message filtering feature. */ - messageTimetoken: string; + meta?: Payload; }; /** - * More message actions fetch information. + * Publish File Message request response. */ - export type MoreMessageActions = { - /** - * Prepared REST API url to fetch next page with message actions. - */ - url: string; + export type PublishFileMessageResponse = { /** - * Message action timetoken denoting the start of the range requested with next page. - * - * **Note:** Return values will be less than {@link start}. + * High-precision time when published file message has been received by the PubNub service. */ - start: string; + timetoken: string; + }; + + /** + * Download File request parameters. + */ + export type DownloadFileParameters = FileUrlParameters & { /** - * Message action timetoken denoting the end of the range requested with next page. + * Custom file and message encryption key. * - * **Note:** Return values will be greater than or equal to {@link end}. - */ - end: string; - /** - * Number of message actions to return in next response. + * @deprecated Use {@link Configuration#cryptoModule|cryptoModule} configured for PubNub client + * instance or encrypt file prior {@link PubNub#sendFile|sendFile} method call. */ - limit: number; + cipherKey?: string; }; /** - * Add Message Action request parameters. + * Generate File download Url request parameters. */ - export type AddMessageActionParameters = { + export type FileUrlParameters = { /** - * Name of channel which stores the message for which {@link action} should be added. + * Name of channel where file has been sent. */ channel: string; /** - * Timetoken of message for which {@link action} should be added. + * Unique file identifier. + * + * Unique file identifier, and it's {@link name} can be used to download file from the channel + * later. */ - messageTimetoken: string; + id: string; /** - * Message `action` information. + * Actual file name under which file has been stored. + * + * File name and unique {@link id} can be used to download file from the channel later. + * + * **Important:** Actual file name may be different from the one which has been used during file + * upload. */ - action: { - /** - * What feature this message action represents. - */ - type: string; - /** - * Value which should be stored along with message action. - */ - value: string; - }; + name: string; }; /** - * Response with added message action object. + * Generate File Download Url response. */ - export type AddMessageActionResponse = { - data: MessageAction; - }; + export type FileUrlResponse = string; /** - * Get Message Actions request parameters. + * Delete File request parameters. */ - export type GetMessageActionsParameters = { + export type DeleteFileParameters = { /** - * Name of channel from which list of messages `actions` should be retrieved. + * Name of channel where file has been sent. */ channel: string; /** - * Message action timetoken denoting the start of the range requested. + * Unique file identifier. * - * **Note:** Return values will be less than {@link start}. + * Unique file identifier, and it's {@link name} can be used to download file from the channel + * later. */ - start?: string; + id: string; /** - * Message action timetoken denoting the end of the range requested. + * Actual file name under which file has been stored. * - * **Note:** Return values will be greater than or equal to {@link end}. + * File name and unique {@link id} can be used to download file from the channel later. + * + * **Important:** Actual file name may be different from the one which has been used during file + * upload. */ - end?: string; + name: string; + }; + + /** + * Delete File request response. + */ + export type DeleteFileResponse = { /** - * Number of message actions to return in response. + * Delete File request processing status code. */ - limit?: number; + status: number; }; + } + export namespace PAM { /** - * Response with message actions in specific `channel`. + * Metadata which will be associated with access token. */ - export type GetMessageActionsResponse = { + export type Metadata = Record; + + /** + * Channel-specific token permissions. + */ + export type ChannelTokenPermissions = { /** - * Retrieved list of message actions. + * Whether `read` operations are permitted for corresponding level or not. */ - data: MessageAction[]; + read?: boolean; /** - * Received message actions time frame start. + * Whether `write` operations are permitted for corresponding level or not. */ - start: string | null; + write?: boolean; /** - * Received message actions time frame end. + * Whether `get` operations are permitted for corresponding level or not. */ - end: string | null; + get?: boolean; /** - * More message actions fetch information. + * Whether `manage` operations are permitted for corresponding level or not. */ - more?: MoreMessageActions; - }; - - /** - * Remove Message Action request parameters. - */ - export type RemoveMessageActionParameters = { + manage?: boolean; /** - * Name of channel which store message for which `action` should be removed. + * Whether `update` operations are permitted for corresponding level or not. */ - channel: string; + update?: boolean; /** - * Timetoken of message for which `action` should be removed. + * Whether `join` operations are permitted for corresponding level or not. */ - messageTimetoken: string; + join?: boolean; /** - * Action addition timetoken. + * Whether `delete` operations are permitted for corresponding level or not. */ - actionTimetoken: string; + delete?: boolean; }; /** - * Response with message remove result. + * Space-specific token permissions. */ - export type RemoveMessageActionResponse = { - data: Record; - }; - } + type SpaceTokenPermissions = ChannelTokenPermissions; - export namespace FileSharing { /** - * Shared file object. + * Channel group-specific token permissions. */ - export type SharedFile = { - /** - * Name with which file has been stored. - */ - name: string; - /** - * Unique service-assigned file identifier. - */ - id: string; + export type ChannelGroupTokenPermissions = { /** - * Shared file size. + * Whether `read` operations are permitted for corresponding level or not. */ - size: number; + read?: boolean; /** - * ISO 8601 time string when file has been shared. + * Whether `manage` operations are permitted for corresponding level or not. */ - created: string; + manage?: boolean; }; /** - * List Files request parameters. + * Uuid-specific token permissions. */ - export type ListFilesParameters = { + export type UuidTokenPermissions = { /** - * Name of channel for which list of files should be requested. + * Whether `get` operations are permitted for corresponding level or not. */ - channel: string; + get?: boolean; /** - * How many entries return with single response. + * Whether `update` operations are permitted for corresponding level or not. */ - limit?: number; + update?: boolean; /** - * Next files list page token. + * Whether `delete` operations are permitted for corresponding level or not. */ - next?: string; + delete?: boolean; }; /** - * List Files request response. + * User-specific token permissions. */ - export type ListFilesResponse = { + type UserTokenPermissions = UuidTokenPermissions; + + /** + * DataSync entity-level token permissions. + * + * Applies to DataSync entities, relationships, and memberships. Only the CRUD-relevant operations + * are exposed. + */ + export type DataSyncTokenPermissions = { /** - * Files list fetch result status code. + * Whether `create` operations are permitted for corresponding level or not. */ - status: number; + create?: boolean; /** - * List of fetched file objects. + * Whether `get` operations are permitted for corresponding level or not. */ - data: SharedFile[]; + get?: boolean; /** - * Next files list page token. + * Whether `update` operations are permitted for corresponding level or not. */ - next: string; + update?: boolean; /** - * Number of retrieved files. + * Whether `delete` operations are permitted for corresponding level or not. */ - count: number; + delete?: boolean; }; /** - * Send File request parameters. + * DataSync permission scopes. + * + * Carried in the grant token `resources` / `patterns` sections and serialized to the wire keys + * `datasync:entities` / `datasync:relationships` / `datasync:memberships`. */ - export type SendFileParameters = Omit & { + export type DataSyncTokenScopes = { /** - * Channel to send the file to. + * Object containing DataSync `entity` permissions. + * + * Keys are concrete entity ids (e.g. `order-456`) for `resources` or RegEx patterns + * (e.g. `order-*`) for `patterns`. */ - channel: string; + entities?: Record; /** - * File to send. + * Object containing DataSync `relationship` permissions. + * + * Keys are composite relationship ids (e.g. `user.A:channel.X`). */ - file: FileParameters; + relationships?: Record; + /** + * Object containing DataSync `membership` permissions. + * + * Keys are composite membership ids (e.g. `user-123:channel-X`). + */ + memberships?: Record; }; /** - * Send File request response. + * Per-resource DataSync projection assignment. + * + * Each id maps to the single projection name the principal is "looking through" for that resource + * (use `__default__` for the base projection). */ - export type SendFileResponse = PublishFileMessageResponse & { + export type DataSyncProjectionScope = { /** - * Send file request processing status code. + * Entity id -> projection name. + * + * Keys are concrete entity ids (e.g. `user.A`) for `resources` or RegEx patterns + * (e.g. `user.*`) for `patterns`. */ - status: number; + entities?: Record; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link id} can be used to download file from the channel later. - * - * **Important:** Actual file name may be different from the one which has been used during file - * upload. + * Relationship id -> projection name. */ - name: string; + relationships?: Record; /** - * Unique file identifier. - * - * Unique file identifier, and it's {@link name} can be used to download file from the channel - * later. + * Membership id -> projection name. */ - id: string; + memberships?: Record; }; /** - * Upload File request parameters. + * DataSync projection permissions for grant token requests. + * + * Encoded into the `pn-projections` key within the token's `meta` section. Exact (`res`) match + * takes priority over pattern (`pat`) match. */ - export type UploadFileParameters = { + export type DataSyncProjections = { /** - * Unique file identifier. - * - * Unique file identifier, and it's {@link fileName} can be used to download file from the channel - * later. + * Projection assignments for concrete resources. */ - fileId: string; + resources?: DataSyncProjectionScope; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link fileId} can be used to download file from the channel later. - * - * **Note:** Actual file name may be different from the one which has been used during file - * upload. + * Projection assignments for resources which match a RegEx pattern. */ - fileName: string; + patterns?: DataSyncProjectionScope; + }; + + /** + * Generate access token with permissions. + * + * Generate time-limited access token with required permissions for App Context objects. + */ + export type ObjectsGrantTokenParameters = { /** - * File which should be uploaded. + * Total number of minutes for which the token is valid. + * + * The minimum allowed value is `1`. + * The maximum is `43,200` minutes (`30` days). */ - file: PubNubFileInterface; + ttl: number; /** - * Pre-signed file upload Url. + * Object containing resource permissions. */ - uploadUrl: string; + resources?: { + /** + * Object containing `spaces` metadata permissions. + */ + spaces?: Record; + /** + * Object containing `users` permissions. + */ + users?: Record; + }; /** - * An array of form fields to be used in the pre-signed POST request. - * - * **Important:** Form data fields should be passed in exact same order as received from - * the PubNub service. + * Object containing permissions to multiple resources specified by a RegEx pattern. */ - formFields: { + patterns?: { /** - * Form data field name. + * Object containing `spaces` metadata permissions. */ - name: string; + spaces?: Record; /** - * Form data field value. + * Object containing `users` permissions. */ - value: string; - }[]; - }; - - /** - * Upload File request response. - */ - export type UploadFileResponse = { + users?: Record; + }; /** - * Upload File request processing status code. + * Extra metadata to be published with the request. + * + * **Important:** Values must be scalar only; `arrays` or `objects` aren't supported. */ - status: number; + meta?: Metadata; /** - * Service processing result response. + * Single `userId` which is authorized to use the token to make API requests to PubNub. */ - message: Payload; + authorizedUserId?: string; }; /** - * Generate File Upload URL request parameters. + * Generate token with permissions. + * + * Generate time-limited access token with required permissions for resources. */ - export type GenerateFileUploadUrlParameters = { + export type GrantTokenParameters = { /** - * Name of channel to which file should be uploaded. + * Total number of minutes for which the token is valid. + * + * The minimum allowed value is `1`. + * The maximum is `43,200` minutes (`30` days). */ - channel: string; + ttl: number; /** - * Actual name of the file which should be uploaded. + * Object containing resource permissions. */ - name: string; - }; - - /** - * Generation File Upload URL request response. - */ - export type GenerateFileUploadUrlResponse = { + resources?: { + /** + * Object containing `uuid` metadata permissions. + */ + uuids?: Record; + /** + * Object containing `channel` permissions. + */ + channels?: Record; + /** + * Object containing `channel group` permissions. + */ + groups?: Record; + /** + * Object containing DataSync entity-level permissions. + */ + dataSync?: DataSyncTokenScopes; + }; /** - * Unique file identifier. - * - * Unique file identifier, and it's {@link name} can be used to download file from the channel - * later. + * Object containing permissions to multiple resources specified by a RegEx pattern. */ - id: string; + patterns?: { + /** + * Object containing `uuid` metadata permissions to apply to all `uuids` matching the RegEx + * pattern. + */ + uuids?: Record; + /** + * Object containing `channel` permissions to apply to all `channels` matching the RegEx + * pattern. + */ + channels?: Record; + /** + * Object containing `channel group` permissions to apply to all `channel groups` matching the + * RegEx pattern. + */ + groups?: Record; + /** + * Object containing DataSync entity-level permissions to apply to all DataSync resources + * matching the RegEx pattern. + */ + dataSync?: DataSyncTokenScopes; + }; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link id} can be used to download file from the channel later. + * Extra metadata to be published with the request. * - * **Note:** Actual file name may be different from the one which has been used during file - * upload. + * **Important:** Values must be scalar only; `arrays` or `objects` aren't supported. */ - name: string; + meta?: Metadata; /** - * Pre-signed URL for file upload. + * DataSync projection permissions. + * + * Encoded into the `pn-projections` key within the token's `meta` section. */ - url: string; + dataSyncProjections?: DataSyncProjections; /** - * An array of form fields to be used in the pre-signed POST request. - * - * **Important:** Form data fields should be passed in exact same order as received from - * the PubNub service. + * Single `uuid` which is authorized to use the token to make API requests to PubNub. */ - formFields: { - /** - * Form data field name. - */ - name: string; - /** - * Form data field value. - */ - value: string; - }[]; + authorized_uuid?: string; }; /** - * Publish File Message request parameters. + * Response with generated access token. */ - export type PublishFileMessageParameters = { - /** - * Name of channel to which file has been sent. - */ - channel: string; + export type GrantTokenResponse = string; + + /** + * Access token for which permissions should be revoked. + */ + export type RevokeParameters = string; + + /** + * Response with revoked access token. + */ + export type RevokeTokenResponse = Record; + + /** + * Decoded access token representation. + */ + export type Token = { /** - * File annotation message. + * Token version. */ - message?: Payload; + version: number; /** - * User-specified message type. - * - * **Important:** string limited by **3**-**50** case-sensitive alphanumeric characters with only - * `-` and `_` special characters allowed. + * Token generation date time. */ - customMessageType?: string; + timestamp: number; /** - * Custom file and message encryption key. - * - * @deprecated Use {@link Configuration#cryptoModule|cryptoModule} configured for PubNub client - * instance or encrypt file prior {@link PubNub#sendFile|sendFile} method call. + * Maximum duration (in minutes) during which token will be valid. */ - cipherKey?: string; + ttl: number; /** - * Unique file identifier. - * - * Unique file identifier, and it's {@link fileName} can be used to download file from the channel - * later. + * Permissions granted to specific resources. */ - fileId: string; + resources?: Partial>>; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link fileId} can be used to download file from the channel later. - * - * **Note:** Actual file name may be different from the one which has been used during file - * upload. + * Permissions granted to resources which match specified regular expression. */ - fileName: string; + patterns?: Partial>>; /** - * Whether published file messages should be stored in the channel's history. - * - * **Note:** If `storeInHistory` not specified, then the history configuration on the key is - * used. - * - * @default `true` + * The uuid that is exclusively authorized to use this token to make API requests. */ - storeInHistory?: boolean; + authorized_uuid?: string; /** - * How long the message should be stored in the channel's history. - * - * **Note:** If not specified, defaults to the key set's retention value. - * - * @default `0` + * PAM token content signature. */ - ttl?: number; + signature: ArrayBuffer; /** - * Metadata, which should be associated with published file. - * - * Associated metadata can be utilized by message filtering feature. + * Additional information which has been added to the token. */ meta?: Payload; }; /** - * Publish File Message request response. - */ - export type PublishFileMessageResponse = { - /** - * High-precision time when published file message has been received by the PubNub service. - */ - timetoken: string; - }; - - /** - * Download File request parameters. + * Granted resource permissions. + * + * **Note:** Following operations doesn't require any permissions: + * - unsubscribe from channel / channel group + * - where now */ - export type DownloadFileParameters = FileUrlParameters & { + export type Permissions = { /** - * Custom file and message encryption key. + * Resource read permission. * - * @deprecated Use {@link Configuration#cryptoModule|cryptoModule} configured for PubNub client - * instance or encrypt file prior {@link PubNub#sendFile|sendFile} method call. - */ - cipherKey?: string; - }; - - /** - * Generate File download Url request parameters. - */ - export type FileUrlParameters = { - /** - * Name of channel where file has been sent. + * Read permission required for: + * - subscribe to channel / channel group (including presence versions `-pnpres`) + * - here now + * - get presence state + * - set presence state + * - fetch history + * - fetch messages count + * - list shared files + * - download shared file + * - enable / disable push notifications + * - get message actions + * - get history with message actions */ - channel: string; + read: boolean; /** - * Unique file identifier. + * Resource write permission. * - * Unique file identifier, and it's {@link name} can be used to download file from the channel - * later. + * Write permission required for: + * - publish message / signal + * - share file + * - add message actions */ - id: string; + write: boolean; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link id} can be used to download file from the channel later. + * Resource manage permission. * - * **Important:** Actual file name may be different from the one which has been used during file - * upload. + * Manage permission required for: + * - add / remove channels to / from the channel group + * - list channels in group + * - remove channel group + * - set / remove channel members */ - name: string; - }; - - /** - * Generate File Download Url response. - */ - export type FileUrlResponse = string; - - /** - * Delete File request parameters. - */ - export type DeleteFileParameters = { + manage: boolean; /** - * Name of channel where file has been sent. + * Resource delete permission. + * + * Delete permission required for: + * - delete messages from history + * - delete shared file + * - delete user metadata + * - delete channel metadata + * - remove message action */ - channel: string; + delete: boolean; /** - * Unique file identifier. + * Resource get permission. * - * Unique file identifier, and it's {@link name} can be used to download file from the channel - * later. + * Get permission required for: + * - get user metadata + * - get channel metadata + * - get channel members */ - id: string; + get: boolean; /** - * Actual file name under which file has been stored. - * - * File name and unique {@link id} can be used to download file from the channel later. + * Resource update permission. * - * **Important:** Actual file name may be different from the one which has been used during file - * upload. + * Update permissions required for: + * - set user metadata + * - set channel metadata + * - set / remove user membership */ - name: string; - }; - - /** - * Delete File request response. - */ - export type DeleteFileResponse = { + update: boolean; /** - * Delete File request processing status code. + * Resource `join` permission. + * + * `Join` permission required for: + * - set / remove channel members */ - status: number; + join: boolean; }; - } - - export namespace PAM { - /** - * Metadata which will be associated with access token. - */ - export type Metadata = Record; /** - * Channel-specific token permissions. + * Channel-specific permissions. + * + * Permissions include objects to the App Context Channel object as well. */ - export type ChannelTokenPermissions = { + type ChannelPermissions = { /** * Whether `read` operations are permitted for corresponding level or not. */ - read?: boolean; + r?: 0 | 1; /** * Whether `write` operations are permitted for corresponding level or not. */ - write?: boolean; + w?: 0 | 1; /** - * Whether `get` operations are permitted for corresponding level or not. + * Whether `delete` operations are permitted for corresponding level or not. */ - get?: boolean; + d?: 0 | 1; /** - * Whether `manage` operations are permitted for corresponding level or not. + * Whether `get` operations are permitted for corresponding level or not. */ - manage?: boolean; + g?: 0 | 1; /** * Whether `update` operations are permitted for corresponding level or not. */ - update?: boolean; + u?: 0 | 1; + /** + * Whether `manage` operations are permitted for corresponding level or not. + */ + m?: 0 | 1; /** * Whether `join` operations are permitted for corresponding level or not. */ - join?: boolean; + j?: 0 | 1; /** - * Whether `delete` operations are permitted for corresponding level or not. + * Duration for which permissions has been granted. */ - delete?: boolean; + ttl?: number; }; /** - * Space-specific token permissions. - */ - type SpaceTokenPermissions = ChannelTokenPermissions; - - /** - * Channel group-specific token permissions. + * Channel group-specific permissions. */ - export type ChannelGroupTokenPermissions = { + type ChannelGroupPermissions = { /** * Whether `read` operations are permitted for corresponding level or not. */ - read?: boolean; + r?: 0 | 1; /** * Whether `manage` operations are permitted for corresponding level or not. */ - manage?: boolean; + m?: 0 | 1; + /** + * Duration for which permissions has been granted. + */ + ttl?: number; }; /** - * Uuid-specific token permissions. + * App Context User-specific permissions. */ - export type UuidTokenPermissions = { + type UserPermissions = { /** * Whether `get` operations are permitted for corresponding level or not. */ - get?: boolean; + g?: 0 | 1; /** * Whether `update` operations are permitted for corresponding level or not. */ - update?: boolean; + u?: 0 | 1; /** * Whether `delete` operations are permitted for corresponding level or not. */ - delete?: boolean; + d?: 0 | 1; + /** + * Duration for which permissions has been granted. + */ + ttl?: number; }; /** - * User-specific token permissions. - */ - type UserTokenPermissions = UuidTokenPermissions; - - /** - * Generate access token with permissions. - * - * Generate time-limited access token with required permissions for App Context objects. + * Common permissions audit response content. */ - export type ObjectsGrantTokenParameters = { - /** - * Total number of minutes for which the token is valid. - * - * The minimum allowed value is `1`. - * The maximum is `43,200` minutes (`30` days). - */ - ttl: number; - /** - * Object containing resource permissions. - */ - resources?: { - /** - * Object containing `spaces` metadata permissions. - */ - spaces?: Record; - /** - * Object containing `users` permissions. - */ - users?: Record; - }; + type BaseAuditResponse< + Level extends 'channel' | 'channel+auth' | 'channel-group' | 'channel-group+auth' | 'user' | 'subkey', + > = { /** - * Object containing permissions to multiple resources specified by a RegEx pattern. + * Permissions level. */ - patterns?: { - /** - * Object containing `spaces` metadata permissions. - */ - spaces?: Record; - /** - * Object containing `users` permissions. - */ - users?: Record; - }; + level: Level; /** - * Extra metadata to be published with the request. - * - * **Important:** Values must be scalar only; `arrays` or `objects` aren't supported. + * Subscription key at which permissions has been granted. */ - meta?: Metadata; + subscribe_key: string; /** - * Single `userId` which is authorized to use the token to make API requests to PubNub. + * Duration for which permissions has been granted. */ - authorizedUserId?: string; + ttl?: number; }; /** - * Generate token with permissions. - * - * Generate time-limited access token with required permissions for resources. + * Auth keys permissions for specified `level`. */ - export type GrantTokenParameters = { + type AuthKeysPermissions = { /** - * Total number of minutes for which the token is valid. - * - * The minimum allowed value is `1`. - * The maximum is `43,200` minutes (`30` days). + * Auth keys-based permissions for specified `level` permission. */ - ttl: number; + auths: Record; + }; + + /** + * Single channel permissions audit result. + */ + type ChannelPermissionsResponse = BaseAuditResponse<'channel+auth'> & { /** - * Object containing resource permissions. + * Name of channel for which permissions audited. */ - resources?: { - /** - * Object containing `uuid` metadata permissions. - */ - uuids?: Record; - /** - * Object containing `channel` permissions. - */ - channels?: Record; - /** - * Object containing `channel group` permissions. - */ - groups?: Record; - }; + channel: string; + } & AuthKeysPermissions; + + /** + * Multiple channels permissions audit result. + */ + type ChannelsPermissionsResponse = BaseAuditResponse<'channel'> & { /** - * Object containing permissions to multiple resources specified by a RegEx pattern. + * Per-channel permissions. */ - patterns?: { - /** - * Object containing `uuid` metadata permissions to apply to all `uuids` matching the RegEx - * pattern. - */ - uuids?: Record; - /** - * Object containing `channel` permissions to apply to all `channels` matching the RegEx - * pattern. - */ - channels?: Record; - /** - * Object containing `channel group` permissions to apply to all `channel groups` matching the - * RegEx pattern. - */ - groups?: Record; - }; + channels: Record>; + }; + + /** + * Single channel group permissions result. + */ + type ChannelGroupPermissionsResponse = BaseAuditResponse<'channel-group+auth'> & { /** - * Extra metadata to be published with the request. - * - * **Important:** Values must be scalar only; `arrays` or `objects` aren't supported. + * Name of channel group for which permissions audited. */ - meta?: Metadata; + 'channel-group': string; + } & AuthKeysPermissions; + + /** + * Multiple channel groups permissions audit result. + */ + type ChannelGroupsPermissionsResponse = BaseAuditResponse<'channel'> & { /** - * Single `uuid` which is authorized to use the token to make API requests to PubNub. + * Per-channel group permissions. */ - authorized_uuid?: string; + 'channel-groups': Record>; }; /** - * Response with generated access token. + * App Context User permissions audit result. */ - export type GrantTokenResponse = string; + type UserPermissionsResponse = BaseAuditResponse<'user'> & { + /** + * Name of channel for which `user` permissions audited. + */ + channel: string; + } & AuthKeysPermissions; /** - * Access token for which permissions should be revoked. + * Global sub-key level permissions audit result. */ - export type RevokeParameters = string; + type SubKeyPermissionsResponse = BaseAuditResponse<'subkey'> & { + /** + * Per-channel permissions. + */ + channels: Record>; + /** + * Per-channel group permissions. + */ + 'channel-groups': Record>; + /** + * Per-object permissions. + */ + objects: Record>; + }; /** - * Response with revoked access token. + * Response with permission information. */ - export type RevokeTokenResponse = Record; + export type PermissionsResponse = + | ChannelPermissionsResponse + | ChannelsPermissionsResponse + | ChannelGroupPermissionsResponse + | ChannelGroupsPermissionsResponse + | UserPermissionsResponse + | SubKeyPermissionsResponse; /** - * Decoded access token representation. + * Audit permissions for provided auth keys / global permissions. + * + * Audit permissions on specific channel and / or channel group for the set of auth keys. */ - export type Token = { + export type AuditParameters = { /** - * Token version. + * Name of channel for which channel-based permissions should be checked for {@link authKeys}. */ - version: number; + channel?: string; /** - * Token generation date time. + * Name of channel group for which channel group-based permissions should be checked for {@link authKeys}. */ - timestamp: number; + channelGroup?: string; /** - * Maximum duration (in minutes) during which token will be valid. + * List of auth keys for which permissions should be checked. + * + * Leave this empty to check channel / group -based permissions or global permissions. + * + * @default `[]` */ - ttl: number; + authKeys?: string[]; + }; + + /** + * Grant permissions for provided auth keys / global permissions. + * + * Grant permissions on specific channel and / or channel group for the set of auth keys. + */ + export type GrantParameters = { /** - * Permissions granted to specific resources. + * List of channels for which permissions should be granted. */ - resources?: Partial>>; + channels?: string[]; /** - * Permissions granted to resources which match specified regular expression. + * List of channel groups for which permissions should be granted. */ - patterns?: Partial>>; + channelGroups?: string[]; /** - * The uuid that is exclusively authorized to use this token to make API requests. + * List of App Context UUID for which permissions should be granted. */ - authorized_uuid?: string; + uuids?: string[]; /** - * PAM token content signature. + * List of auth keys for which permissions should be granted on specified objects. + * + * Leave this empty to grant channel / group -based permissions or global permissions. */ - signature: ArrayBuffer; + authKeys?: string[]; /** - * Additional information which has been added to the token. + * Whether `read` operations are permitted for corresponding level or not. + * + * @default `false` */ - meta?: Payload; - }; - - /** - * Granted resource permissions. - * - * **Note:** Following operations doesn't require any permissions: - * - unsubscribe from channel / channel group - * - where now - */ - export type Permissions = { + read?: boolean; /** - * Resource read permission. + * Whether `write` operations are permitted for corresponding level or not. * - * Read permission required for: - * - subscribe to channel / channel group (including presence versions `-pnpres`) - * - here now - * - get presence state - * - set presence state - * - fetch history - * - fetch messages count - * - list shared files - * - download shared file - * - enable / disable push notifications - * - get message actions - * - get history with message actions + * @default `false` */ - read: boolean; + write?: boolean; /** - * Resource write permission. + * Whether `delete` operations are permitted for corresponding level or not. * - * Write permission required for: - * - publish message / signal - * - share file - * - add message actions + * @default `false` */ - write: boolean; + delete?: boolean; /** - * Resource manage permission. + * Whether `get` operations are permitted for corresponding level or not. * - * Manage permission required for: - * - add / remove channels to / from the channel group - * - list channels in group - * - remove channel group - * - set / remove channel members + * @default `false` */ - manage: boolean; + get?: boolean; /** - * Resource delete permission. + * Whether `update` operations are permitted for corresponding level or not. * - * Delete permission required for: - * - delete messages from history - * - delete shared file - * - delete user metadata - * - delete channel metadata - * - remove message action + * @default `false` */ - delete: boolean; + update?: boolean; /** - * Resource get permission. + * Whether `manage` operations are permitted for corresponding level or not. * - * Get permission required for: - * - get user metadata - * - get channel metadata - * - get channel members + * @default `false` */ - get: boolean; + manage?: boolean; /** - * Resource update permission. + * Whether `join` operations are permitted for corresponding level or not. * - * Update permissions required for: - * - set user metadata - * - set channel metadata - * - set / remove user membership + * @default `false` */ - update: boolean; + join?: boolean; /** - * Resource `join` permission. + * For how long permissions should be effective (in minutes). * - * `Join` permission required for: - * - set / remove channel members + * @default `1440` */ - join: boolean; + ttl?: number; }; + } + export namespace Time { /** - * Channel-specific permissions. - * - * Permissions include objects to the App Context Channel object as well. + * Service success response. */ - type ChannelPermissions = { - /** - * Whether `read` operations are permitted for corresponding level or not. - */ - r?: 0 | 1; - /** - * Whether `write` operations are permitted for corresponding level or not. - */ - w?: 0 | 1; + export type TimeResponse = { /** - * Whether `delete` operations are permitted for corresponding level or not. + * High-precision time when published data has been received by the PubNub service. */ - d?: 0 | 1; + timetoken: string; + }; + } + + export namespace DataSync { + /** + * Filterable field definition for entity classes. + */ + export type FilterableField = { + /** Unique semantic identifier for the property. */ + name: string; + /** JSON Pointer (RFC 6901) to the property location. */ + path: string; + /** Data type of the property value. */ + valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; /** - * Whether `get` operations are permitted for corresponding level or not. + * Whether the property should be indexed for full-text search. + * @default false */ - g?: 0 | 1; + enabledAdvancedFiltering?: boolean; /** - * Whether `update` operations are permitted for corresponding level or not. + * Whether the property can have null values. + * @default true */ - u?: 0 | 1; + isNullable?: boolean; + }; + + /** + * Cursor-based pagination metadata returned by the server. + */ + export type DataSyncPageMeta = { + /** Opaque cursor for the next page. Null if no more results. */ + next_cursor: string | null; + /** Opaque cursor for the previous page. Null if first page. */ + prev_cursor: string | null; + /** Whether there are more results after this page. */ + has_next: boolean; + /** Whether there are results before this page. */ + has_prev: boolean; + /** The limit applied to this page. */ + limit: number; + }; + + /** + * HATEOAS navigation links. + */ + export type DataSyncLinks = { + /** Link to the current page. */ + self: string; + /** Link to the next page, if available. */ + next?: string | null; + /** Link to the previous page, if available. */ + prev?: string | null; + /** Additional links for related resources. */ + [key: string]: string | null | undefined; + }; + + /** + * Common parameters for paginated list requests. + */ + type PagedRequestParameters = { + /** Opaque cursor for pagination. Omit for the first page. */ + cursor?: string; /** - * Whether `manage` operations are permitted for corresponding level or not. + * Maximum number of items per page. + * @default 20 + * @max 100 */ - m?: 0 | 1; + limit?: number; + /** Filter expression for results. */ + filter?: string; /** - * Whether `join` operations are permitted for corresponding level or not. + * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). + * Example: "+name,-createdAt" */ - j?: 0 | 1; + sort?: string; + }; + + /** + * Single-entity response envelope. + */ + type DataSyncEntityResponse = { + /** HTTP status code. */ + status: number; + /** Response data. */ + data: T; + /** HATEOAS links. */ + links?: DataSyncLinks; + /** Response metadata. */ + meta?: DataSyncPageMeta; + }; + + /** + * Paged list response envelope. + */ + type DataSyncPagedResponse = { + /** HTTP status code. */ + status: number; + /** Array of response items. */ + data: T[]; + /** HATEOAS links for pagination. */ + links?: DataSyncLinks; + /** Cursor-based pagination metadata. */ + meta?: DataSyncPageMeta; + }; + + /** + * Entity properties for create requests. + * + * Includes `entityClass` since it must be set at creation time and is immutable afterward. + */ + export type CreateEntityProperties = { + /** Entity class this entity belongs to. */ + entityClass: string; + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity properties for update (PUT) requests. + * + * `entityClass` is immutable after creation and therefore excluded from updates. + */ + export type UpdateEntityProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * Entity resource as returned from the server. + */ + export type EntityObject = { + /** Unique identifier (UUID). */ + id: string; + /** Entity class this entity belongs to. */ + entityClass: string; + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + /** Date and time the entity was created (ISO 8601). */ + createdAt: string; + /** Date and time the entity was last updated (ISO 8601). */ + updatedAt: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ + expiresAt?: string; + }; + + /** + * Create Entity request parameters. + */ + export type CreateEntityParameters = { /** - * Duration for which permissions has been granted. + * Entity properties to create. + * + * All entity properties go inside `entity` because they map to the request body envelope. + * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation + * posts to a collection URL with all fields in the body. */ - ttl?: number; + entity: CreateEntityProperties & { + /** + * Optional entity ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; }; /** - * Channel group-specific permissions. + * Get Entity request parameters. */ - type ChannelGroupPermissions = { - /** - * Whether `read` operations are permitted for corresponding level or not. - */ - r?: 0 | 1; - /** - * Whether `manage` operations are permitted for corresponding level or not. - */ - m?: 0 | 1; - /** - * Duration for which permissions has been granted. - */ - ttl?: number; + export type GetEntityParameters = { + /** Entity ID. */ + id: string; }; /** - * App Context User-specific permissions. + * Get All Entities request parameters. + * + * `entityClass` is required — entities are always listed within the context of their class. */ - type UserPermissions = { - /** - * Whether `get` operations are permitted for corresponding level or not. - */ - g?: 0 | 1; + export type GetAllEntitiesParameters = PagedRequestParameters & { + /** Entity class name to filter by (required). */ + entityClass: string; /** - * Whether `update` operations are permitted for corresponding level or not. + * Entity class version. If not provided, the server returns entities for the latest version. */ - u?: 0 | 1; + entityClassVersion?: number; /** - * Whether `delete` operations are permitted for corresponding level or not. + * Advanced filter expression for complex queries. + * + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. */ - d?: 0 | 1; + filterAdvanced?: string; + }; + + /** + * Update Entity request parameters (full replacement via PUT). + * + * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, + * and `payload` can be updated. + */ + export type UpdateEntityParameters = { + /** Entity ID. */ + id: string; + /** Complete entity properties for replacement (excludes immutable `entityClass`). */ + entity: UpdateEntityProperties; /** - * Duration for which permissions has been granted. + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. */ - ttl?: number; + ifMatchesEtag?: string; }; /** - * Common permissions audit response content. + * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. */ - type BaseAuditResponse< - Level extends 'channel' | 'channel+auth' | 'channel-group' | 'channel-group+auth' | 'user' | 'subkey', - > = { + export type PatchEntityParameters = { + /** Entity ID. */ + id: string; /** - * Permissions level. + * Fields to add, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "add" operations. + * + * @example + * ```typescript + * add: { + * 'payload.tags.0': 'priority', + * 'payload.profile.displayName': 'Alice', + * } + * ``` */ - level: Level; + add?: Record; /** - * Subscription key at which permissions has been granted. + * Fields to replace, using dot-notation keys. + * + * Each key is a dot-delimited path to the target field. + * The SDK converts these to JSON Patch "replace" operations. + * + * @example + * ```typescript + * replace: { + * 'status': 'active', + * 'payload.score': 300, + * } + * ``` */ - subscribe_key: string; + replace?: Record; /** - * Duration for which permissions has been granted. + * Array of dot-notation field paths to remove. + * + * The SDK converts these to JSON Patch "remove" operations. + * + * @example + * ```typescript + * remove: ['payload.tempFlag', 'payload.legacyField'] + * ``` */ - ttl?: number; - }; - - /** - * Auth keys permissions for specified `level`. - */ - type AuthKeysPermissions = { + remove?: string[]; /** - * Auth keys-based permissions for specified `level` permission. + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. */ - auths: Record; + ifMatchesEtag?: string; }; /** - * Single channel permissions audit result. + * Remove Entity request parameters. */ - type ChannelPermissionsResponse = BaseAuditResponse<'channel+auth'> & { + export type RemoveEntityParameters = { + /** Entity ID. */ + id: string; /** - * Name of channel for which permissions audited. + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. */ - channel: string; - } & AuthKeysPermissions; + ifMatchesEtag?: string; + }; - /** - * Multiple channels permissions audit result. - */ - type ChannelsPermissionsResponse = BaseAuditResponse<'channel'> & { - /** - * Per-channel permissions. - */ - channels: Record>; + /** Response for creating an entity. */ + export type CreateEntityResponse = DataSyncEntityResponse; + + /** Response for getting a single entity. */ + export type GetEntityResponse = DataSyncEntityResponse; + + /** Response for listing entities. */ + export type GetAllEntitiesResponse = DataSyncPagedResponse; + + /** Response for updating an entity (PUT). */ + export type UpdateEntityResponse = DataSyncEntityResponse; + + /** Response for patching an entity (PATCH). */ + export type PatchEntityResponse = DataSyncEntityResponse; + + /** Response for removing an entity. */ + export type RemoveEntityResponse = { + /** HTTP status code. */ + status: number; }; /** - * Single channel group permissions result. + * Relationship properties for create requests. + * + * Both `entityAId` and `entityBId` must be set at creation time. */ - type ChannelGroupPermissionsResponse = BaseAuditResponse<'channel-group+auth'> & { - /** - * Name of channel group for which permissions audited. - */ - 'channel-group': string; - } & AuthKeysPermissions; + export type CreateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Relationship class this relationship belongs to. */ + relationshipClass: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + }; /** - * Multiple channel groups permissions audit result. + * Relationship properties for update (PUT) requests. + * + * PUT is a full replacement — `entityAId`, `entityBId`, and `relationshipClassVersion` are required + * (`relationshipClass` is immutable after creation and therefore excluded). The server rejects a + * PUT that omits `relationshipClassVersion`. */ - type ChannelGroupsPermissionsResponse = BaseAuditResponse<'channel'> & { - /** - * Per-channel group permissions. - */ - 'channel-groups': Record>; + export type UpdateRelationshipProperties = { + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; }; /** - * App Context User permissions audit result. + * Relationship resource as returned from the server. */ - type UserPermissionsResponse = BaseAuditResponse<'user'> & { - /** - * Name of channel for which `user` permissions audited. - */ - channel: string; - } & AuthKeysPermissions; + export type RelationshipObject = { + /** Unique identifier. */ + id: string; + /** First entity ID in the relationship. */ + entityAId: string; + /** Second entity ID in the relationship. */ + entityBId: string; + /** Relationship class this relationship belongs to. */ + relationshipClass: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; + /** Lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + /** Date and time the relationship was created (ISO 8601). */ + createdAt: string; + /** Date and time the relationship was last updated (ISO 8601). */ + updatedAt: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). */ + expiresAt?: string; + }; /** - * Global sub-key level permissions audit result. + * Create Relationship request parameters. */ - type SubKeyPermissionsResponse = BaseAuditResponse<'subkey'> & { - /** - * Per-channel permissions. - */ - channels: Record>; - /** - * Per-channel group permissions. - */ - 'channel-groups': Record>; + export type CreateRelationshipParameters = { /** - * Per-object permissions. + * Relationship properties to create. + * + * All relationship properties go inside `relationship` because they map to the request body envelope. */ - objects: Record>; + relationship: CreateRelationshipProperties & { + /** + * Optional relationship ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; }; /** - * Response with permission information. + * Get Relationship request parameters. */ - export type PermissionsResponse = - | ChannelPermissionsResponse - | ChannelsPermissionsResponse - | ChannelGroupPermissionsResponse - | ChannelGroupsPermissionsResponse - | UserPermissionsResponse - | SubKeyPermissionsResponse; + export type GetRelationshipParameters = { + /** Relationship ID. */ + id: string; + }; /** - * Audit permissions for provided auth keys / global permissions. - * - * Audit permissions on specific channel and / or channel group for the set of auth keys. + * Get All Relationships request parameters. */ - export type AuditParameters = { - /** - * Name of channel for which channel-based permissions should be checked for {@link authKeys}. - */ - channel?: string; - /** - * Name of channel group for which channel group-based permissions should be checked for {@link authKeys}. - */ - channelGroup?: string; + export type GetAllRelationshipsParameters = PagedRequestParameters & { + /** Relationship class name (required by the server). */ + relationshipClass: string; + /** Relationship class version. */ + relationshipClassVersion?: number; + /** Filter relationships by first entity ID. */ + entityAId?: string; + /** Filter relationships by second entity ID. */ + entityBId?: string; /** - * List of auth keys for which permissions should be checked. - * - * Leave this empty to check channel / group -based permissions or global permissions. + * Advanced filter expression for complex queries. * - * @default `[]` + * Supports logical operators and nested conditions for sophisticated filtering + * beyond what the basic `filter` parameter provides. */ - authKeys?: string[]; + filterAdvanced?: string; }; /** - * Grant permissions for provided auth keys / global permissions. - * - * Grant permissions on specific channel and / or channel group for the set of auth keys. + * Update Relationship request parameters (full replacement via PUT). */ - export type GrantParameters = { - /** - * List of channels for which permissions should be granted. - */ - channels?: string[]; - /** - * List of channel groups for which permissions should be granted. - */ - channelGroups?: string[]; - /** - * List of App Context UUID for which permissions should be granted. - */ - uuids?: string[]; - /** - * List of auth keys for which permissions should be granted on specified objects. - * - * Leave this empty to grant channel / group -based permissions or global permissions. - */ - authKeys?: string[]; + export type UpdateRelationshipParameters = { + /** Relationship ID. */ + id: string; + /** Complete relationship properties for replacement. */ + relationship: UpdateRelationshipProperties; /** - * Whether `read` operations are permitted for corresponding level or not. - * - * @default `false` + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. */ - read?: boolean; + ifMatchesEtag?: string; + }; + + /** + * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. + */ + export type PatchRelationshipParameters = { + /** Relationship ID. */ + id: string; /** - * Whether `write` operations are permitted for corresponding level or not. + * Fields to add, using dot-notation keys. * - * @default `false` - */ - write?: boolean; - /** - * Whether `delete` operations are permitted for corresponding level or not. + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "add" operations. * - * @default `false` + * @example + * ```typescript + * add: { + * 'tags.0': 'mentor', + * } + * ``` */ - delete?: boolean; + add?: Record; /** - * Whether `get` operations are permitted for corresponding level or not. + * Fields to replace, using dot-notation keys. * - * @default `false` - */ - get?: boolean; - /** - * Whether `update` operations are permitted for corresponding level or not. + * Each key is a dot-delimited path to the target field within `payload`. + * The SDK converts these to JSON Patch "replace" operations. * - * @default `false` + * @example + * ```typescript + * replace: { + * 'role': 'admin', + * 'permissions.read': true, + * } + * ``` */ - update?: boolean; + replace?: Record; /** - * Whether `manage` operations are permitted for corresponding level or not. + * Array of dot-notation field paths to remove from `payload`. * - * @default `false` - */ - manage?: boolean; - /** - * Whether `join` operations are permitted for corresponding level or not. + * The SDK converts these to JSON Patch "remove" operations. * - * @default `false` + * @example + * ```typescript + * remove: ['tempFlag', 'legacyField'] + * ``` */ - join?: boolean; + remove?: string[]; /** - * For how long permissions should be effective (in minutes). - * - * @default `1440` + * ETag for optimistic concurrency control. + * If provided, the patch only succeeds if the server's ETag matches. */ - ttl?: number; + ifMatchesEtag?: string; }; - } - export namespace Time { /** - * Service success response. + * Remove Relationship request parameters. */ - export type TimeResponse = { + export type RemoveRelationshipParameters = { + /** Relationship ID. */ + id: string; /** - * High-precision time when published data has been received by the PubNub service. + * ETag for optimistic concurrency control. + * If provided, the delete only succeeds if the server's ETag matches. */ - timetoken: string; + ifMatchesEtag?: string; + }; + + /** Response for creating a relationship. */ + export type CreateRelationshipResponse = DataSyncEntityResponse; + + /** Response for getting a single relationship. */ + export type GetRelationshipResponse = DataSyncEntityResponse; + + /** Response for listing relationships. */ + export type GetAllRelationshipsResponse = DataSyncPagedResponse; + + /** Response for updating a relationship (PUT). */ + export type UpdateRelationshipResponse = DataSyncEntityResponse; + + /** Response for patching a relationship (PATCH). */ + export type PatchRelationshipResponse = DataSyncEntityResponse; + + /** Response for removing a relationship. */ + export type RemoveRelationshipResponse = { + /** HTTP status code. */ + status: number; }; - } - export namespace DataSync { /** - * Filterable field definition for entity classes. + * User properties for create requests. */ - export type FilterableField = { - /** Unique semantic identifier for the property. */ - name: string; - /** JSON Pointer (RFC 6901) to the property location. */ - path: string; - /** Data type of the property value. */ - valueKind: 'string' | 'number' | 'boolean' | 'date' | 'datetime'; - /** - * Whether the property should be indexed for full-text search. - * @default false - */ - enabledAdvancedFiltering?: boolean; + export type CreateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; + }; + + /** + * User resource as returned from the server. + */ + export type UserObject = { + /** Unique identifier (UUID). */ + id: string; + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Lifecycle status. */ + status?: string; + /** User-defined JSON payload. */ + payload?: Record; + /** Date and time the user was created (ISO 8601). */ + createdAt: string; + /** Date and time the user was last updated (ISO 8601). */ + updatedAt: string; + /** Content fingerprint for optimistic concurrency control. */ + eTag: string; + /** Auto-deletion timestamp (ISO 8601). Users expire at this time. */ + expiresAt?: string; + }; + + /** + * Create User request parameters. + */ + export type CreateUserParameters = { /** - * Whether the property can have null values. - * @default true + * User properties to create. */ - isNullable?: boolean; + user: CreateUserProperties & { + /** + * Optional user ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + }; }; /** - * Cursor-based pagination metadata returned by the server. + * User properties for update (PUT) requests. */ - export type DataSyncPageMeta = { - /** Opaque cursor for the next page. Null if no more results. */ - next_cursor: string | null; - /** Opaque cursor for the previous page. Null if first page. */ - prev_cursor: string | null; - /** Whether there are more results after this page. */ - has_next: boolean; - /** Whether there are results before this page. */ - has_prev: boolean; - /** The limit applied to this page. */ - limit: number; + export type UpdateUserProperties = { + /** Version of the entity class schema. */ + entityClassVersion: number; + /** Optional lifecycle status. */ + status?: string; + /** User-defined JSON payload conforming to the entity class schema. */ + payload?: Record; }; /** - * HATEOAS navigation links. + * Get User request parameters. + */ + export type GetUserParameters = { + /** User ID. */ + id: string; + }; + + /** + * Get All Users request parameters. + */ + export type GetAllUsersParameters = PagedRequestParameters & { + /** + * Entity class version. If not provided, the server returns users for the latest version. + */ + entityClassVersion?: number; + /** + * Advanced filter expression for complex queries. + */ + filterAdvanced?: string; + }; + + /** + * Update User request parameters (full replacement via PUT). */ - export type DataSyncLinks = { - /** Link to the current page. */ - self: string; - /** Link to the next page, if available. */ - next?: string | null; - /** Link to the previous page, if available. */ - prev?: string | null; - /** Additional links for related resources. */ - [key: string]: string | null | undefined; + export type UpdateUserParameters = { + /** User ID. */ + id: string; + /** Complete user properties for replacement. */ + user: UpdateUserProperties; + /** + * ETag for optimistic concurrency control. + * If provided, the update only succeeds if the server's ETag matches. + */ + ifMatchesEtag?: string; }; /** - * Common parameters for paginated list requests. + * Patch User request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * The SDK converts these to JSON Patch operations on the wire. + * + * At least one of `add`, `replace`, or `remove` must be provided. */ - type PagedRequestParameters = { - /** Opaque cursor for pagination. Omit for the first page. */ - cursor?: string; + export type PatchUserParameters = { + /** User ID. */ + id: string; /** - * Maximum number of items per page. - * @default 20 - * @max 100 + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. */ - limit?: number; - /** Filter expression for results. */ - filter?: string; + add?: Record; /** - * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). - * Example: "+name,-createdAt" + * Fields to replace, using dot-notation keys. + * The SDK converts these to JSON Patch "replace" operations. */ - sort?: string; + replace?: Record; + /** + * Array of dot-notation field paths to remove. + * The SDK converts these to JSON Patch "remove" operations. + */ + remove?: string[]; + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; }; /** - * Single-entity response envelope. + * Remove User request parameters. */ - type DataSyncEntityResponse = { - /** HTTP status code. */ - status: number; - /** Response data. */ - data: T; - /** HATEOAS links. */ - links?: DataSyncLinks; - /** Response metadata. */ - meta?: DataSyncPageMeta; + export type RemoveUserParameters = { + /** User ID. */ + id: string; + /** + * ETag for optimistic concurrency control. + */ + ifMatchesEtag?: string; }; - /** - * Paged list response envelope. - */ - type DataSyncPagedResponse = { + /** Response for creating a user. */ + export type CreateUserResponse = DataSyncEntityResponse; + + /** Response for getting a single user. */ + export type GetUserResponse = DataSyncEntityResponse; + + /** Response for listing users. */ + export type GetAllUsersResponse = DataSyncPagedResponse; + + /** Response for updating a user (PUT). */ + export type UpdateUserResponse = DataSyncEntityResponse; + + /** Response for patching a user (PATCH). */ + export type PatchUserResponse = DataSyncEntityResponse; + + /** Response for removing a user. */ + export type RemoveUserResponse = { /** HTTP status code. */ status: number; - /** Array of response items. */ - data: T[]; - /** HATEOAS links for pagination. */ - links?: DataSyncLinks; - /** Cursor-based pagination metadata. */ - meta?: DataSyncPageMeta; }; /** - * Entity properties for create requests. - * - * Includes `entityClass` since it must be set at creation time and is immutable afterward. + * Channel properties for create requests. */ - export type CreateEntityProperties = { - /** Entity class this entity belongs to. */ - entityClass: string; + export type CreateChannelProperties = { /** Version of the entity class schema. */ entityClassVersion: number; /** Optional lifecycle status. */ @@ -9357,11 +10656,9 @@ declare namespace PubNub { }; /** - * Entity properties for update (PUT) requests. - * - * `entityClass` is immutable after creation and therefore excluded from updates. + * Channel properties for update (PUT) requests. */ - export type UpdateEntityProperties = { + export type UpdateChannelProperties = { /** Version of the entity class schema. */ entityClassVersion: number; /** Optional lifecycle status. */ @@ -9371,195 +10668,155 @@ declare namespace PubNub { }; /** - * Entity resource as returned from the server. + * Channel resource as returned from the server. */ - export type EntityObject = { + export type ChannelObject = { /** Unique identifier (UUID). */ id: string; - /** Entity class this entity belongs to. */ - entityClass: string; /** Version of the entity class schema. */ entityClassVersion: number; /** Lifecycle status. */ status?: string; /** User-defined JSON payload. */ payload?: Record; - /** Date and time the entity was created (ISO 8601). */ + /** Date and time the channel was created (ISO 8601). */ createdAt: string; - /** Date and time the entity was last updated (ISO 8601). */ + /** Date and time the channel was last updated (ISO 8601). */ updatedAt: string; /** Content fingerprint for optimistic concurrency control. */ eTag: string; - /** Auto-deletion timestamp (ISO 8601). Entities expire at this time. */ + /** Auto-deletion timestamp (ISO 8601). Channels expire at this time. */ expiresAt?: string; }; /** - * Create Entity request parameters. + * Create Channel request parameters. */ - export type CreateEntityParameters = { + export type CreateChannelParameters = { /** - * Entity properties to create. - * - * All entity properties go inside `entity` because they map to the request body envelope. - * Unlike EntityClass (where `name`/`version` are URL path params), Entity creation - * posts to a collection URL with all fields in the body. + * Channel properties to create. */ - entity: CreateEntityProperties & { + channel: CreateChannelProperties & { /** - * Optional entity ID. + * Optional channel ID. * Server auto-generates a UUID if not provided. */ id?: string; }; - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** - * Get Entity request parameters. + * Get Channel request parameters. */ - export type GetEntityParameters = { - /** Entity ID. */ + export type GetChannelParameters = { + /** Channel ID. */ id: string; }; /** - * Get All Entities request parameters. - * - * `entityClass` is required — entities are always listed within the context of their class. + * Get All Channels request parameters. */ - export type GetAllEntitiesParameters = PagedRequestParameters & { - /** Entity class name to filter by (required). */ - entityClass: string; + export type GetAllChannelsParameters = PagedRequestParameters & { /** - * Entity class version. If not provided, the server returns entities for the latest version. + * Entity class version. If not provided, the server returns channels for the latest version. */ entityClassVersion?: number; /** * Advanced filter expression for complex queries. - * - * Supports logical operators and nested conditions for sophisticated filtering - * beyond what the basic `filter` parameter provides. */ filterAdvanced?: string; }; /** - * Update Entity request parameters (full replacement via PUT). - * - * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, - * and `payload` can be updated. + * Update Channel request parameters (full replacement via PUT). */ - export type UpdateEntityParameters = { - /** Entity ID. */ + export type UpdateChannelParameters = { + /** Channel ID. */ id: string; - /** Complete entity properties for replacement (excludes immutable `entityClass`). */ - entity: UpdateEntityProperties; + /** Complete channel properties for replacement. */ + channel: UpdateChannelProperties; /** * ETag for optimistic concurrency control. - * If provided, the update only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; }; /** - * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * Patch Channel request parameters (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * - * At least one of `set` or `remove` must be provided. + * At least one of `add`, `replace`, or `remove` must be provided. */ - export type PatchEntityParameters = { - /** Entity ID. */ + export type PatchChannelParameters = { + /** Channel ID. */ id: string; /** - * Fields to add or replace, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field. + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; + /** + * Fields to replace, using dot-notation keys. * The SDK converts these to JSON Patch "replace" operations. - * - * @example - * ```typescript - * set: { - * 'status': 'active', - * 'payload.score': 300, - * 'payload.profile.displayName': 'Alice', - * } - * ``` */ - set?: Record; + replace?: Record; /** * Array of dot-notation field paths to remove. - * * The SDK converts these to JSON Patch "remove" operations. - * - * @example - * ```typescript - * remove: ['payload.tempFlag', 'payload.legacyField'] - * ``` */ remove?: string[]; /** * ETag for optimistic concurrency control. - * If provided, the patch only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** - * Remove Entity request parameters. + * Remove Channel request parameters. */ - export type RemoveEntityParameters = { - /** Entity ID. */ + export type RemoveChannelParameters = { + /** Channel ID. */ id: string; /** * ETag for optimistic concurrency control. - * If provided, the delete only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; }; - /** Response for creating an entity. */ - export type CreateEntityResponse = DataSyncEntityResponse; + /** Response for creating a channel. */ + export type CreateChannelResponse = DataSyncEntityResponse; - /** Response for getting a single entity. */ - export type GetEntityResponse = DataSyncEntityResponse; + /** Response for getting a single channel. */ + export type GetChannelResponse = DataSyncEntityResponse; - /** Response for listing entities. */ - export type GetAllEntitiesResponse = DataSyncPagedResponse; + /** Response for listing channels. */ + export type GetAllChannelsResponse = DataSyncPagedResponse; - /** Response for updating an entity (PUT). */ - export type UpdateEntityResponse = DataSyncEntityResponse; + /** Response for updating a channel (PUT). */ + export type UpdateChannelResponse = DataSyncEntityResponse; - /** Response for patching an entity (PATCH). */ - export type PatchEntityResponse = DataSyncEntityResponse; + /** Response for patching a channel (PATCH). */ + export type PatchChannelResponse = DataSyncEntityResponse; - /** Response for removing an entity. */ - export type RemoveEntityResponse = { + /** Response for removing a channel. */ + export type RemoveChannelResponse = { /** HTTP status code. */ status: number; }; /** - * Relationship properties for create requests. + * Membership properties for create requests. * - * Both `entityAId` and `entityBId` must be set at creation time. + * Both `userId` and `channelId` must be set at creation time. */ - export type CreateRelationshipProperties = { - /** First entity ID in the relationship. */ - entityAId: string; - /** Second entity ID in the relationship. */ - entityBId: string; + export type CreateMembershipProperties = { + /** User ID reference. */ + userId: string; + /** Channel ID reference. */ + channelId: string; + /** Version of the Membership relationship class. */ + relationshipClassVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload. */ @@ -9567,15 +10824,15 @@ declare namespace PubNub { }; /** - * Relationship properties for update (PUT) requests. + * Membership properties for update (PUT) requests. * - * PUT is a full replacement — `entityAId` and `entityBId` are required. + * PUT is a full replacement — `userId` and `channelId` are required. */ - export type UpdateRelationshipProperties = { - /** First entity ID in the relationship. */ - entityAId: string; - /** Second entity ID in the relationship. */ - entityBId: string; + export type UpdateMembershipProperties = { + /** User ID reference. */ + userId: string; + /** Channel ID reference. */ + channelId: string; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload. */ @@ -9583,22 +10840,29 @@ declare namespace PubNub { }; /** - * Relationship resource as returned from the server. + * Membership resource as returned from the server. + * + * Note: server responses are shaped like a relationship — `entityAId` corresponds + * to `channelId` and `entityBId` corresponds to `userId`. */ - export type RelationshipObject = { + export type MembershipObject = { /** Unique identifier. */ id: string; - /** First entity ID in the relationship. */ + /** Channel ID (server returns this as `entityAId`). */ entityAId: string; - /** Second entity ID in the relationship. */ + /** User ID (server returns this as `entityBId`). */ entityBId: string; + /** Relationship class. */ + relationshipClass: string; + /** Version of the relationship class schema. */ + relationshipClassVersion: number; /** Lifecycle status. */ status?: string; /** User-defined JSON payload. */ payload?: Record; - /** Date and time the relationship was created (ISO 8601). */ + /** Date and time the membership was created (ISO 8601). */ createdAt: string; - /** Date and time the relationship was last updated (ISO 8601). */ + /** Date and time the membership was last updated (ISO 8601). */ updatedAt: string; /** Content fingerprint for optimistic concurrency control. */ eTag: string; @@ -9607,149 +10871,122 @@ declare namespace PubNub { }; /** - * Create Relationship request parameters. + * Create Membership request parameters. */ - export type CreateRelationshipParameters = { + export type CreateMembershipParameters = { /** - * Relationship properties to create. - * - * All relationship properties go inside `relationship` because they map to the request body envelope. + * Membership properties to create. */ - relationship: CreateRelationshipProperties & { + membership: CreateMembershipProperties & { /** - * Optional relationship ID. + * Optional membership ID. * Server auto-generates a UUID if not provided. */ id?: string; }; - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** - * Get Relationship request parameters. + * Get Membership request parameters. */ - export type GetRelationshipParameters = { - /** Relationship ID. */ + export type GetMembershipParameters = { + /** Membership ID. */ id: string; }; /** - * Get All Relationships request parameters. - * - * All parameters are optional — relationships can be listed without any filters. + * Get All Memberships request parameters. */ - export type GetAllRelationshipsParameters = PagedRequestParameters & { - /** Filter relationships by first entity ID. */ - entityAId?: string; - /** Filter relationships by second entity ID. */ - entityBId?: string; + export type GetAllMembershipsParameters = PagedRequestParameters & { + /** Filter memberships by user ID. */ + userId?: string; + /** Filter memberships by channel ID. */ + channelId?: string; + /** + * Schema version of the relationship class. + * If not provided, the server uses the latest version. + */ + relationshipClassVersion?: number; /** * Advanced filter expression for complex queries. - * - * Supports logical operators and nested conditions for sophisticated filtering - * beyond what the basic `filter` parameter provides. */ filterAdvanced?: string; }; /** - * Update Relationship request parameters (full replacement via PUT). + * Update Membership request parameters (full replacement via PUT). */ - export type UpdateRelationshipParameters = { - /** Relationship ID. */ + export type UpdateMembershipParameters = { + /** Membership ID. */ id: string; - /** Complete relationship properties for replacement. */ - relationship: UpdateRelationshipProperties; + /** Complete membership properties for replacement. */ + membership: UpdateMembershipProperties; /** * ETag for optimistic concurrency control. - * If provided, the update only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; }; /** - * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * Patch Membership request parameters (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * - * At least one of `set` or `remove` must be provided. + * At least one of `add`, `replace`, or `remove` must be provided. */ - export type PatchRelationshipParameters = { - /** Relationship ID. */ + export type PatchMembershipParameters = { + /** Membership ID. */ id: string; /** - * Fields to add or replace, using dot-notation keys. - * - * Each key is a dot-delimited path to the target field within `payload`. + * Fields to add, using dot-notation keys. + * The SDK converts these to JSON Patch "add" operations. + */ + add?: Record; + /** + * Fields to replace, using dot-notation keys. * The SDK converts these to JSON Patch "replace" operations. - * - * @example - * ```typescript - * set: { - * 'role': 'admin', - * 'permissions.read': true, - * } - * ``` */ - set?: Record; + replace?: Record; /** - * Array of dot-notation field paths to remove from `payload`. - * + * Array of dot-notation field paths to remove. * The SDK converts these to JSON Patch "remove" operations. - * - * @example - * ```typescript - * remove: ['tempFlag', 'legacyField'] - * ``` */ remove?: string[]; /** * ETag for optimistic concurrency control. - * If provided, the patch only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; - /** - * UUIDv4 idempotency key for safe retries. - * Auto-generated if not provided. - */ - idempotencyKey?: string; }; /** - * Remove Relationship request parameters. + * Remove Membership request parameters. */ - export type RemoveRelationshipParameters = { - /** Relationship ID. */ + export type RemoveMembershipParameters = { + /** Membership ID. */ id: string; /** * ETag for optimistic concurrency control. - * If provided, the delete only succeeds if the server's ETag matches. */ ifMatchesEtag?: string; }; - /** Response for creating a relationship. */ - export type CreateRelationshipResponse = DataSyncEntityResponse; + /** Response for creating a membership. */ + export type CreateMembershipResponse = DataSyncEntityResponse; - /** Response for getting a single relationship. */ - export type GetRelationshipResponse = DataSyncEntityResponse; + /** Response for getting a single membership. */ + export type GetMembershipResponse = DataSyncEntityResponse; - /** Response for listing relationships. */ - export type GetAllRelationshipsResponse = DataSyncPagedResponse; + /** Response for listing memberships. */ + export type GetAllMembershipsResponse = DataSyncPagedResponse; - /** Response for updating a relationship (PUT). */ - export type UpdateRelationshipResponse = DataSyncEntityResponse; + /** Response for updating a membership (PUT). */ + export type UpdateMembershipResponse = DataSyncEntityResponse; - /** Response for patching a relationship (PATCH). */ - export type PatchRelationshipResponse = DataSyncEntityResponse; + /** Response for patching a membership (PATCH). */ + export type PatchMembershipResponse = DataSyncEntityResponse; - /** Response for removing a relationship. */ - export type RemoveRelationshipResponse = { + /** Response for removing a membership. */ + export type RemoveMembershipResponse = { /** HTTP status code. */ status: number; }; From 7fa7586f82c5d44b6fc2e41a206f5d20fe51a5c6 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Thu, 23 Jul 2026 13:00:49 +0530 Subject: [PATCH 19/19] dist/lib updates --- dist/web/pubnub.js | 2009 +++++++++++++++-- dist/web/pubnub.min.js | 5 +- .../endpoints/data_sync/channel/create.js | 17 + .../endpoints/data_sync/channel/get-all.js | 17 + lib/core/endpoints/data_sync/channel/get.js | 17 + lib/core/endpoints/data_sync/channel/patch.js | 17 + .../endpoints/data_sync/channel/update.js | 17 + lib/core/endpoints/data_sync/entity/create.js | 17 + .../endpoints/data_sync/entity/get-all.js | 17 + lib/core/endpoints/data_sync/entity/get.js | 17 + lib/core/endpoints/data_sync/entity/patch.js | 17 + lib/core/endpoints/data_sync/entity/update.js | 17 + .../endpoints/data_sync/membership/create.js | 17 + .../endpoints/data_sync/membership/get-all.js | 17 + .../endpoints/data_sync/membership/get.js | 17 + .../endpoints/data_sync/membership/patch.js | 17 + .../endpoints/data_sync/membership/update.js | 19 + .../data_sync/relationship/create.js | 17 + .../data_sync/relationship/get-all.js | 17 + .../endpoints/data_sync/relationship/get.js | 17 + .../endpoints/data_sync/relationship/patch.js | 17 + .../data_sync/relationship/update.js | 17 + lib/core/endpoints/data_sync/user/create.js | 17 + lib/core/endpoints/data_sync/user/get-all.js | 17 + lib/core/endpoints/data_sync/user/get.js | 17 + lib/core/endpoints/data_sync/user/patch.js | 17 + lib/core/endpoints/data_sync/user/update.js | 17 + lib/types/index.d.ts | 18 +- 28 files changed, 2211 insertions(+), 248 deletions(-) diff --git a/dist/web/pubnub.js b/dist/web/pubnub.js index 0662472da..b5ca735d2 100644 --- a/dist/web/pubnub.js +++ b/dist/web/pubnub.js @@ -3741,6 +3741,78 @@ * Remove relationship REST API operation. */ RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + /** + * Create user REST API operation. + */ + RequestOperation["PNCreateUserOperation"] = "PNCreateUserOperation"; + /** + * Get user REST API operation. + */ + RequestOperation["PNGetUserOperation"] = "PNGetUserOperation"; + /** + * Get all users REST API operation. + */ + RequestOperation["PNGetAllUsersOperation"] = "PNGetAllUsersOperation"; + /** + * Update user REST API operation. + */ + RequestOperation["PNUpdateUserOperation"] = "PNUpdateUserOperation"; + /** + * Patch user REST API operation. + */ + RequestOperation["PNPatchUserOperation"] = "PNPatchUserOperation"; + /** + * Remove user REST API operation. + */ + RequestOperation["PNRemoveUserOperation"] = "PNRemoveUserOperation"; + /** + * Create channel REST API operation. + */ + RequestOperation["PNCreateChannelOperation"] = "PNCreateChannelOperation"; + /** + * Get channel REST API operation. + */ + RequestOperation["PNGetChannelOperation"] = "PNGetChannelOperation"; + /** + * Get all channels REST API operation. + */ + RequestOperation["PNGetAllChannelsOperation"] = "PNGetAllChannelsOperation"; + /** + * Update channel REST API operation. + */ + RequestOperation["PNUpdateChannelOperation"] = "PNUpdateChannelOperation"; + /** + * Patch channel REST API operation. + */ + RequestOperation["PNPatchChannelOperation"] = "PNPatchChannelOperation"; + /** + * Remove channel REST API operation. + */ + RequestOperation["PNRemoveChannelOperation"] = "PNRemoveChannelOperation"; + /** + * Create membership REST API operation. + */ + RequestOperation["PNCreateMembershipOperation"] = "PNCreateMembershipOperation"; + /** + * Get membership REST API operation. + */ + RequestOperation["PNGetMembershipOperation"] = "PNGetMembershipOperation"; + /** + * Get all memberships REST API operation. + */ + RequestOperation["PNGetAllMembershipsOperation"] = "PNGetAllMembershipsOperation"; + /** + * Update membership REST API operation. + */ + RequestOperation["PNUpdateMembershipOperation"] = "PNUpdateMembershipOperation"; + /** + * Patch membership REST API operation. + */ + RequestOperation["PNPatchMembershipOperation"] = "PNPatchMembershipOperation"; + /** + * Remove membership REST API operation. + */ + RequestOperation["PNRemoveMembershipOperation"] = "PNRemoveMembershipOperation"; // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- @@ -6624,7 +6696,31 @@ * Files event. */ PubNubEventType[PubNubEventType["Files"] = 4] = "Files"; + /** + * DataSync object change event. + * + * **Note:** Value must equal `5` to match the service wire value (`e: 5`). + */ + PubNubEventType[PubNubEventType["DataSync"] = 5] = "DataSync"; })(PubNubEventType || (PubNubEventType = {})); + /** + * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * + * NOTE: the exact wire `className` for typed User/Channel/Membership resources must be confirmed by + * running the `ds-event-test` spike against an origin that emits DataSync events. Keys are compared + * case-insensitively after `className.split(':').pop()`. Best-guess values are derived from the create + * content-types (`application/vnd.pubnub.objects.{user,channel,membership}+json`). + * + * @internal + */ + const DATA_SYNC_RESERVED_CLASSES = { + user: 'user', + channel: 'channel', + membership: 'membership', + pn_user: 'user', + pn_channel: 'channel', + pn_membership: 'membership', + }; // endregion /** * Base subscription request implementation. @@ -6732,6 +6828,13 @@ pn_mfp, }; } + else if (eventType === PubNubEventType.DataSync) { + const dataSync = this.dataSyncFromEnvelope(envelope); + // Guard: only treat as DataSync when the service marks it so; otherwise fall back to message. + if (dataSync) + return { type: PubNubEventType.DataSync, data: dataSync, pn_mfp }; + return { type: PubNubEventType.Message, data: this.messageFromEnvelope(envelope), pn_mfp }; + } return { type: PubNubEventType.Files, data: this.fileFromEnvelope(envelope), @@ -6837,6 +6940,53 @@ message: object, }; } + dataSyncFromEnvelope(envelope) { + var _a; + const [channel, subscription] = this.subscriptionChannelFromEnvelope(envelope); + const payload = envelope.d; + const metadata = payload === null || payload === void 0 ? void 0 : payload.metadata; + // Only treat the envelope as DataSync when the service marks it and carries the required fields. + if (!metadata || metadata.source !== 'data-sync' || !metadata.event || !metadata.type) + return undefined; + // Wire `className` is a positional composite `::`: + // - typed User/Channel/Membership → `User::` / `Channel::` / `Membership::` (system in 1st segment) + // - generic entity / relationship → `::Customer` / `::REQUESTED_BY` (developer in last segment) + // The reserved system class (1st segment) drives `objectType`; the surfaced `className` is the + // developer class (last non-empty segment) when present, else the system class. + const classSegments = metadata.className ? metadata.className.split(':') : []; + const systemClass = classSegments.length > 0 ? classSegments[0] : undefined; + const nonEmptySegments = classSegments.filter((segment) => segment.length > 0); + const className = nonEmptySegments.length > 0 ? nonEmptySegments[nonEmptySegments.length - 1] : undefined; + const objectType = (systemClass && DATA_SYNC_RESERVED_CLASSES[systemClass.toLowerCase()]) || metadata.type; + const parsedVersion = metadata.classVersion !== undefined ? Number.parseInt(`${metadata.classVersion}`, 10) : NaN; + const classVersion = Number.isNaN(parsedVersion) ? undefined : parsedVersion; + const raw = ((_a = payload.data) !== null && _a !== void 0 ? _a : {}); + let data; + if (metadata.event === 'delete') { + data = { id: raw.id, deletedAt: raw.deletedAt }; + } + else if (metadata.type === 'relationship') { + data = Object.assign(Object.assign({}, raw), { relationshipClass: className, relationshipClassVersion: classVersion }); + } + else { + data = Object.assign(Object.assign({}, raw), { entityClass: className, entityClassVersion: classVersion }); + } + return { + channel, + subscription, + timetoken: envelope.p.t, + message: { + version: payload.version, + event: metadata.event, + source: metadata.source, + type: metadata.type, + objectType, + className, + classVersion, + data, + }, + }; + } fileFromEnvelope(envelope) { const [channel, subscription] = this.subscriptionChannelFromEnvelope(envelope); const [file, decryptionError] = this.decryptedData(envelope.d); @@ -7021,6 +7171,15 @@ set onFile(listener) { this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'file' }); } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + this.updateTypeOrObjectListener({ add: !!listener, listener, type: 'dataSync' }); + } /** * Dispatch received a real-time update. * @@ -7063,6 +7222,8 @@ this.announce('messageAction', event.data); else if (event.type === PubNubEventType.Files) this.announce('file', event.data); + else if (event.type === PubNubEventType.DataSync) + this.announce('dataSync', event.data); } /** * Dispatch received connection status change. @@ -10530,6 +10691,15 @@ set onFile(listener) { this.eventDispatcher.onFile = listener; } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + this.eventDispatcher.onDataSync = listener; + } /** * Set events handler. * @@ -15437,50 +15607,54 @@ } /** - * Create Relationship REST API module. + * Create User REST API module. * * @internal */ // endregion /** - * Create Relationship request. + * Create User request. * * @internal */ - class CreateRelationshipRequest extends AbstractRequest { + class CreateUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.POST }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateRelationshipOperation; + return RequestOperation$1.PNCreateUserOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { - if (!this.parameters.relationship) - return 'Relationship cannot be empty'; - if (!this.parameters.relationship.entityAId) - return 'Entity A id cannot be empty'; - if (!this.parameters.relationship.entityBId) - return 'Entity B id cannot be empty'; + if (!this.parameters.user) + return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; } get headers() { var _a; - let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); - return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1' }); } get path() { const { keySet: { subscribeKey }, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships`; + return `/v1/datasync/subkeys/${subscribeKey}/users`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + return JSON.stringify({ data: this.parameters.user }); } } /** - * Get All Relationships REST API module. + * Get All Users REST API module. * * @internal */ @@ -15491,35 +15665,43 @@ /** * Default number of items per page. */ - const DEFAULT_LIMIT$1 = 20; + const DEFAULT_LIMIT$4 = 20; // endregion /** - * Get All Relationships request. + * Get All Users request. * * @internal */ - class GetAllRelationshipsRequest extends AbstractRequest { + class GetAllUsersRequest extends AbstractRequest { constructor(parameters) { var _a; super(); this.parameters = parameters; // Apply defaults. - (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$1); + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$4); } operation() { - return RequestOperation$1.PNGetAllRelationshipsOperation; + return RequestOperation$1.PNGetAllUsersOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } get path() { - return `/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`; } get queryParameters() { - const { entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Relationship REST API module. + * Update User REST API module. * * Full resource replacement via PUT. * @@ -15527,66 +15709,72 @@ */ // endregion /** - * Update Relationship request. + * Update User request. * * @internal */ - class UpdateRelationshipRequest extends AbstractRequest { + class UpdateUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateRelationshipOperation; + return RequestOperation$1.PNUpdateUserOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Relationship id cannot be empty'; - if (!this.parameters.relationship) - return 'Relationship cannot be empty'; - if (!this.parameters.relationship.entityAId) - return 'Entity A id cannot be empty'; - if (!this.parameters.relationship.entityBId) - return 'Entity B id cannot be empty'; + return 'User id cannot be empty'; + if (!this.parameters.user) + return 'User cannot be empty'; + if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + return 'Entity class version cannot be empty'; } get headers() { var _a; let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + return JSON.stringify({ data: this.parameters.user }); } } /** - * Remove Relationship REST API module. + * Remove User REST API module. * * @internal */ // endregion /** - * Remove Relationship request. + * Remove User request. * * @internal */ - class RemoveRelationshipRequest extends AbstractRequest { + class RemoveUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.DELETE }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveRelationshipOperation; + return RequestOperation$1.PNRemoveUserOperation; } validate() { if (!this.parameters.id) - return 'Relationship id cannot be empty'; + return 'User id cannot be empty'; } get headers() { var _a; @@ -15602,7 +15790,7 @@ } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; } } @@ -15623,20 +15811,26 @@ return '/' + dotPath.split('.').join('/'); } /** - * Convert `set` and `remove` parameters to JSON Patch operations (wire format). + * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). * - * - Each key in `set` becomes a "replace" operation. + * - Each key in `add` becomes an "add" operation. + * - Each key in `replace` becomes a "replace" operation. * - Each entry in `remove` becomes a "remove" operation. * * @internal */ - function toJsonPatchOperations(set, remove) { + function toJsonPatchOperations(add, replace, remove) { const ops = []; - if (set) { - for (const [dotPath, value] of Object.entries(set)) { + if (add) { + for (const [dotPath, value] of Object.entries(add)) { ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); } } + if (replace) { + for (const [dotPath, value] of Object.entries(replace)) { + ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); + } + } if (remove) { for (const dotPath of remove) { ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); @@ -15646,136 +15840,155 @@ } /** - * Patch Relationship REST API module. + * Patch User REST API module. * * Partial update via JSON Patch (RFC 6902). - * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) - * and converts them to JSON Patch operations on the wire. + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. * * @internal */ // endregion /** - * Patch Relationship request. + * Patch User request. * * @internal */ - class PatchRelationshipRequest extends AbstractRequest { + class PatchUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchRelationshipOperation; + return RequestOperation$1.PNPatchUserOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Relationship id cannot be empty'; - const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + return 'User id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; - if (!hasSet && !hasRemove) - return 'At least one of set or remove must be provided'; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; } get headers() { var _a; let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; } get body() { // Prefix all field paths with 'payload.' so users write simple field names - // (e.g., 'role') and the SDK produces '/payload/role' on the wire. - const prefixedSet = this.parameters.set - ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) - : undefined; + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; - // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). - const jsonPatchOps = toJsonPatchOperations(prefixedSet, prefixedRemove); + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); return JSON.stringify(jsonPatchOps); } } /** - * Get Relationship REST API module. + * Get User REST API module. * * @internal */ // endregion /** - * Get Relationship request. + * Get User request. * * @internal */ - class GetRelationshipRequest extends AbstractRequest { + class GetUserRequest extends AbstractRequest { constructor(parameters) { super(); this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetRelationshipOperation; + return RequestOperation$1.PNGetUserOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Relationship id cannot be empty'; + return 'User id cannot be empty'; } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; } } /** - * Create Entity REST API module. + * Create Channel REST API module. * * @internal */ // endregion /** - * Create Entity request. + * Create Channel request. * * @internal */ - class CreateEntityRequest extends AbstractRequest { + class CreateChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.POST }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateEntityOperation; + return RequestOperation$1.PNCreateChannelOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { - if (!this.parameters.entity) - return 'Entity cannot be empty'; - if (!this.parameters.entity.entityClass) - return 'Entity class cannot be empty'; - if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + if (!this.parameters.channel) + return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) return 'Entity class version cannot be empty'; } get headers() { var _a; - let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); - return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1' }); } get path() { const { keySet: { subscribeKey }, } = this.parameters; - return `/subkeys/${subscribeKey}/entities`; + return `/v1/datasync/subkeys/${subscribeKey}/channels`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + return JSON.stringify({ data: this.parameters.channel }); } } /** - * Get All Entities REST API module. + * Get All Channels REST API module. * * @internal */ @@ -15786,65 +15999,76 @@ /** * Default number of items per page. */ - const DEFAULT_LIMIT = 20; + const DEFAULT_LIMIT$3 = 20; // endregion /** - * Get All Entities request. + * Get All Channels request. * * @internal */ - class GetAllEntitiesRequest extends AbstractRequest { + class GetAllChannelsRequest extends AbstractRequest { constructor(parameters) { var _a; super(); this.parameters = parameters; // Apply defaults. - (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$3); } operation() { - return RequestOperation$1.PNGetAllEntitiesOperation; + return RequestOperation$1.PNGetAllChannelsOperation; } - validate() { - if (!this.parameters.entityClass) - return 'Entity class cannot be empty'; + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } get path() { - return `/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`; } get queryParameters() { - const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; - return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ entity_class: entityClass }, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Entity REST API module. + * Update Channel REST API module. * * Full resource replacement via PUT. - * Note: `entityClass` is immutable and cannot be changed via update. * * @internal */ // endregion /** - * Update Entity request. + * Update Channel request. * * @internal */ - class UpdateEntityRequest extends AbstractRequest { + class UpdateChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateEntityOperation; + return RequestOperation$1.PNUpdateChannelOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Entity id cannot be empty'; - if (!this.parameters.entity) - return 'Entity cannot be empty'; - if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Channel id cannot be empty'; + if (!this.parameters.channel) + return 'Channel cannot be empty'; + if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) return 'Entity class version cannot be empty'; } get headers() { @@ -15852,39 +16076,39 @@ let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + return JSON.stringify({ data: this.parameters.channel }); } } /** - * Remove Entity REST API module. + * Remove Channel REST API module. * * @internal */ // endregion /** - * Remove Entity request. + * Remove Channel request. * * @internal */ - class RemoveEntityRequest extends AbstractRequest { + class RemoveChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.DELETE }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveEntityOperation; + return RequestOperation$1.PNRemoveChannelOperation; } validate() { if (!this.parameters.id) - return 'Entity id cannot be empty'; + return 'Channel id cannot be empty'; } get headers() { var _a; @@ -15900,381 +16124,1680 @@ } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; } } /** - * Patch Entity REST API module. + * Patch Channel REST API module. * * Partial update via JSON Patch (RFC 6902). - * Accepts `set` (dot-notation key-value pairs) and `remove` (dot-notation paths) - * and converts them to JSON Patch operations on the wire. + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. * * @internal */ // endregion /** - * Patch Entity request. + * Patch Channel request. * * @internal */ - class PatchEntityRequest extends AbstractRequest { + class PatchChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchEntityOperation; + return RequestOperation$1.PNPatchChannelOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Entity id cannot be empty'; - const hasSet = this.parameters.set && Object.keys(this.parameters.set).length > 0; + return 'Channel id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; - if (!hasSet && !hasRemove) - return 'At least one of set or remove must be provided'; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; } get headers() { var _a; let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; if (this.parameters.ifMatchesEtag) headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); - if (this.parameters.idempotencyKey) - headers = Object.assign(Object.assign({}, headers), { 'Idempotency-Key': this.parameters.idempotencyKey }); return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; } get body() { // Prefix all field paths with 'payload.' so users write simple field names - // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. - const prefixedSet = this.parameters.set - ? Object.fromEntries(Object.entries(this.parameters.set).map(([key, value]) => [`payload.${key}`, value])) - : undefined; + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; - // Convert set/remove (dot notation) to JSON Patch operations (JSON Pointer notation). - const jsonPatchOps = toJsonPatchOperations(prefixedSet, prefixedRemove); + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); return JSON.stringify(jsonPatchOps); } } /** - * Get Entity REST API module. + * Get Channel REST API module. * * @internal */ // endregion /** - * Get Entity request. + * Get Channel request. * * @internal */ - class GetEntityRequest extends AbstractRequest { + class GetChannelRequest extends AbstractRequest { constructor(parameters) { super(); this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetEntityOperation; + return RequestOperation$1.PNGetChannelOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); } validate() { if (!this.parameters.id) - return 'Entity id cannot be empty'; + return 'Channel id cannot be empty'; } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; - return `/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; } } /** - * PubNub DataSync API module. + * Create Membership REST API module. + * + * @internal */ + // endregion /** - * PubNub DataSync API interface. + * Create Membership request. + * + * @internal */ - class PubNubDataSync { - /** - * Create DataSync API access object. - * - * @param configuration - Extended PubNub client configuration object. - * @param sendRequest - Function which should be used to send REST API calls. - * - * @internal - */ - constructor(configuration, - /* eslint-disable @typescript-eslint/no-explicit-any */ - sendRequest) { - this.keySet = configuration.keySet; - this.configuration = configuration; - this.sendRequest = sendRequest; + class CreateMembershipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; } - /** - * Get registered loggers' manager. - * - * @returns Registered loggers' manager. - * - * @internal - */ - get logger() { - return this.configuration.logger(); + operation() { + return RequestOperation$1.PNCreateMembershipOperation; } - /** - * Create a new Entity. - * - * @param parameters - Request configuration parameters. - * @param [callback] - Request completion handler callback. - * + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.membership) + return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) + return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) + return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) + return 'Relationship class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships`; + } + get body() { + return JSON.stringify({ data: this.parameters.membership }); + } + } + + /** + * Get All Memberships REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Default number of items per page. + */ + const DEFAULT_LIMIT$2 = 20; + // endregion + /** + * Get All Memberships request. + * + * @internal + */ + class GetAllMembershipsRequest extends AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$2); + } + operation() { + return RequestOperation$1.PNGetAllMembershipsOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`; + } + get queryParameters() { + const { userId, channelId, relationshipClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (userId ? { user_id: userId } : {})), (channelId ? { channel_id: channelId } : {})), (relationshipClassVersion !== undefined ? { relationship_class_version: `${relationshipClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } + } + + /** + * Update Membership REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + // endregion + /** + * Update Membership request. + * + * @internal + */ + class UpdateMembershipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNUpdateMembershipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + if (!this.parameters.membership) + return 'Membership cannot be empty'; + if (!this.parameters.membership.userId) + return 'User id cannot be empty'; + if (!this.parameters.membership.channelId) + return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) + return 'Relationship class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.membership+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.membership }); + } + } + + /** + * Remove Membership REST API module. + * + * @internal + */ + // endregion + /** + * Remove Membership request. + * + * @internal + */ + class RemoveMembershipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNRemoveMembershipOperation; + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + } + + /** + * Patch Membership REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + // endregion + /** + * Patch Membership request. + * + * @internal + */ + class PatchMembershipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNPatchMembershipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // and the SDK produces '/payload/' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } + } + + /** + * Get Membership REST API module. + * + * @internal + */ + // endregion + /** + * Get Membership request. + * + * @internal + */ + class GetMembershipRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetMembershipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Membership id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; + } + } + + /** + * Create Relationship REST API module. + * + * @internal + */ + // endregion + /** + * Create Relationship request. + * + * @internal + */ + class CreateRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNCreateRelationshipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + if (!this.parameters.relationship.relationshipClass) + return 'Relationship class cannot be empty'; + if (!this.parameters.relationship.relationshipClassVersion) + return 'Relationship class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/relationships`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); + } + } + + /** + * Get All Relationships REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Default number of items per page. + */ + const DEFAULT_LIMIT$1 = 20; + // endregion + /** + * Get All Relationships request. + * + * @internal + */ + class GetAllRelationshipsRequest extends AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$1); + } + operation() { + return RequestOperation$1.PNGetAllRelationshipsOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.relationshipClass) + return 'Relationship class cannot be empty'; + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/relationships`; + } + get queryParameters() { + const { relationshipClass, relationshipClassVersion, entityAId, entityBId, cursor, limit, filter, sort, filterAdvanced, } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ relationship_class: relationshipClass }, (relationshipClassVersion !== undefined ? { relationship_class_version: `${relationshipClassVersion}` } : {})), (entityAId ? { entity_a_id: entityAId } : {})), (entityBId ? { entity_b_id: entityBId } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } + } + + /** + * Update Relationship REST API module. + * + * Full resource replacement via PUT. + * + * @internal + */ + // endregion + /** + * Update Relationship request. + * + * @internal + */ + class UpdateRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNUpdateRelationshipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + if (!this.parameters.relationship) + return 'Relationship cannot be empty'; + if (!this.parameters.relationship.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.relationship.entityBId) + return 'Entity B id cannot be empty'; + if (!this.parameters.relationship.relationshipClassVersion) + return 'Relationship class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.relationship+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.relationship }); + } + } + + /** + * Remove Relationship REST API module. + * + * @internal + */ + // endregion + /** + * Remove Relationship request. + * + * @internal + */ + class RemoveRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNRemoveRelationshipOperation; + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + } + + /** + * Patch Relationship REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + // endregion + /** + * Patch Relationship request. + * + * @internal + */ + class PatchRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNPatchRelationshipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'role') and the SDK produces '/payload/role' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } + } + + /** + * Get Relationship REST API module. + * + * @internal + */ + // endregion + /** + * Get Relationship request. + * + * @internal + */ + class GetRelationshipRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetRelationshipOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Relationship id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; + } + } + + /** + * Create Entity REST API module. + * + * @internal + */ + // endregion + /** + * Create Entity request. + * + * @internal + */ + class CreateEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.POST }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNCreateEntityOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (!this.parameters.entity.entityClass) + return 'Entity class cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + const headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/entities`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } + } + + /** + * Get All Entities REST API module. + * + * @internal + */ + // -------------------------------------------------------- + // ----------------------- Defaults ----------------------- + // -------------------------------------------------------- + // region Defaults + /** + * Default number of items per page. + */ + const DEFAULT_LIMIT = 20; + // endregion + /** + * Get All Entities request. + * + * @internal + */ + class GetAllEntitiesRequest extends AbstractRequest { + constructor(parameters) { + var _a; + super(); + this.parameters = parameters; + // Apply defaults. + (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); + } + operation() { + return RequestOperation$1.PNGetAllEntitiesOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.entityClass) + return 'Entity class cannot be empty'; + } + get path() { + return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/entities`; + } + get queryParameters() { + const { entityClass, entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ entity_class: entityClass }, (entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {})), (cursor ? { cursor } : {})), (limit ? { limit: `${limit}` } : {})), (filter ? { filter } : {})), (sort ? { sort } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); + } + } + + /** + * Update Entity REST API module. + * + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. + * + * @internal + */ + // endregion + /** + * Update Entity request. + * + * @internal + */ + class UpdateEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNUpdateEntityOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + if (!this.parameters.entity) + return 'Entity cannot be empty'; + if (this.parameters.entity.entityClassVersion === undefined || this.parameters.entity.entityClassVersion === null) + return 'Entity class version cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + get body() { + return JSON.stringify({ data: this.parameters.entity }); + } + } + + /** + * Remove Entity REST API module. + * + * @internal + */ + // endregion + /** + * Remove Entity request. + * + * @internal + */ + class RemoveEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.DELETE }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNRemoveEntityOperation; + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.keys(headers).length > 0 ? headers : undefined; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + return { status: response.status }; + }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + } + + /** + * Patch Entity REST API module. + * + * Partial update via JSON Patch (RFC 6902). + * Accepts `add` and `replace` (dot-notation key-value pairs) and `remove` + * (dot-notation paths) and converts them to JSON Patch operations on the wire. + * + * @internal + */ + // endregion + /** + * Patch Entity request. + * + * @internal + */ + class PatchEntityRequest extends AbstractRequest { + constructor(parameters) { + super({ method: TransportMethod.PATCH }); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNPatchEntityOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + const hasAdd = this.parameters.add && Object.keys(this.parameters.add).length > 0; + const hasReplace = this.parameters.replace && Object.keys(this.parameters.replace).length > 0; + const hasRemove = this.parameters.remove && this.parameters.remove.length > 0; + if (!hasAdd && !hasReplace && !hasRemove) + return 'At least one of add, replace, or remove must be provided'; + } + get headers() { + var _a; + let headers = (_a = super.headers) !== null && _a !== void 0 ? _a : {}; + if (this.parameters.ifMatchesEtag) + headers = Object.assign(Object.assign({}, headers), { 'If-Match': this.parameters.ifMatchesEtag }); + return Object.assign(Object.assign({}, headers), { 'Content-Type': 'application/json-patch+json' }); + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + get body() { + // Prefix all field paths with 'payload.' so users write simple field names + // (e.g., 'standards') and the SDK produces '/payload/standards' on the wire. + const prefixWithPayload = (input) => Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const prefixedAdd = this.parameters.add ? prefixWithPayload(this.parameters.add) : undefined; + const prefixedReplace = this.parameters.replace ? prefixWithPayload(this.parameters.replace) : undefined; + const prefixedRemove = this.parameters.remove ? this.parameters.remove.map((key) => `payload.${key}`) : undefined; + // Convert add/replace/remove (dot notation) to JSON Patch operations (JSON Pointer notation). + const jsonPatchOps = toJsonPatchOperations(prefixedAdd, prefixedReplace, prefixedRemove); + return JSON.stringify(jsonPatchOps); + } + } + + /** + * Get Entity REST API module. + * + * @internal + */ + // endregion + /** + * Get Entity request. + * + * @internal + */ + class GetEntityRequest extends AbstractRequest { + constructor(parameters) { + super(); + this.parameters = parameters; + } + operation() { + return RequestOperation$1.PNGetEntityOperation; + } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } + validate() { + if (!this.parameters.id) + return 'Entity id cannot be empty'; + } + get path() { + const { keySet: { subscribeKey }, id, } = this.parameters; + return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; + } + } + + /** + * PubNub DataSync API module. + */ + /** + * PubNub DataSync API interface. + */ + class PubNubDataSync { + /** + * Create DataSync API access object. + * + * @param configuration - Extended PubNub client configuration object. + * @param sendRequest - Function which should be used to send REST API calls. + * + * @internal + */ + constructor(configuration, + /* eslint-disable @typescript-eslint/no-explicit-any */ + sendRequest) { + this.keySet = configuration.keySet; + this.configuration = configuration; + this.sendRequest = sendRequest; + } + /** + * Get registered loggers' manager. + * + * @returns Registered loggers' manager. + * + * @internal + */ + get logger() { + return this.configuration.logger(); + } + /** + * Create a new Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * * @returns Asynchronous create entity response or `void` in case if `callback` provided. */ - createEntity(parameters, callback) { + createEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Entity with parameters:', + })); + const request = new CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get entity response or `void` in case if `callback` provided. + */ + getEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Entity with parameters:', + })); + const request = new GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Entities for a given Entity Class. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all entities response or `void` in case if `callback` provided. + */ + getAllEntities(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Entities with parameters:', + })); + const request = new GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update an Entity (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update entity response or `void` in case if `callback` provided. + */ + updateEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Entity with parameters:', + })); + const request = new UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch an Entity (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch entity response or `void` in case if `callback` provided. + */ + patchEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Entity with parameters:', + })); + const request = new PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove an Entity. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove entity response or `void` in case if `callback` provided. + */ + removeEntity(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Entity with parameters:', + })); + const request = new RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create relationship response or `void` in case if `callback` provided. + */ + createRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Relationship with parameters:', + })); + const request = new CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Relationship. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get relationship response or `void` in case if `callback` provided. + */ + getRelationship(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Relationship with parameters:', + })); + const request = new GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Relationships. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + */ + getAllRelationships(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Create Entity with parameters:', + details: 'Get all Relationships with parameters:', })); - const request = new CreateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Fetch a specific Entity. + * Update a Relationship (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get entity response or `void` in case if `callback` provided. + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. */ - getEntity(parameters, callback) { + updateRelationship(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get Entity with parameters:', + details: 'Update Relationship with parameters:', })); - const request = new GetEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Fetch a paginated list of Entities for a given Entity Class. + * Patch a Relationship (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get all entities response or `void` in case if `callback` provided. + * @returns Asynchronous patch relationship response or `void` in case if `callback` provided. */ - getAllEntities(parameters, callback) { + patchRelationship(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get all Entities with parameters:', + details: 'Patch Relationship with parameters:', })); - const request = new GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Update an Entity (full replacement via PUT). + * Remove a Relationship. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous update entity response or `void` in case if `callback` provided. + * @returns Asynchronous remove relationship response or `void` in case if `callback` provided. */ - updateEntity(parameters, callback) { + removeRelationship(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Update Entity with parameters:', + details: 'Remove Relationship with parameters:', })); - const request = new UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Create a new User. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. * - * Uses `set` and `remove` with dot-notation field paths. + * @returns Asynchronous create user response or `void` in case if `callback` provided. + */ + createUser(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create User with parameters:', + })); + const request = new CreateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific User. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous patch entity response or `void` in case if `callback` provided. + * @returns Asynchronous get user response or `void` in case if `callback` provided. */ - patchEntity(parameters, callback) { + getUser(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Patch Entity with parameters:', + details: 'Get User with parameters:', })); - const request = new PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Remove an Entity. + * Fetch a paginated list of Users. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all users response or `void` in case if `callback` provided. + */ + getAllUsers(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Users with parameters:', + })); + const request = new GetAllUsersRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a User (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous remove entity response or `void` in case if `callback` provided. + * @returns Asynchronous update user response or `void` in case if `callback` provided. */ - removeEntity(parameters, callback) { + updateUser(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Remove Entity with parameters:', + details: 'Update User with parameters:', })); - const request = new RemoveEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new UpdateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Create a new Relationship. + * Patch a User (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous create relationship response or `void` in case if `callback` provided. + * @returns Asynchronous patch user response or `void` in case if `callback` provided. */ - createRelationship(parameters, callback) { + patchUser(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Create Relationship with parameters:', + details: 'Patch User with parameters:', })); - const request = new CreateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new PatchUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Fetch a specific Relationship. + * Remove a User. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get relationship response or `void` in case if `callback` provided. + * @returns Asynchronous remove user response or `void` in case if `callback` provided. */ - getRelationship(parameters, callback) { + removeUser(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get Relationship with parameters:', + details: 'Remove User with parameters:', })); - const request = new GetRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new RemoveUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Fetch a paginated list of Relationships. + * Create a new Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create channel response or `void` in case if `callback` provided. + */ + createChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Channel with parameters:', + })); + const request = new CreateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Channel. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get channel response or `void` in case if `callback` provided. + */ + getChannel(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Channel with parameters:', + })); + const request = new GetChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Channels. * * @param [parametersOrCallback] - Request configuration parameters or callback from overload. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + * @returns Asynchronous get all channels response or `void` in case if `callback` provided. */ - getAllRelationships(parametersOrCallback, callback) { + getAllChannels(parametersOrCallback, callback) { return __awaiter(this, void 0, void 0, function* () { const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get all Relationships with parameters:', + details: 'Get all Channels with parameters:', })); - const request = new GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetAllChannelsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Update a Relationship (full replacement via PUT). + * Update a Channel (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous update relationship response or `void` in case if `callback` provided. + * @returns Asynchronous update channel response or `void` in case if `callback` provided. */ - updateRelationship(parameters, callback) { + updateChannel(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Update Relationship with parameters:', + details: 'Update Channel with parameters:', })); - const request = new UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new UpdateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Patch a Channel (partial update via JSON Patch RFC 6902). * - * Uses `set` and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with dot-notation field paths. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous patch relationship response or `void` in case if `callback` provided. + * @returns Asynchronous patch channel response or `void` in case if `callback` provided. */ - patchRelationship(parameters, callback) { + patchChannel(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Patch Relationship with parameters:', + details: 'Patch Channel with parameters:', })); - const request = new PatchRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new PatchChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); }); } /** - * Remove a Relationship. + * Remove a Channel. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous remove relationship response or `void` in case if `callback` provided. + * @returns Asynchronous remove channel response or `void` in case if `callback` provided. */ - removeRelationship(parameters, callback) { + removeChannel(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Remove Relationship with parameters:', + details: 'Remove Channel with parameters:', })); - const request = new RemoveRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new RemoveChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Create a new Membership (associates a User with a Channel). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous create membership response or `void` in case if `callback` provided. + */ + createMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Create Membership with parameters:', + })); + const request = new CreateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a specific Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get membership response or `void` in case if `callback` provided. + */ + getMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get Membership with parameters:', + })); + const request = new GetMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Fetch a paginated list of Memberships. + * + * @param [parametersOrCallback] - Request configuration parameters or callback from overload. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous get all memberships response or `void` in case if `callback` provided. + */ + getAllMemberships(parametersOrCallback, callback) { + return __awaiter(this, void 0, void 0, function* () { + const parameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; + callback !== null && callback !== void 0 ? callback : (callback = typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined); + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Get all Memberships with parameters:', + })); + const request = new GetAllMembershipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Update a Membership (full replacement via PUT). + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous update membership response or `void` in case if `callback` provided. + */ + updateMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Update Membership with parameters:', + })); + const request = new UpdateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Patch a Membership (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous patch membership response or `void` in case if `callback` provided. + */ + patchMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Patch Membership with parameters:', + })); + const request = new PatchMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + if (callback) + return this.sendRequest(request, callback); + return this.sendRequest(request); + }); + } + /** + * Remove a Membership. + * + * @param parameters - Request configuration parameters. + * @param [callback] - Request completion handler callback. + * + * @returns Asynchronous remove membership response or `void` in case if `callback` provided. + */ + removeMembership(parameters, callback) { + return __awaiter(this, void 0, void 0, function* () { + this.logger.debug('PubNub', () => ({ + messageType: 'object', + message: Object.assign({}, parameters), + details: 'Remove Membership with parameters:', + })); + const request = new RemoveMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -19101,6 +20624,18 @@ this.eventDispatcher.onFile = listener; } } + /** + * Set a new DataSync event handler. + * + * @param listener - Listener function, which will be called each time when a new + * DataSync event is received from the real-time network. + */ + set onDataSync(listener) { + { + if (this.eventDispatcher) + this.eventDispatcher.onDataSync = listener; + } + } /** * Set events handler. * diff --git a/dist/web/pubnub.min.js b/dist/web/pubnub.min.js index d0e662350..d077c5445 100644 --- a/dist/web/pubnub.min.js +++ b/dist/web/pubnub.min.js @@ -1,3 +1,2 @@ - -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),h(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function y(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var m=function e(){var r,d,m=l(),f=m>>5,v=31&m;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=h(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)w+=d,S.push(u(d));var O=new Uint8Array(w),k=0;for(r=0;r=0;)y(C,d);else y(C,d);return String.fromCharCode.apply(null,C);case 4:var P;if(d<0)for(P=[];!p();)P.push(e());else for(P=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,l,h;for(let e=0;e>18,c=(258048&h)>>12,u=(4032&h)>>6,l=63&h,t+=s[o]+s[c]+s[u]+s[l];return 1==i?(h=n[a],o=(252&h)>>2,c=(3&h)<<4,t+=s[o]+s[c]+"=="):2==i&&(h=n[a]<<8|n[a+1],o=(64512&h)>>10,c=(1008&h)>>4,u=(15&h)<<2,t+=s[o]+s[c]+s[u]+"="),t}var l;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNServerErrorCategory="PNServerErrorCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory",e.PNSharedWorkerUpdatedCategory="PNSharedWorkerUpdatedCategory"}(l||(l={}));var h=l;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),h.PNMalformedResponseCategory)}var b,y,m,f,v,S=S||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},l=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var l;e:{l=c;for(var h=e.sqrt(l),d=2;d<=h;d++)if(!(l%d)){l=!1;break e}l=!0}l&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],l=s[6],h=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=h+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&l)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),h=l,l=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+l|0,s[7]=s[7]+h|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),y=(b=S).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=y.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=S,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],l=0;64>l;l++)u[l]=4294967296*e.abs(e.sin(l+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],l=(o=e[i+1],e[i+2]),h=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],y=e[i+8],m=e[i+9],f=e[i+10],v=e[i+11],S=e[i+12],w=e[i+13],O=e[i+14],k=e[i+15],C=t(C=a[0],E=a[1],j=a[2],P=a[3],c,7,u[0]),P=t(P,C,E,j,o,12,u[1]),j=t(j,P,C,E,l,17,u[2]),E=t(E,j,P,C,h,22,u[3]);C=t(C,E,j,P,d,7,u[4]),P=t(P,C,E,j,p,12,u[5]),j=t(j,P,C,E,g,17,u[6]),E=t(E,j,P,C,b,22,u[7]),C=t(C,E,j,P,y,7,u[8]),P=t(P,C,E,j,m,12,u[9]),j=t(j,P,C,E,f,17,u[10]),E=t(E,j,P,C,v,22,u[11]),C=t(C,E,j,P,S,7,u[12]),P=t(P,C,E,j,w,12,u[13]),j=t(j,P,C,E,O,17,u[14]),C=s(C,E=t(E,j,P,C,k,22,u[15]),j,P,o,5,u[16]),P=s(P,C,E,j,g,9,u[17]),j=s(j,P,C,E,v,14,u[18]),E=s(E,j,P,C,c,20,u[19]),C=s(C,E,j,P,p,5,u[20]),P=s(P,C,E,j,f,9,u[21]),j=s(j,P,C,E,k,14,u[22]),E=s(E,j,P,C,d,20,u[23]),C=s(C,E,j,P,m,5,u[24]),P=s(P,C,E,j,O,9,u[25]),j=s(j,P,C,E,h,14,u[26]),E=s(E,j,P,C,y,20,u[27]),C=s(C,E,j,P,w,5,u[28]),P=s(P,C,E,j,l,9,u[29]),j=s(j,P,C,E,b,14,u[30]),C=n(C,E=s(E,j,P,C,S,20,u[31]),j,P,p,4,u[32]),P=n(P,C,E,j,y,11,u[33]),j=n(j,P,C,E,v,16,u[34]),E=n(E,j,P,C,O,23,u[35]),C=n(C,E,j,P,o,4,u[36]),P=n(P,C,E,j,d,11,u[37]),j=n(j,P,C,E,b,16,u[38]),E=n(E,j,P,C,f,23,u[39]),C=n(C,E,j,P,w,4,u[40]),P=n(P,C,E,j,c,11,u[41]),j=n(j,P,C,E,h,16,u[42]),E=n(E,j,P,C,g,23,u[43]),C=n(C,E,j,P,m,4,u[44]),P=n(P,C,E,j,S,11,u[45]),j=n(j,P,C,E,k,16,u[46]),C=r(C,E=n(E,j,P,C,l,23,u[47]),j,P,c,6,u[48]),P=r(P,C,E,j,b,10,u[49]),j=r(j,P,C,E,O,15,u[50]),E=r(E,j,P,C,p,21,u[51]),C=r(C,E,j,P,S,6,u[52]),P=r(P,C,E,j,h,10,u[53]),j=r(j,P,C,E,f,15,u[54]),E=r(E,j,P,C,o,21,u[55]),C=r(C,E,j,P,y,6,u[56]),P=r(P,C,E,j,k,10,u[57]),j=r(j,P,C,E,g,15,u[58]),E=r(E,j,P,C,w,21,u[59]),C=r(C,E,j,P,d,6,u[60]),P=r(P,C,E,j,v,10,u[61]),j=r(j,P,C,E,l,15,u[62]),E=r(E,j,P,C,m,21,u[63]);a[0]=a[0]+C|0,a[1]=a[1]+E|0,a[2]=a[2]+j|0,a[3]=a[3]+P|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=S,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var l=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),h=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return l.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,l.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,l.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=h.extend({cfg:h.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=h.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,h.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=S,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],l=[],h=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,y=0;for(g=0;256>g;g++){var m=(m=y^y<<1^y<<2^y<<3^y<<4)>>>8^255&m^99;n[b]=m,r[m]=b;var f=p[b],v=p[f],w=p[v],O=257*p[m]^16843008*m;i[b]=O<<24|O>>>8,a[b]=O<<16|O>>>16,o[b]=O<<8|O>>>24,c[b]=O,O=16843009*w^65537*v^257*f^16843008*b,u[m]=O<<24|O>>>8,l[m]=O<<16|O>>>16,h[m]=O<<8|O>>>24,d[m]=O,b?(b=f^p[p[p[w^f]]],y^=p[p[y]]):b=y=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^l[n[a>>>16&255]]^h[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,l,h,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],l=e[t+1]^s[1],h=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[l>>>16&255]^i[h>>>8&255]^a[255&d]^s[p++],y=n[l>>>24]^r[h>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],m=n[h>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&l]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[l>>>8&255]^a[255&h]^s[p++],u=b,l=y,h=m}b=(o[u>>>24]<<24|o[l>>>16&255]<<16|o[h>>>8&255]<<8|o[255&d])^s[p++],y=(o[l>>>24]<<24|o[h>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],m=(o[h>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&l])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[l>>>8&255]<<8|o[255&h])^s[p++],e[t]=b,e[t+1]=y,e[t+2]=m,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),S.mode.ECB=((v=S.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var w=t(S);class O{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=w,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:O.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return O.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(O.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=O.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;sk.has(e),P=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),j=(e,t)=>{const s=e.map((e=>P(e)));return s.length?s.join(","):null!=t?t:""},E=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},N=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),T=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${P(e)}`)).join("&"):`${t}=${P(s)}`})).join("&"),_=(e,t)=>{if("0"===t||"0"===e)return;const s=M(`${Date.now()}0000`,t,!1);return M(e,s,!0)},I=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=M(e,t,!1);return M(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},M=(e,t,s)=>{t.startsWith("-")&&(t=t.replace("-",""),s=!1),t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0?o>0?(o-=1,c+=1e7):o<0&&(c*=-1):o<0&&c>0&&(o+=1,c=1e7-c),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},A=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};function U(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e||C(e)})))}get logger(){return this._logger}HMACSHA256(e){return w.HmacSHA256(e,this.configuration.secretKey).toString(w.enc.Base64)}SHA256(e){return w.SHA256(e).toString(w.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e},null!=s?s:{}),details:"Encrypt with parameters:",ignoredKeys:C}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=w.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(w.enc.Base64)}const a=this.getIV(s);return w.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(w.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e},null!=s?s:{}),details:"Decrypt with parameters:",ignoredKeys:C}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=U(t.slice(0,16)),n=U(t.slice(16));try{const e=w.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(w.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=w.enc.Base64.parse(e),n=w.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(w.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?w.enc.Base64.parse(e):"hex"===t.keyEncoding?w.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?w.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?w.mode.ECB:w.mode.CBC}getIV(e){return"cbc"===e.mode?w.enc.Utf8.parse(this.iv):null}getRandomIV(){return w.lib.WordArray.random(16)}}class R{encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=R.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return R.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice(R.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(R.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=R.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return R.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",R.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=R.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}R.IV_LENGTH=16,R.encoder=new TextEncoder,R.decoder=new TextDecoder;class ${constructor(e){this.config=e,this.cryptor=new D(Object.assign({},e)),this.fileCryptor=new R}set logger(e){this.cryptor.logger=e,!1===this.config.useRandomIVs&&e.warn("LegacyCryptor","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")}encrypt(e){const t="string"==typeof e?e:$.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`LegacyCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||C(t)||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}$.encoder=new TextEncoder,$.decoder=new TextDecoder;class F extends a{set logger(e){if(this.defaultCryptor.identifier===F.LEGACY_IDENTIFIER)e.warn("CryptoModule","'legacyCryptoModule' is deprecated. Use 'aesCbcCryptoModule' instead for new applications."),this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===F.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return e.logger&&(e.logger.warn("CryptoModule","'legacyCryptoModule' is deprecated. Use 'aesCbcCryptoModule' instead for new applications."),!1===e.useRandomIVs&&e.logger.warn("CryptoModule","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")),new F({default:new $(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new O({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new F({default:new O({cipherKey:e.cipherKey}),cryptors:[new $(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===F.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(F.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===x.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=x.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=x.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===x.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof L)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=x.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}F.LEGACY_IDENTIFIER="";class x{static from(e,t){if(e!==x.LEGACY_IDENTIFIER)return new L(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==x.SENTINEL))return F.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>x.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+x.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new L(this.decoder.decode(n),a)}}x.SENTINEL="PNED",x.LEGACY_IDENTIFIER="",x.IDENTIFIER_LENGTH=4,x.VERSION=1,x.MAX_VERSION=1,x.decoder=new TextDecoder;class L{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return x.VERSION}get length(){return x.SENTINEL.length+1+x.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(x.SENTINEL)),e+=x.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=x.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}L.IDENTIFIER_LENGTH=4,L.SENTINEL="PNED";class q extends Error{static create(e,t){return q.isErrorObject(e)?q.createFromError(e):q.createFromServiceResponse(e,t)}static createFromError(e){let t=h.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new q(s,t,0);if(e instanceof q)return e;if(q.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=h.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=h.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=h.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?h.PNNetworkIssuesCategory:h.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=h.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=h.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=h.PNTimeoutCategory);return new q(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=h.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":404===i?r="Resource not found":400===i?(n=h.PNBadRequestCategory,r="Bad request"):403===i?(n=h.PNAccessDeniedCategory,r="Access denied"):i>=500&&(n=h.PNServerErrorCategory,r="Internal server error"),"object"==typeof e&&0===Object.keys(e).length&&(n=h.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);"object"==typeof e&&(Array.isArray(e)?"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]):("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e?(s=e,i=e.status):s=e,"error"in e&&e.error instanceof Error&&(s=e.error)))}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new q(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,q.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}var G;!function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(G||(G={}));var K=G;class H{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}set emitStatus(e){this._emitStatus=e}onUserIdChange(e){this.configuration.userId=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onPresenceStateChange(e){this.scheduleEventPost({type:"client-presence-state-update",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel,state:e})}onHeartbeatIntervalChange(e){this.configuration.heartbeatInterval=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onTokenChange(e){const t={type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel};this.parsedAccessToken(e).then((s=>{t.preProcessedToken=s,t.accessToken=e})).then((()=>this.scheduleEventPost(t)))}disconnect(){this.scheduleEventPost({type:"client-disconnect",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e,workerLogLevel:this.configuration.workerLogLevel};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier,workerLogLevel:this.configuration.workerLogLevel};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.preProcessedToken=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogLevel:this.configuration.workerLogLevel},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e),this.shouldAnnounceNewerSharedWorkerVersionAvailability()&&localStorage.setItem("PNSubscriptionSharedWorkerVersion",this.configuration.sdkVersion),window.addEventListener("storage",(e=>{"PNSubscriptionSharedWorkerVersion"===e.key&&e.newValue&&this._emitStatus&&this.isNewerSharedWorkerVersion(e.newValue)&&this._emitStatus({error:!1,category:h.PNSharedWorkerUpdatedCategory})}))}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",(()=>"string"==typeof t.message||"number"==typeof t.message||"boolean"==typeof t.message?{messageType:"text",message:t.message}:t.message));else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t,workerLogLevel:this.configuration.workerLogLevel})}else if("request-process-success"===t.type||"request-process-error"===t.type)if(this.callbacks.has(t.identifier)){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);this.callbacks.delete(t.identifier),"request-process-success"===t.type?e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body}):s(this.errorFromRequestSendingError(t))}else this._emitStatus&&t.url.indexOf("/v2/presence")>=0&&t.url.indexOf("/heartbeat")>=0&&("request-process-success"===t.type&&this.configuration.announceSuccessfulHeartbeats?this._emitStatus({statusCode:t.response.status,error:!1,operation:K.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}):"request-process-error"===t.type&&this.configuration.announceFailedHeartbeats&&this._emitStatus(this.errorFromRequestSendingError(t).toStatus(K.PNHeartbeatOperation)))}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;return this.parsedAccessToken(e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0)}))}parsedAccessToken(e){return i(this,void 0,void 0,(function*(){if(e)return this.accessTokensMap[e]?this.accessTokensMap[e]:this.stringifyAccessToken(e).then((([t,s])=>{if(t&&s)return(this.accessTokensMap={[e]:{token:s,expiration:t.timestamp+60*t.ttl}})[e]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}errorFromRequestSendingError(e){let t=h.PNUnknownCategory,s="Unknown error";if(e.error)"NETWORK_ISSUE"===e.error.type?t=h.PNNetworkIssuesCategory:"TIMEOUT"===e.error.type?t=h.PNTimeoutCategory:"ABORTED"===e.error.type&&(t=h.PNCancelledCategory),s=`${e.error.message} (${e.identifier})`;else if(e.response){const{url:t,response:s}=e;return q.create({url:t,headers:s.headers,body:s.body,status:s.status},s.body)}return new q(s,t,0,new Error(s))}shouldAnnounceNewerSharedWorkerVersionAvailability(){const e=localStorage.getItem("PNSubscriptionSharedWorkerVersion");return!e||!this.isNewerSharedWorkerVersion(e)}isNewerSharedWorkerVersion(e){const[t,s,n]=this.configuration.sdkVersion.split(".").map(Number),[r,i,a]=e.split(".").map(Number);return r>t||i>s||a>n}}function B(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?B(c,t+1):c})),r}const W=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,l,h,p,g,b,y;const m=Object.assign({},e);if(null!==(t=m.ssl)&&void 0!==t||(m.ssl=!0),null!==(s=m.transactionalRequestTimeout)&&void 0!==s||(m.transactionalRequestTimeout=15),null!==(n=m.subscribeRequestTimeout)&&void 0!==n||(m.subscribeRequestTimeout=310),null!==(r=m.fileRequestTimeout)&&void 0!==r||(m.fileRequestTimeout=300),null!==(i=m.restore)&&void 0!==i||(m.restore=!0),null!==(a=m.useInstanceId)&&void 0!==a||(m.useInstanceId=!1),null!==(o=m.suppressLeaveEvents)&&void 0!==o||(m.suppressLeaveEvents=!1),null!==(c=m.requestMessageCountThreshold)&&void 0!==c||(m.requestMessageCountThreshold=100),null!==(u=m.autoNetworkDetection)&&void 0!==u||(m.autoNetworkDetection=!1),null!==(l=m.enableEventEngine)&&void 0!==l||(m.enableEventEngine=!0),null!==(h=m.maintainPresenceState)&&void 0!==h||(m.maintainPresenceState=!0),null!==(p=m.useSmartHeartbeat)&&void 0!==p||(m.useSmartHeartbeat=!1),null!==(g=m.keepAlive)&&void 0!==g||(m.keepAlive=!1),m.userId&&m.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=m.userId)&&void 0!==b||(m.userId=m.uuid),!m.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(y=m.userId)||void 0===y?void 0:y.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");m.origin||(m.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:m.subscribeKey,publishKey:m.publishKey,secretKey:m.secretKey};void 0!==m.presenceTimeout&&(m.presenceTimeout>320?(m.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):m.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete m.presenceTimeout)),void 0!==m.presenceTimeout?m.heartbeatInterval=m.presenceTimeout/2-1:m.presenceTimeout=300;let v=!1,S=!0,w=5,O=!1,k=100,C=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(O=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(C=m.useRequestId),void 0!==m.announceSuccessfulHeartbeats&&"boolean"==typeof m.announceSuccessfulHeartbeats&&(v=m.announceSuccessfulHeartbeats),void 0!==m.announceFailedHeartbeats&&"boolean"==typeof m.announceFailedHeartbeats&&(S=m.announceFailedHeartbeats),void 0!==m.fileUploadPublishRetryLimit&&"number"==typeof m.fileUploadPublishRetryLimit&&(w=m.fileUploadPublishRetryLimit),Object.assign(Object.assign({},m),{keySet:f,dedupeOnSubscribe:O,maximumCacheSize:k,useRequestId:C,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:S,fileUploadPublishRetryLimit:w})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var V,z;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(V||(V={}));class J{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}toString(){return"ConsoleLogger {}"}log(e){const t=V[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==V.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?T(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===V.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${e.details?`\n ${this.paddedString("Details",n)}: ${e.details}`:""}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),l=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,h=e[s],d=s.padEnd(l," ");if(null===h)o.push(`${u}${d}: null`);else if(void 0===h)o.push(`${u}${d}: undefined`);else if("function"==typeof h)o.push(`${u}${d}: `);else if("object"==typeof h){const e=Array.isArray(h),s=e&&0===h.length,r=!(e||h instanceof String||0!==Object.keys(h).length),a=!e&&"function"==typeof h.toString&&0!==h.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(h,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${h}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${J.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(J.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}J.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(z||(z={}));class X{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return Q(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return Q(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(this.minimumDelay*Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry")}}}}const Q=(e,t,s,n,r,i)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!Y(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),Y=(e,t)=>!!(t&&t.length>0)&&t.includes(Z(e)),Z=e=>{let t=z.Unknown;return e.path.startsWith("/v2/subscribe")?t=z.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=z.MessageSend:e.path.startsWith("/v2/presence")?t=z.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=z.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=z.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=z.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=z.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=z.Files),t};class ee{constructor(e,t,s){this.previousEntryTimestamp=0,this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(V.Trace,e,t)}debug(e,t){this.log(V.Debug,e,t)}info(e,t){this.log(V.Info,e,t)}warn(e,t){this.log(V.Warn,e,t)}error(e,t){this.log(V.Error,e,t)}log(e,t,s){if(ee[r](i)))}}var te={exports:{}}; -/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(te,te.exports);var se=t(te.exports),ne={createUUID:()=>se.uuid?se.uuid():se()};const re=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=X.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[z.MessageSend,z.Presence,z.Files,z.MessageStorage,z.ChannelGroups,z.DevicePushNotifications,z.AppContext,z.MessageReactions]}));const a=`pn-${ne.createUUID()}`;e.logVerbosity?e.logLevel=V.Debug:void 0===e.logLevel&&(e.logLevel=V.None);const o=new ee(ae(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new J]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate();const c=e.useRandomIVs;null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),void 0!==c&&(o.warn("Configuration","'useRandomIVs' is deprecated. Pass it to 'cryptoModule' instead."),!1===c&&o.warn("Configuration","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")),e.origin=ie(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const u=e.cryptoModule;u&&delete e.cryptoModule;const l=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,isSharedWorkerEnabled:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"12.0.2"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),l.setCipherKey(e.cipherKey)):u&&(l._cryptoModule=u),l},ie=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},ae=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class oe{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,l=n.length>0;if(c||u||l){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(l){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const h=r.length>0,d=i.length>0,p=a.length>0;if(h||d||p){if(o.patterns={},h){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var ce;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.DELETE="DELETE",e.LOCAL="LOCAL"}(ce||(ce={}));class ue{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?ce.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===ce.POST||t===ce.PATCH){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ue.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${P(e)}`)).join("&"):`${t}=${P(s)}`})).join("&")}}ue.textDecoder=new TextDecoder("utf-8");class le{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ue(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[l,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==h.PNCancelledCategory,l=(!s||s.status>=400)&&404!==(null==r?void 0:r.statusCode);let d=-1;i&&l&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};l.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class he{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"===t&&"undefined"==typeof fetch&&(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(he.originalFetch=he.getOriginalFetch(),this.isFetchMonkeyPatched()&&e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw q.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:q.create(n).message,failed:!0}))),q.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([he.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(q.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?he.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${T(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){if("undefined"==typeof document||!document.body)return fetch;let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}he.encoder=new TextEncoder,he.decoder=new TextDecoder;class de{constructor(e){this.params=e,this.requestIdentifier=ne.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:ce.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===ce.POST||a.method===ce.PATCH){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=de.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw q.create(e);return n}}de.decoder=new TextDecoder;var pe;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files"}(pe||(pe={}));class ge extends de{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return K.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=de.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;null!=t||(t=e.c.endsWith("-pnpres")?pe.Presence:pe.Message);const s=A(e.d);return t!=pe.Signal&&"string"==typeof e.d?t==pe.Message?{type:pe.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:{type:pe.Files,data:this.fileFromEnvelope(e),pn_mfp:s}:t==pe.Message?{type:pe.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:t===pe.Presence?{type:pe.Presence,data:this.presenceEventFromEnvelope(e),pn_mfp:s}:t==pe.Signal?{type:pe.Signal,data:this.signalFromEnvelope(e),pn_mfp:s}:t===pe.AppContext?{type:pe.AppContext,data:this.appContextFromEnvelope(e),pn_mfp:s}:t===pe.MessageAction?{type:pe.MessageAction,data:this.messageActionFromEnvelope(e),pn_mfp:s}:{type:pe.Files,data:this.fileFromEnvelope(e),pn_mfp:s}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(be.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class be extends ge{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${j(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i,onDemand:a}=this.parameters,o={};return a&&(o["on-demand"]=1),e&&e.length>0&&(o["channel-group"]=e.sort().join(",")),t&&t.length>0&&(o["filter-expr"]=t),s&&(o.heartbeat=s),n&&Object.keys(n).length>0&&(o.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(o.tt=r):void 0!==r&&r>0&&(o.tt=r),i&&(o.tr=i),o}}class ye{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}handleEvent(e){if(this.hasListeners)if(e.type===pe.Message)this.announce("message",e.data);else if(e.type===pe.Signal)this.announce("signal",e.data);else if(e.type===pe.Presence)this.announce("presence",e.data);else if(e.type===pe.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:l}=o,h=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},h),{user:u,space:l})})});this.announce("membership",d)}}else e.type===pe.MessageAction?this.announce("messageAction",e.data):e.type===pe.Files&&this.announce("file",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class me{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class fe{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;if(null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size)return;const o=this.lastTimetoken,c=this.currentTimetoken;0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0),!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:c,lastTimetoken:o}))})))}unsubscribeAll(e=!1){this.disconnectedWhileHandledEvent=!0,this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.disconnectedWhileHandledEvent=!1,this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),{onDemand:!this.subscriptionStatusAnnounced||e}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===h.PNCancelledCategory)return;return void(e.category===h.PNTimeoutCategory?this.startSubscribeLoop():e.category===h.PNNetworkIssuesCategory||e.category===h.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:h.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:h.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:h.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:h.PNNetworkIssuesCategory}))):e.category===h.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=I(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:h.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:h.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>({type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:e.pn_mfp})}))),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.disconnectedWhileHandledEvent?this.disconnectedWhileHandledEvent=!1:this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:h.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class Se{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class we extends Se{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class Oe extends Se{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get androidNotification(){var e;return null===(e=this.payload.android)||void 0===e?void 0:e.notification}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this.androidNotification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this.androidNotification.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.androidNotification.notification_count=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.androidNotification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.androidNotification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.androidNotification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={},this.payload.android={notification:{}}}toObject(){var e,t;const s={},n=Object.assign({},this.payload.notification),i=Object.assign({},this.payload.android),a=r(Object.assign({},null!==(e=i.notification)&&void 0!==e?e:{}),["title","body"]);if(this._isSilent){const e={};this._title&&(e.title=this._title),this._body&&(e.body=this._body);for(const[t,s]of Object.entries(a))null!=s&&(e[t]=String(s));this.payload.data&&Object.assign(e,this.payload.data),Object.keys(e).length&&(s.data=e),delete i.notification,Object.keys(i).length&&(s.android=i)}else if(Object.keys(n).length&&(s.notification=n),this.payload.data&&Object.keys(this.payload.data).length&&(s.data=Object.assign({},this.payload.data)),Object.keys(a).length){const e=r(i,["notification"]);s.android=Object.assign(Object.assign({},e),{notification:a})}else{const e=r(i,["notification"]);Object.keys(e).length&&(s.android=e)}const o=r(this.payload,["notification","android","data","pn_exceptions"]);return Object.assign(s,o),(null===(t=this.payload.pn_exceptions)||void 0===t?void 0:t.length)&&(s.pn_exceptions=this.payload.pn_exceptions),Object.keys(s).length?s:null}}class ke{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new we(this._payload.apns,e,t),this.fcm=new Oe(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_fcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Ce{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class Pe{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class je extends Ce{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new Pe(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class Ee{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Ne(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Te(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function _e(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Ie extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class Me extends Ce{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Ie}abort(){this._aborted=!0,this.notify(new Ie)}}class Ae{constructor(e,t){this.payload=e,this.dependencies=t}}class Ue extends Ae{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new Me}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const De=e=>(t,s)=>new Ue(t,s,e),Re=_e("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),$e=Te("LEAVE",((e,t)=>({channels:e,groups:t}))),Fe=Te("EMIT_STATUS",(e=>e)),xe=_e("WAIT",(()=>({}))),Le=Ne("RECONNECT",(()=>({}))),qe=Ne("DISCONNECT",((e=!1)=>({isOffline:e}))),Ge=Ne("JOINED",((e,t)=>({channels:e,groups:t}))),Ke=Ne("LEFT",((e,t)=>({channels:e,groups:t}))),He=Ne("LEFT_ALL",((e=!1)=>({isOffline:e}))),Be=Ne("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),We=Ne("HEARTBEAT_FAILURE",(e=>e)),Ve=Ne("TIMES_UP",(()=>({})));class ze extends Ee{constructor(e,t){super(t,t.config.logger()),this.on(Re.type,De(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(Be(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(We(t))}}}))))),this.on($e.type,De(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(xe.type,De(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Ve())}))))),this.on(Fe.type,De(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:K.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:K.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const Je=new Pe("HEARTBEAT_STOPPED");Je.on(Ge.type,((e,t)=>Je.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Je.on(Ke.type,((e,t)=>Je.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),Je.on(Le.type,((e,t)=>Ye.with({channels:e.channels,groups:e.groups}))),Je.on(He.type,((e,t)=>Ze.with(void 0)));const Xe=new Pe("HEARTBEAT_COOLDOWN");Xe.onEnter((()=>xe())),Xe.onExit((()=>xe.cancel)),Xe.on(Ve.type,((e,t)=>Ye.with({channels:e.channels,groups:e.groups}))),Xe.on(Ge.type,((e,t)=>Ye.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(Ke.type,((e,t)=>Ye.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Xe.on(qe.type,((e,t)=>Je.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Xe.on(He.type,((e,t)=>Ze.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Qe=new Pe("HEARTBEAT_FAILED");Qe.on(Ge.type,((e,t)=>Ye.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Qe.on(Ke.type,((e,t)=>Ye.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Qe.on(Le.type,((e,t)=>Ye.with({channels:e.channels,groups:e.groups}))),Qe.on(qe.type,((e,t)=>Je.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Qe.on(He.type,((e,t)=>Ze.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Ye=new Pe("HEARTBEATING");Ye.onEnter((e=>Re(e.channels,e.groups))),Ye.onExit((()=>Re.cancel)),Ye.on(Be.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups},[Fe(Object.assign({},t.payload))]))),Ye.on(Ge.type,((e,t)=>Ye.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ye.on(Ke.type,((e,t)=>Ye.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[$e(t.payload.channels,t.payload.groups)]))),Ye.on(We.type,((e,t)=>Qe.with(Object.assign({},e),[...t.payload.status?[Fe(Object.assign({},t.payload.status))]:[]]))),Ye.on(qe.type,((e,t)=>Je.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]]))),Ye.on(He.type,((e,t)=>Ze.with(void 0,[...t.payload.isOffline?[]:[$e(e.channels,e.groups)]])));const Ze=new Pe("HEARTBEAT_INACTIVE");Ze.on(Ge.type,((e,t)=>Ye.with({channels:t.payload.channels,groups:t.payload.groups})));class et{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new je(e.config.logger()),this.dispatcher=new ze(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(Ze,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(Ge(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){e&&(this.channels=this.channels.filter((t=>!e.includes(t)))),t&&(this.groups=this.groups.filter((e=>!t.includes(e)))),this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(Ke(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.dependencies.presenceState&&(this.channels.forEach((e=>delete this.dependencies.presenceState[e])),this.groups.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=[],this.groups=[],this.engine.transition(He(e))}reconnect(){this.engine.transition(Le())}disconnect(e=!1){this.engine.transition(qe(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const tt=_e("HANDSHAKE",((e,t,s)=>({channels:e,groups:t,onDemand:s}))),st=_e("RECEIVE_MESSAGES",((e,t,s,n)=>({channels:e,groups:t,cursor:s,onDemand:n}))),nt=Te("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),rt=Te("EMIT_STATUS",(e=>e)),it=Ne("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),at=Ne("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),ot=Ne("HANDSHAKE_SUCCESS",(e=>e)),ct=Ne("HANDSHAKE_FAILURE",(e=>e)),ut=Ne("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),lt=Ne("RECEIVE_FAILURE",(e=>e)),ht=Ne("DISCONNECT",((e=!1)=>({isOffline:e}))),dt=Ne("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),pt=Ne("UNSUBSCRIBE_ALL",(()=>({}))),gt=new Pe("UNSUBSCRIBED");gt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,onDemand:!0}))),gt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region},onDemand:!0})));const bt=new Pe("HANDSHAKE_STOPPED");bt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),bt.on(dt.type,((e,{payload:t})=>mt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),bt.on(at.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?gt.with(void 0):bt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),bt.on(pt.type,(e=>gt.with()));const yt=new Pe("HANDSHAKE_FAILED");yt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),yt.on(dt.type,((e,{payload:t})=>mt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),yt.on(at.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0},onDemand:!0})})),yt.on(pt.type,(e=>gt.with()));const mt=new Pe("HANDSHAKING");mt.onEnter((e=>{var t;return tt(e.channels,e.groups,null!==(t=e.onDemand)&&void 0!==t&&t)})),mt.onExit((()=>tt.cancel)),mt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),mt.on(ot.type,((e,{payload:t})=>{var s,n,r,i,a;return St.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:I(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[rt({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),operation:K.PNSubscribeOperation,currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),mt.on(ct.type,((e,t)=>{var s;return yt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[rt({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),mt.on(ht.type,((e,t)=>{var s;if(t.payload.isOffline){const t=q.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation);return yt.with(Object.assign(Object.assign({},e),{reason:t}),[rt({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return bt.with(Object.assign({},e))})),mt.on(at.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0},onDemand:!0})})),mt.on(pt.type,(e=>gt.with()));const ft=new Pe("RECEIVE_STOPPED");ft.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),ft.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),ft.on(dt.type,((e,{payload:t})=>{var s;return mt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),ft.on(pt.type,(()=>gt.with(void 0)));const vt=new Pe("RECEIVE_FAILED");vt.on(dt.type,((e,{payload:t})=>{var s;return mt.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),vt.on(it.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),vt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},onDemand:!0}))),vt.on(pt.type,(e=>gt.with(void 0)));const St=new Pe("RECEIVING");St.onEnter((e=>{var t;return st(e.channels,e.groups,e.cursor,null!==(t=e.onDemand)&&void 0!==t&&t)})),St.onExit((()=>st.cancel)),St.on(ut.type,((e,{payload:t})=>St.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:I(t.cursor.timetoken)},[nt(e.cursor,t.events)]))),St.on(it.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=q.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation).status)||void 0===s?void 0:s.category),gt.with(void 0,[rt(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation},e?{error:e}:{}))])}return St.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken,onDemand:!0},[rt({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),St.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?gt.with(void 0,[rt({category:h.PNDisconnectedCategory})]):St.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:I(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken),onDemand:!0},[rt({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),St.on(lt.type,((e,{payload:t})=>{var s;return vt.with(Object.assign(Object.assign({},e),{reason:t}),[rt({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),St.on(ht.type,((e,t)=>{var s;if(t.payload.isOffline){const t=q.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation);return vt.with(Object.assign(Object.assign({},e),{reason:t}),[rt({category:h.PNDisconnectedUnexpectedlyCategory,operation:K.PNSubscribeOperation,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return ft.with(Object.assign({},e),[rt({category:h.PNDisconnectedCategory,operation:K.PNSubscribeOperation})])})),St.on(pt.type,(e=>gt.with(void 0,[rt({category:h.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation})])));class wt extends Ee{constructor(e,t){super(t,t.config.logger()),this.on(tt.type,De(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}),{onDemand:t.onDemand}));return e.transition(ot(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(ct(t))}}}))))),this.on(st.type,De(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression,onDemand:t.onDemand});e.transition(ut(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;if(!s.aborted)return e.transition(lt(t))}}}))))),this.on(nt.type,De(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(rt.type,De(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class Ot{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new je(e.config.logger()),this.dispatcher=new wt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(gt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===St.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return _(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){var r;const i=null==e?void 0:e.some((e=>!this.channels.includes(e))),a=null==t?void 0:t.some((e=>!this.groups.includes(e))),o=i||a;if(this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s)this.engine.transition(at(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s));else if(o)this.engine.transition(it(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]]))));else{this.dependencies.config.logger().debug("EventEngine","Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.");const e=this.engine.currentState,t=this.engine.currentContext;let s="0";if((null==e?void 0:e.label)===St.label&&t){s=null===(r=t.cursor)||void 0===r?void 0:r.timetoken}this.dependencies.emitStatus({category:h.PNSubscriptionChangedCategory,affectedChannels:Array.from(new Set(this.channels)),affectedChannelGroups:Array.from(new Set(this.groups)),currentTimetoken:s})}this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=E(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=E(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=N(this.channels,e),i=N(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(it(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannelGroups(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(it(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(dt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(ht(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class kt extends de{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?ce.POST:ce.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return K.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${P(t)}/0${this.parameters.sendByPost?"":`/${P(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Ct extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${P(s)}/0/${P(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class Pt extends ge{operation(){return K.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${j(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n,onDemand:r}=this.parameters,i={ee:""};return r&&(i["on-demand"]=1),e&&e.length>0&&(i["channel-group"]=e.sort().join(",")),t&&t.length>0&&(i["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(i.tt=s):s&&s>0&&(i.tt=s),n&&(i.tr=n),i}}class jt extends ge{operation(){return K.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${j(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s,onDemand:n}=this.parameters,r={ee:""};return n&&(r["on-demand"]=1),e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),s&&Object.keys(s).length>0&&(r.state=JSON.stringify(s)),r}}var Et;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Et||(Et={}));class Nt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Nt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Nt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class Tt{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=ne.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class _t{constructor(e,t="Subscription"){this.subscriptionType=t,this.id=ne.createUUID(),this.eventDispatcher=new ye,this._state=e}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class It extends Tt{constructor(e){const t=new Nt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class Mt extends _t{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new It({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t,"SubscriptionSet"),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new Mt({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>e?{messageType:"object",message:{subscription:this,subscriptions:e},details:"Unregister subscriptions of subscription set from real-time events:"}:{messageType:"text",message:`Unregister subscription from real-time events: ${this}`})),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class At extends Tt{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new Nt({[e.entity.subscriptionType==Et.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class Ut extends _t{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new At(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s,n;if(this.state.isSubscribed&&this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)){if(this.parentSetsCount>0){const e=A(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Event (${e}) already handled by ${this.id}. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(n=t.data.subscription)&&void 0!==n?n:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Nt({}):this.state.subscriptionInput}cloneEmpty(){return new Ut({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new Mt({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class Dt extends de{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return K.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${j(null!=s?s:[],",")}/uuid/${P(null!=t?t:"")}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Rt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?void 0===t?"Missing State":0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${j(null!=s?s:[],",")}/uuid/${P(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class $t extends de{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return K.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${j(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),void 0!==t&&(n.state=JSON.stringify(t)),n}}class Ft extends de{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return K.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${j(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class xt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${P(t)}`}}class Lt extends de{constructor(e){var t,s,n,r,i,a,o,c;super(),this.parameters=e,null!==(t=(i=this.parameters).queryParameters)&&void 0!==t||(i.queryParameters={}),null!==(s=(a=this.parameters).includeUUIDs)&&void 0!==s||(a.includeUUIDs=true),null!==(n=(o=this.parameters).includeState)&&void 0!==n||(o.includeState=false),null!==(r=(c=this.parameters).limit)&&void 0!==r||(c.limit=1e3)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?K.PNGlobalHereNowOperation:K.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};const c=this.parameters.limit;let u=!1;if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy},u||t.occupancy!==c||(u=!0)})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${j(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,limit:n,offset:r,queryParameters:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},this.operation()===K.PNHereNowOperation?{limit:n}:{}),this.operation()===K.PNHereNowOperation&&null!=r&&r?{offset:r}:{}),t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),i)}}class qt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${P(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Gt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${j(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class Kt extends de{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return K.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${P(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(Kt.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Ht;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Ht||(Ht={}));class Bt extends de{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return K.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Ht.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${j(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Bt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Ht.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Wt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class Vt extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class zt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}/message/${n}/action/${s}`}}class Jt extends de{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return K.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${P(t)}/0/${P(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Xt extends de{constructor(e){super({method:ce.LOCAL}),this.parameters=e}operation(){return K.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${P(e)}/files/${P(t)}/${P(s)}`}}class Qt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${P(s)}/files/${P(t)}/${P(n)}`}}class Yt extends de{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return K.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class Zt extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class es extends de{constructor(e){super({method:ce.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return K.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?es.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class ts{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:h.PNUnknownCategory,operation:K.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof q?e:q.create(e);throw new d("File upload error.",t.toStatus(K.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new Zt(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new es({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:h.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class ss{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return Et.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new Ut({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class ns extends ss{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class rs extends ss{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return Et.ChannelGroup}}class is extends ss{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class as extends ss{get entityType(){return"Channel"}get name(){return this._nameOrId}}class os extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class cs extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class us extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}}class ls extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}/remove`}}class hs extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ds{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new us(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new hs({keySet:this.keySet}),s=e=>{e&&this.logger.debug("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new os(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new ls(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class ps extends de{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: fcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class gs extends ps{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return K.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class bs extends ps{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return K.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class ys extends ps{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return K.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ms extends ps{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return K.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class fs{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new ys(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new gs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new ms(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class vs extends de{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return K.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}}class ws extends de{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Os extends de{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(y=e.include).customChannelFields)&&void 0!==o||(y.customChannelFields=false),null!==(c=(m=e.include).channelStatusField)&&void 0!==c||(m.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ks extends de{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return K.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Cs extends de{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return K.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class Ps extends de{constructor(e){var t,s,n;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return K.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class js extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}}class Es extends de{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return K.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ns extends de{constructor(e){var t,s,n,r,i,a,o,c,u,l,h,d,p,g,b,y,m,f;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(h=e.include).customFields)&&void 0!==s||(h.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(y=e.include).customUUIDFields)&&void 0!==o||(y.customUUIDFields=false),null!==(c=(m=e.include).UUIDStatusField)&&void 0!==c||(m.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(l=e.limit)&&void 0!==l||(e.limit=100)}operation(){return K.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class Ts extends de{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class _s extends de{constructor(e){var t,s,n;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Is{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ks(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Ts(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new _s(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new js(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new vs(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Ss(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new Es(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ns(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ns(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new ws(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new Os(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new Os(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class Ms extends de{constructor(){super()}operation(){return K.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class As extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/files/${P(s)}/${P(n)}`}}class Us{static notificationPayload(e,t){return new ke(e,t)}static generateUUID(){return ne.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")||"keySet"===e||C(e)}))),this._objects=new Is(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ds(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new fs(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ye,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new et({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new Ot({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===pe.Message||e.type===pe.Signal?A(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new ve(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:h.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub","Auth key updated."),this._configuration.setAuthKey(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e,this.onUserIdChange&&this.onUserIdChange(this._configuration.userId)}getUserId(){return this._configuration.userId}setUserId(e){this.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub","Cipher key updated."),this.cipherKey=e}set heartbeatInterval(e){var t;this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e),this.onHeartbeatIntervalChange&&this.onHeartbeatIntervalChange(null!==(t=this._configuration.getHeartbeatInterval())&&void 0!==t?t:0)}setHeartbeatInterval(e){this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new as(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new rs(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new ns(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new is(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new Mt({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),h.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===K.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===K.PNSubscribeOperation||i===K.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:h.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=Us.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof q?e:q.create(e);if(t)return s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,"REST API request processing error, check status for details")}))),t(s.toStatus(i),null);const n=s.toPubNubError(i,"REST API request processing error, check status for details");throw s.category!==h.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:n}))),n}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Nt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"})));let n,r=!t||0===t.length;if(!r&&e instanceof Mt&&e.subscriptions.length===(null==t?void 0:t.length)&&(r=e.subscriptions.every((e=>t.includes(e)))),r&&delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Nt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof Mt?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===Et.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof Mt?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof Ut&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new Nt({channels:t,channelGroups:e})),n.isEmpty))return}const i={};i.channels=n.channels,i.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(i):this.eventEngine&&this.eventEngine.unsubscribe(i)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const s=new be(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:K.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new Ft({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub",`Disconnect (while offline? ${e?"yes":"no"})`),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new Pt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Bt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new Kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new xt({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new Dt(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state))),this.onPresenceStateChange&&this.onPresenceStateChange(this.presenceState)}o="withHeartbeat"in e&&e.withHeartbeat?new $t(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Rt(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof $t?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&(this.subscriptionManager.setState(e),this.onPresenceStateChange&&this.onPresenceStateChange(this.subscriptionManager.presenceState)),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:K.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new $t(Object.assign(Object.assign({},e),{channels:[...new Set(n)],channelGroups:[...new Set(r)],keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}setToken(e){this.logger.debug("PubNub","Access token updated."),this.token=e}parseToken(e){return this.logger.debug("PubNub","Parse access token."),this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new ts(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:K.PNPublishFileOperation,category:h.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof q&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Yt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${P(t)}`)).join("&"):`${e}=${P(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new As(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new Ms,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s!==this._globalSubscriptionSet&&s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}Us.decoder=new TextDecoder,Us.OPERATIONS=K,Us.CATEGORIES=h,Us.Endpoint=z,Us.ExponentialRetryPolicy=X.ExponentialRetryPolicy,Us.LinearRetryPolicy=X.LinearRetryPolicy,Us.NoneRetryPolicy=X.None,Us.LogLevel=V;class Ds{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class Rs extends Us{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=W(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=re(i,(e=>{if(e.cipherKey){return new F({default:new $(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new O({cipherKey:e.cipherKey})]})}}));let u,l;e.subscriptionWorkerLogVerbosity?e.subscriptionWorkerLogLevel=V.Debug:void 0===e.subscriptionWorkerLogLevel&&(e.subscriptionWorkerLogLevel=V.None),void 0!==e.subscriptionWorkerLogVerbosity&&a.logger().warn("Configuration","'subscriptionWorkerLogVerbosity' is deprecated. Use 'subscriptionWorkerLogLevel' instead."),a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new oe(new Ds((e=>B(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new D({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()}));let h,d=()=>{},p=()=>{},g=()=>{},b=()=>{};h=new R;let y=new he(a.logger(),i.transport);if(r.subscriptionWorkerUrl)try{const e=new H({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),announceSuccessfulHeartbeats:a.announceSuccessfulHeartbeats,announceFailedHeartbeats:a.announceFailedHeartbeats,workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogLevel:i.subscriptionWorkerLogLevel,tokenManager:u,transport:y,logger:a.logger()});p=t=>e.onPresenceStateChange(t),d=t=>e.onHeartbeatIntervalChange(t),g=t=>e.onTokenChange(t),b=t=>e.onUserIdChange(t),y=e,r.subscriptionWorkerUnsubscribeOfflineClients&&"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("pagehide",(t=>{t.persisted||e.terminate()}),{once:!0})}catch(e){a.logger().error("PubNub",(()=>({messageType:"error",message:e})))}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const m=new le({clientConfiguration:a,tokenManager:u,transport:y});if(super({configuration:a,transport:m,cryptography:h,tokenManager:u,crypto:l}),this.File=o,this.onHeartbeatIntervalChange=d,this.onAuthenticationChange=g,this.onPresenceStateChange=p,this.onUserIdChange=b,y instanceof H){y.emitStatus=this.emitStatus.bind(this);const e=this.disconnect.bind(this);this.disconnect=t=>{y.disconnect(),e()}}(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&"undefined"!=typeof window&&window.addEventListener&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:Rs.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:Rs.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return Rs.CryptoModule=F,Rs})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).PubNub=t()}(this,(function(){"use strict";var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var s={exports:{}};!function(t){!function(e,s){var n=Math.pow(2,-24),r=Math.pow(2,32),i=Math.pow(2,53);var a={encode:function(e){var t,n=new ArrayBuffer(256),a=new DataView(n),o=0;function c(e){for(var s=n.byteLength,r=o+e;s>2,u=0;u>6),r.push(128|63&a)):a<55296?(r.push(224|a>>12),r.push(128|a>>6&63),r.push(128|63&a)):(a=(1023&a)<<10,a|=1023&t.charCodeAt(++n),a+=65536,r.push(240|a>>18),r.push(128|a>>12&63),r.push(128|a>>6&63),r.push(128|63&a))}return d(3,r.length),l(r);default:var p;if(Array.isArray(t))for(d(4,p=t.length),n=0;n>5!==e)throw"Invalid indefinite length element";return s}function m(e,t){for(var s=0;s>10),e.push(56320|1023&n))}}"function"!=typeof t&&(t=function(e){return e}),"function"!=typeof i&&(i=function(){return s});var y=function e(){var r,d,y=h(),f=y>>5,v=31&y;if(7===f)switch(v){case 25:return function(){var e=new ArrayBuffer(4),t=new DataView(e),s=l(),r=32768&s,i=31744&s,a=1023&s;if(31744===i)i=261120;else if(0!==i)i+=114688;else if(0!==a)return a*n;return t.setUint32(0,r<<16|i<<13|a<<13),t.getFloat32(0)}();case 26:return c(a.getFloat32(o),4);case 27:return c(a.getFloat64(o),8)}if((d=g(v))<0&&(f<2||6=0;)S+=d,O.push(u(d));var j=new Uint8Array(S),k=0;for(r=0;r=0;)m(w,d);else m(w,d);return String.fromCharCode.apply(null,w);case 4:var P;if(d<0)for(P=[];!p();)P.push(e());else for(P=new Array(d),r=0;re.toString())).join(", ")}]}`}}a.encoder=new TextEncoder,a.decoder=new TextDecoder;class o{static create(e){return new o(e)}constructor(e){let t,s,n,r;if(e instanceof File)r=e,n=e.name,s=e.type,t=e.size;else if("data"in e){const i=e.data;s=e.mimeType,n=e.name,r=new File([i],n,{type:s}),t=r.size}if(void 0===r)throw new Error("Couldn't construct a file out of supplied options.");if(void 0===n)throw new Error("Couldn't guess filename out of the options. Please provide one.");t&&(this.contentLength=t),this.mimeType=s,this.data=r,this.name=n}toBuffer(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toArrayBuffer(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if(s.result instanceof ArrayBuffer)return e(s.result)})),s.addEventListener("error",(()=>t(s.error))),s.readAsArrayBuffer(this.data)}))}))}toString(){return i(this,void 0,void 0,(function*(){return new Promise(((e,t)=>{const s=new FileReader;s.addEventListener("load",(()=>{if("string"==typeof s.result)return e(s.result)})),s.addEventListener("error",(()=>{t(s.error)})),s.readAsBinaryString(this.data)}))}))}toStream(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in Node.js environments.")}))}toFile(){return i(this,void 0,void 0,(function*(){return this.data}))}toFileUri(){return i(this,void 0,void 0,(function*(){throw new Error("This feature is only supported in React Native environments.")}))}toBlob(){return i(this,void 0,void 0,(function*(){return this.data}))}}o.supportsBlob="undefined"!=typeof Blob,o.supportsFile="undefined"!=typeof File,o.supportsBuffer=!1,o.supportsStream=!1,o.supportsString=!0,o.supportsArrayBuffer=!0,o.supportsEncryptFile=!0,o.supportsFileUri=!1;function c(e){const t=e.replace(/==?$/,""),s=Math.floor(t.length/4*3),n=new ArrayBuffer(s),r=new Uint8Array(n);let i=0;function a(){const e=t.charAt(i++),s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(e);if(-1===s)throw new Error(`Illegal character at ${i}: ${t.charAt(i-1)}`);return s}for(let e=0;e>4,c=(15&s)<<4|n>>2,u=(3&n)<<6|i;r[e]=o,64!=n&&(r[e+1]=c),64!=i&&(r[e+2]=u)}return n}function u(e){let t="";const s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(e),r=n.byteLength,i=r%3,a=r-i;let o,c,u,h,l;for(let e=0;e>18,c=(258048&l)>>12,u=(4032&l)>>6,h=63&l,t+=s[o]+s[c]+s[u]+s[h];return 1==i?(l=n[a],o=(252&l)>>2,c=(3&l)<<4,t+=s[o]+s[c]+"=="):2==i&&(l=n[a]<<8|n[a+1],o=(64512&l)>>10,c=(1008&l)>>4,u=(15&l)<<2,t+=s[o]+s[c]+s[u]+"="),t}var h;!function(e){e.PNNetworkIssuesCategory="PNNetworkIssuesCategory",e.PNTimeoutCategory="PNTimeoutCategory",e.PNCancelledCategory="PNCancelledCategory",e.PNBadRequestCategory="PNBadRequestCategory",e.PNAccessDeniedCategory="PNAccessDeniedCategory",e.PNValidationErrorCategory="PNValidationErrorCategory",e.PNAcknowledgmentCategory="PNAcknowledgmentCategory",e.PNMalformedResponseCategory="PNMalformedResponseCategory",e.PNServerErrorCategory="PNServerErrorCategory",e.PNUnknownCategory="PNUnknownCategory",e.PNNetworkUpCategory="PNNetworkUpCategory",e.PNNetworkDownCategory="PNNetworkDownCategory",e.PNReconnectedCategory="PNReconnectedCategory",e.PNConnectedCategory="PNConnectedCategory",e.PNSubscriptionChangedCategory="PNSubscriptionChangedCategory",e.PNRequestMessageCountExceededCategory="PNRequestMessageCountExceededCategory",e.PNDisconnectedCategory="PNDisconnectedCategory",e.PNConnectionErrorCategory="PNConnectionErrorCategory",e.PNDisconnectedUnexpectedlyCategory="PNDisconnectedUnexpectedlyCategory",e.PNSharedWorkerUpdatedCategory="PNSharedWorkerUpdatedCategory"}(h||(h={}));var l=h;class d extends Error{constructor(e,t){super(e),this.status=t,this.name="PubNubError",this.message=e,Object.setPrototypeOf(this,new.target.prototype)}}function p(e,t){var s;return null!==(s=e.statusCode)&&void 0!==s||(e.statusCode=0),Object.assign(Object.assign({},e),{statusCode:e.statusCode,category:t,error:!0})}function g(e,t){return p(Object.assign(Object.assign({message:"Unable to deserialize service response"},void 0!==e?{responseText:e}:{}),void 0!==t?{statusCode:t}:{}),l.PNMalformedResponseCategory)}var b,m,y,f,v,O=O||function(e){var t={},s=t.lib={},n=function(){},r=s.Base={extend:function(e){n.prototype=this;var t=new n;return e&&t.mixIn(e),t.hasOwnProperty("init")||(t.init=function(){t.$super.init.apply(this,arguments)}),t.init.prototype=t,t.$super=this,t},create:function(){var e=this.extend();return e.init.apply(e,arguments),e},init:function(){},mixIn:function(e){for(var t in e)e.hasOwnProperty(t)&&(this[t]=e[t]);e.hasOwnProperty("toString")&&(this.toString=e.toString)},clone:function(){return this.init.prototype.extend(this)}},i=s.WordArray=r.extend({init:function(e,t){e=this.words=e||[],this.sigBytes=null!=t?t:4*e.length},toString:function(e){return(e||o).stringify(this)},concat:function(e){var t=this.words,s=e.words,n=this.sigBytes;if(e=e.sigBytes,this.clamp(),n%4)for(var r=0;r>>2]|=(s[r>>>2]>>>24-r%4*8&255)<<24-(n+r)%4*8;else if(65535>>2]=s[r>>>2];else t.push.apply(t,s);return this.sigBytes+=e,this},clamp:function(){var t=this.words,s=this.sigBytes;t[s>>>2]&=4294967295<<32-s%4*8,t.length=e.ceil(s/4)},clone:function(){var e=r.clone.call(this);return e.words=this.words.slice(0),e},random:function(t){for(var s=[],n=0;n>>2]>>>24-n%4*8&255;s.push((r>>>4).toString(16)),s.push((15&r).toString(16))}return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>3]|=parseInt(e.substr(n,2),16)<<24-n%8*4;return new i.init(s,t/2)}},c=a.Latin1={stringify:function(e){var t=e.words;e=e.sigBytes;for(var s=[],n=0;n>>2]>>>24-n%4*8&255));return s.join("")},parse:function(e){for(var t=e.length,s=[],n=0;n>>2]|=(255&e.charCodeAt(n))<<24-n%4*8;return new i.init(s,t)}},u=a.Utf8={stringify:function(e){try{return decodeURIComponent(escape(c.stringify(e)))}catch(e){throw Error("Malformed UTF-8 data")}},parse:function(e){return c.parse(unescape(encodeURIComponent(e)))}},h=s.BufferedBlockAlgorithm=r.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(e){"string"==typeof e&&(e=u.parse(e)),this._data.concat(e),this._nDataBytes+=e.sigBytes},_process:function(t){var s=this._data,n=s.words,r=s.sigBytes,a=this.blockSize,o=r/(4*a);if(t=(o=t?e.ceil(o):e.max((0|o)-this._minBufferSize,0))*a,r=e.min(4*t,r),t){for(var c=0;cu;){var h;e:{h=c;for(var l=e.sqrt(h),d=2;d<=l;d++)if(!(h%d)){h=!1;break e}h=!0}h&&(8>u&&(i[u]=o(e.pow(c,.5))),a[u]=o(e.pow(c,1/3)),u++),c++}var p=[];r=r.SHA256=n.extend({_doReset:function(){this._hash=new s.init(i.slice(0))},_doProcessBlock:function(e,t){for(var s=this._hash.words,n=s[0],r=s[1],i=s[2],o=s[3],c=s[4],u=s[5],h=s[6],l=s[7],d=0;64>d;d++){if(16>d)p[d]=0|e[t+d];else{var g=p[d-15],b=p[d-2];p[d]=((g<<25|g>>>7)^(g<<14|g>>>18)^g>>>3)+p[d-7]+((b<<15|b>>>17)^(b<<13|b>>>19)^b>>>10)+p[d-16]}g=l+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&u^~c&h)+a[d]+p[d],b=((n<<30|n>>>2)^(n<<19|n>>>13)^(n<<10|n>>>22))+(n&r^n&i^r&i),l=h,h=u,u=c,c=o+g|0,o=i,i=r,r=n,n=g+b|0}s[0]=s[0]+n|0,s[1]=s[1]+r|0,s[2]=s[2]+i|0,s[3]=s[3]+o|0,s[4]=s[4]+c|0,s[5]=s[5]+u|0,s[6]=s[6]+h|0,s[7]=s[7]+l|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;return s[r>>>5]|=128<<24-r%32,s[14+(r+64>>>9<<4)]=e.floor(n/4294967296),s[15+(r+64>>>9<<4)]=n,t.sigBytes=4*s.length,this._process(),this._hash},clone:function(){var e=n.clone.call(this);return e._hash=this._hash.clone(),e}});t.SHA256=n._createHelper(r),t.HmacSHA256=n._createHmacHelper(r)}(Math),m=(b=O).enc.Utf8,b.algo.HMAC=b.lib.Base.extend({init:function(e,t){e=this._hasher=new e.init,"string"==typeof t&&(t=m.parse(t));var s=e.blockSize,n=4*s;t.sigBytes>n&&(t=e.finalize(t)),t.clamp();for(var r=this._oKey=t.clone(),i=this._iKey=t.clone(),a=r.words,o=i.words,c=0;c>>2]>>>24-r%4*8&255)<<16|(t[r+1>>>2]>>>24-(r+1)%4*8&255)<<8|t[r+2>>>2]>>>24-(r+2)%4*8&255,a=0;4>a&&r+.75*a>>6*(3-a)&63));if(t=n.charAt(64))for(;e.length%4;)e.push(t);return e.join("")},parse:function(e){var t=e.length,s=this._map;(n=s.charAt(64))&&-1!=(n=e.indexOf(n))&&(t=n);for(var n=[],r=0,i=0;i>>6-i%4*2;n[r>>>2]|=(a|o)<<24-r%4*8,r++}return f.create(n,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(e){function t(e,t,s,n,r,i,a){return((e=e+(t&s|~t&n)+r+a)<>>32-i)+t}function s(e,t,s,n,r,i,a){return((e=e+(t&n|s&~n)+r+a)<>>32-i)+t}function n(e,t,s,n,r,i,a){return((e=e+(t^s^n)+r+a)<>>32-i)+t}function r(e,t,s,n,r,i,a){return((e=e+(s^(t|~n))+r+a)<>>32-i)+t}for(var i=O,a=(c=i.lib).WordArray,o=c.Hasher,c=i.algo,u=[],h=0;64>h;h++)u[h]=4294967296*e.abs(e.sin(h+1))|0;c=c.MD5=o.extend({_doReset:function(){this._hash=new a.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(e,i){for(var a=0;16>a;a++){var o=e[c=i+a];e[c]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8)}a=this._hash.words;var c=e[i+0],h=(o=e[i+1],e[i+2]),l=e[i+3],d=e[i+4],p=e[i+5],g=e[i+6],b=e[i+7],m=e[i+8],y=e[i+9],f=e[i+10],v=e[i+11],O=e[i+12],S=e[i+13],j=e[i+14],k=e[i+15],w=t(w=a[0],N=a[1],C=a[2],P=a[3],c,7,u[0]),P=t(P,w,N,C,o,12,u[1]),C=t(C,P,w,N,h,17,u[2]),N=t(N,C,P,w,l,22,u[3]);w=t(w,N,C,P,d,7,u[4]),P=t(P,w,N,C,p,12,u[5]),C=t(C,P,w,N,g,17,u[6]),N=t(N,C,P,w,b,22,u[7]),w=t(w,N,C,P,m,7,u[8]),P=t(P,w,N,C,y,12,u[9]),C=t(C,P,w,N,f,17,u[10]),N=t(N,C,P,w,v,22,u[11]),w=t(w,N,C,P,O,7,u[12]),P=t(P,w,N,C,S,12,u[13]),C=t(C,P,w,N,j,17,u[14]),w=s(w,N=t(N,C,P,w,k,22,u[15]),C,P,o,5,u[16]),P=s(P,w,N,C,g,9,u[17]),C=s(C,P,w,N,v,14,u[18]),N=s(N,C,P,w,c,20,u[19]),w=s(w,N,C,P,p,5,u[20]),P=s(P,w,N,C,f,9,u[21]),C=s(C,P,w,N,k,14,u[22]),N=s(N,C,P,w,d,20,u[23]),w=s(w,N,C,P,y,5,u[24]),P=s(P,w,N,C,j,9,u[25]),C=s(C,P,w,N,l,14,u[26]),N=s(N,C,P,w,m,20,u[27]),w=s(w,N,C,P,S,5,u[28]),P=s(P,w,N,C,h,9,u[29]),C=s(C,P,w,N,b,14,u[30]),w=n(w,N=s(N,C,P,w,O,20,u[31]),C,P,p,4,u[32]),P=n(P,w,N,C,m,11,u[33]),C=n(C,P,w,N,v,16,u[34]),N=n(N,C,P,w,j,23,u[35]),w=n(w,N,C,P,o,4,u[36]),P=n(P,w,N,C,d,11,u[37]),C=n(C,P,w,N,b,16,u[38]),N=n(N,C,P,w,f,23,u[39]),w=n(w,N,C,P,S,4,u[40]),P=n(P,w,N,C,c,11,u[41]),C=n(C,P,w,N,l,16,u[42]),N=n(N,C,P,w,g,23,u[43]),w=n(w,N,C,P,y,4,u[44]),P=n(P,w,N,C,O,11,u[45]),C=n(C,P,w,N,k,16,u[46]),w=r(w,N=n(N,C,P,w,h,23,u[47]),C,P,c,6,u[48]),P=r(P,w,N,C,b,10,u[49]),C=r(C,P,w,N,j,15,u[50]),N=r(N,C,P,w,p,21,u[51]),w=r(w,N,C,P,O,6,u[52]),P=r(P,w,N,C,l,10,u[53]),C=r(C,P,w,N,f,15,u[54]),N=r(N,C,P,w,o,21,u[55]),w=r(w,N,C,P,m,6,u[56]),P=r(P,w,N,C,k,10,u[57]),C=r(C,P,w,N,g,15,u[58]),N=r(N,C,P,w,S,21,u[59]),w=r(w,N,C,P,d,6,u[60]),P=r(P,w,N,C,v,10,u[61]),C=r(C,P,w,N,h,15,u[62]),N=r(N,C,P,w,y,21,u[63]);a[0]=a[0]+w|0,a[1]=a[1]+N|0,a[2]=a[2]+C|0,a[3]=a[3]+P|0},_doFinalize:function(){var t=this._data,s=t.words,n=8*this._nDataBytes,r=8*t.sigBytes;s[r>>>5]|=128<<24-r%32;var i=e.floor(n/4294967296);for(s[15+(r+64>>>9<<4)]=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),s[14+(r+64>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),t.sigBytes=4*(s.length+1),this._process(),s=(t=this._hash).words,n=0;4>n;n++)r=s[n],s[n]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8);return t},clone:function(){var e=o.clone.call(this);return e._hash=this._hash.clone(),e}}),i.MD5=o._createHelper(c),i.HmacMD5=o._createHmacHelper(c)}(Math),function(){var e,t=O,s=(e=t.lib).Base,n=e.WordArray,r=(e=t.algo).EvpKDF=s.extend({cfg:s.extend({keySize:4,hasher:e.MD5,iterations:1}),init:function(e){this.cfg=this.cfg.extend(e)},compute:function(e,t){for(var s=(o=this.cfg).hasher.create(),r=n.create(),i=r.words,a=o.keySize,o=o.iterations;i.length>>2]}},e.BlockCipher=a.extend({cfg:a.cfg.extend({mode:o,padding:u}),reset:function(){a.reset.call(this);var e=(t=this.cfg).iv,t=t.mode;if(this._xformMode==this._ENC_XFORM_MODE)var s=t.createEncryptor;else s=t.createDecryptor,this._minBufferSize=1;this._mode=s.call(t,this,e&&e.words)},_doProcessBlock:function(e,t){this._mode.processBlock(e,t)},_doFinalize:function(){var e=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){e.pad(this._data,this.blockSize);var t=this._process(!0)}else t=this._process(!0),e.unpad(t);return t},blockSize:4});var h=e.CipherParams=t.extend({init:function(e){this.mixIn(e)},toString:function(e){return(e||this.formatter).stringify(this)}}),l=(o=(d.format={}).OpenSSL={stringify:function(e){var t=e.ciphertext;return((e=e.salt)?s.create([1398893684,1701076831]).concat(e).concat(t):t).toString(r)},parse:function(e){var t=(e=r.parse(e)).words;if(1398893684==t[0]&&1701076831==t[1]){var n=s.create(t.slice(2,4));t.splice(0,4),e.sigBytes-=16}return h.create({ciphertext:e,salt:n})}},e.SerializableCipher=t.extend({cfg:t.extend({format:o}),encrypt:function(e,t,s,n){n=this.cfg.extend(n);var r=e.createEncryptor(s,n);return t=r.finalize(t),r=r.cfg,h.create({ciphertext:t,key:s,iv:r.iv,algorithm:e,mode:r.mode,padding:r.padding,blockSize:e.blockSize,formatter:n.format})},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),e.createDecryptor(s,n).finalize(t.ciphertext)},_parse:function(e,t){return"string"==typeof e?t.parse(e,this):e}})),d=(d.kdf={}).OpenSSL={execute:function(e,t,n,r){return r||(r=s.random(8)),e=i.create({keySize:t+n}).compute(e,r),n=s.create(e.words.slice(t),4*n),e.sigBytes=4*t,h.create({key:e,iv:n,salt:r})}},p=e.PasswordBasedCipher=l.extend({cfg:l.cfg.extend({kdf:d}),encrypt:function(e,t,s,n){return s=(n=this.cfg.extend(n)).kdf.execute(s,e.keySize,e.ivSize),n.iv=s.iv,(e=l.encrypt.call(this,e,t,s.key,n)).mixIn(s),e},decrypt:function(e,t,s,n){return n=this.cfg.extend(n),t=this._parse(t,n.format),s=n.kdf.execute(s,e.keySize,e.ivSize,t.salt),n.iv=s.iv,l.decrypt.call(this,e,t,s.key,n)}})}(),function(){for(var e=O,t=e.lib.BlockCipher,s=e.algo,n=[],r=[],i=[],a=[],o=[],c=[],u=[],h=[],l=[],d=[],p=[],g=0;256>g;g++)p[g]=128>g?g<<1:g<<1^283;var b=0,m=0;for(g=0;256>g;g++){var y=(y=m^m<<1^m<<2^m<<3^m<<4)>>>8^255&y^99;n[b]=y,r[y]=b;var f=p[b],v=p[f],S=p[v],j=257*p[y]^16843008*y;i[b]=j<<24|j>>>8,a[b]=j<<16|j>>>16,o[b]=j<<8|j>>>24,c[b]=j,j=16843009*S^65537*v^257*f^16843008*b,u[y]=j<<24|j>>>8,h[y]=j<<16|j>>>16,l[y]=j<<8|j>>>24,d[y]=j,b?(b=f^p[p[p[S^f]]],m^=p[p[m]]):b=m=1}var k=[0,1,2,4,8,16,32,64,128,27,54];s=s.AES=t.extend({_doReset:function(){for(var e=(s=this._key).words,t=s.sigBytes/4,s=4*((this._nRounds=t+6)+1),r=this._keySchedule=[],i=0;i>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a]):(a=n[(a=a<<8|a>>>24)>>>24]<<24|n[a>>>16&255]<<16|n[a>>>8&255]<<8|n[255&a],a^=k[i/t|0]<<24),r[i]=r[i-t]^a}for(e=this._invKeySchedule=[],t=0;tt||4>=i?a:u[n[a>>>24]]^h[n[a>>>16&255]]^l[n[a>>>8&255]]^d[n[255&a]]},encryptBlock:function(e,t){this._doCryptBlock(e,t,this._keySchedule,i,a,o,c,n)},decryptBlock:function(e,t){var s=e[t+1];e[t+1]=e[t+3],e[t+3]=s,this._doCryptBlock(e,t,this._invKeySchedule,u,h,l,d,r),s=e[t+1],e[t+1]=e[t+3],e[t+3]=s},_doCryptBlock:function(e,t,s,n,r,i,a,o){for(var c=this._nRounds,u=e[t]^s[0],h=e[t+1]^s[1],l=e[t+2]^s[2],d=e[t+3]^s[3],p=4,g=1;g>>24]^r[h>>>16&255]^i[l>>>8&255]^a[255&d]^s[p++],m=n[h>>>24]^r[l>>>16&255]^i[d>>>8&255]^a[255&u]^s[p++],y=n[l>>>24]^r[d>>>16&255]^i[u>>>8&255]^a[255&h]^s[p++];d=n[d>>>24]^r[u>>>16&255]^i[h>>>8&255]^a[255&l]^s[p++],u=b,h=m,l=y}b=(o[u>>>24]<<24|o[h>>>16&255]<<16|o[l>>>8&255]<<8|o[255&d])^s[p++],m=(o[h>>>24]<<24|o[l>>>16&255]<<16|o[d>>>8&255]<<8|o[255&u])^s[p++],y=(o[l>>>24]<<24|o[d>>>16&255]<<16|o[u>>>8&255]<<8|o[255&h])^s[p++],d=(o[d>>>24]<<24|o[u>>>16&255]<<16|o[h>>>8&255]<<8|o[255&l])^s[p++],e[t]=b,e[t+1]=m,e[t+2]=y,e[t+3]=d},keySize:8});e.AES=t._createHelper(s)}(),O.mode.ECB=((v=O.lib.BlockCipherMode.extend()).Encryptor=v.extend({processBlock:function(e,t){this._cipher.encryptBlock(e,t)}}),v.Decryptor=v.extend({processBlock:function(e,t){this._cipher.decryptBlock(e,t)}}),v);var S=t(O);class j{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=S,this.encryptedKey=this.CryptoJS.SHA256(e)}encrypt(e){if(0===("string"==typeof e?e:j.decoder.decode(e)).length)throw new Error("encryption error. empty content");const t=this.getIv();return{metadata:t,data:c(this.CryptoJS.AES.encrypt(e,this.encryptedKey,{iv:this.bufferToWordArray(t),mode:this.CryptoJS.mode.CBC}).ciphertext.toString(this.CryptoJS.enc.Base64))}}encryptFileData(e){return i(this,void 0,void 0,(function*(){const t=yield this.getKey(),s=this.getIv();return{data:yield crypto.subtle.encrypt({name:this.algo,iv:s},t,e),metadata:s}}))}decrypt(e){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=this.bufferToWordArray(new Uint8ClampedArray(e.metadata)),s=this.bufferToWordArray(new Uint8ClampedArray(e.data));return j.encoder.encode(this.CryptoJS.AES.decrypt({ciphertext:s},this.encryptedKey,{iv:t,mode:this.CryptoJS.mode.CBC}).toString(this.CryptoJS.enc.Utf8)).buffer}decryptFileData(e){return i(this,void 0,void 0,(function*(){if("string"==typeof e.data)throw new Error("Decryption error: data for decryption should be ArrayBuffed.");const t=yield this.getKey();return crypto.subtle.decrypt({name:this.algo,iv:e.metadata},t,e.data)}))}get identifier(){return"ACRH"}get algo(){return"AES-CBC"}getIv(){return crypto.getRandomValues(new Uint8Array(j.BLOCK_SIZE))}getKey(){return i(this,void 0,void 0,(function*(){const e=j.encoder.encode(this.cipherKey),t=yield crypto.subtle.digest("SHA-256",e.buffer);return crypto.subtle.importKey("raw",t,this.algo,!0,["encrypt","decrypt"])}))}bufferToWordArray(e){const t=[];let s;for(s=0;sk.has(e),P=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),C=(e,t)=>{const s=e.map((e=>P(e)));return s.length?s.join(","):null!=t?t:""},N=(e,t)=>{const s=Object.fromEntries(t.map((e=>[e,!1])));return e.filter((e=>!(t.includes(e)&&!s[e])||(s[e]=!0,!1)))},E=(e,t)=>[...e].filter((s=>t.includes(s)&&e.indexOf(s)===e.lastIndexOf(s)&&t.indexOf(s)===t.lastIndexOf(s))),T=e=>Object.keys(e).map((t=>{const s=e[t];return Array.isArray(s)?s.map((e=>`${t}=${P(e)}`)).join("&"):`${t}=${P(s)}`})).join("&"),_=(e,t)=>{if("0"===t||"0"===e)return;const s=R(`${Date.now()}0000`,t,!1);return R(e,s,!0)},M=(e,t,s)=>{if(e&&0!==e.length){if(t&&t.length>0&&"0"!==t){const n=R(e,t,!1);return R(null!=s?s:`${Date.now()}0000`,n.replace("-",""),Number(n)<0)}return s&&s.length>0&&"0"!==s?s:`${Date.now()}0000`}},R=(e,t,s)=>{t.startsWith("-")&&(t=t.replace("-",""),s=!1),t=t.padStart(17,"0");const n=e.slice(0,10),r=e.slice(10,17),i=t.slice(0,10),a=t.slice(10,17);let o=Number(n),c=Number(r);return o+=Number(i)*(s?1:-1),c+=Number(a)*(s?1:-1),c>=1e7?(o+=Math.floor(c/1e7),c%=1e7):c<0?o>0?(o-=1,c+=1e7):o<0&&(c*=-1):o<0&&c>0&&(o+=1,c=1e7-c),0!==o?`${o}${`${c}`.padStart(7,"0")}`:`${c}`},I=e=>{const t="string"!=typeof e?JSON.stringify(e):e,s=new Uint32Array(1);let n=0,r=t.length;for(;r-- >0;)s[0]=(s[0]<<5)-s[0]+t.charCodeAt(n++);return s[0].toString(16).padStart(8,"0")};function U(e){const t=[];let s;for(s=0;s({messageType:"object",message:this.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||"logger"===e||w(e)})))}get logger(){return this._logger}HMACSHA256(e){return S.HmacSHA256(e,this.configuration.secretKey).toString(S.enc.Base64)}SHA256(e){return S.SHA256(e).toString(S.enc.Hex)}encrypt(e,t,s){return this.configuration.customEncrypt?(this.logger&&this.logger.warn("Crypto","'customEncrypt' is deprecated. Consult docs for better alternative."),this.configuration.customEncrypt(e)):this.pnEncrypt(e,t,s)}decrypt(e,t,s){return this.configuration.customDecrypt?(this.logger&&this.logger.warn("Crypto","'customDecrypt' is deprecated. Consult docs for better alternative."),this.configuration.customDecrypt(e)):this.pnDecrypt(e,t,s)}pnEncrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e},null!=s?s:{}),details:"Encrypt with parameters:",ignoredKeys:w}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=S.AES.encrypt(e,i,{iv:t,mode:r}).ciphertext;return t.clone().concat(s.clone()).toString(S.enc.Base64)}const a=this.getIV(s);return S.AES.encrypt(e,i,{iv:a,mode:r}).ciphertext.toString(S.enc.Base64)||e}pnDecrypt(e,t,s){const n=null!=t?t:this.configuration.cipherKey;if(!n)return e;this.logger&&this.logger.debug("Crypto",(()=>({messageType:"object",message:Object.assign({data:e},null!=s?s:{}),details:"Decrypt with parameters:",ignoredKeys:w}))),s=this.parseOptions(s);const r=this.getMode(s),i=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=new Uint8ClampedArray(c(e)),s=U(t.slice(0,16)),n=U(t.slice(16));try{const e=S.AES.decrypt({ciphertext:n},i,{iv:s,mode:r}).toString(S.enc.Utf8);return JSON.parse(e)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}else{const t=this.getIV(s);try{const s=S.enc.Base64.parse(e),n=S.AES.decrypt({ciphertext:s},i,{iv:t,mode:r}).toString(S.enc.Utf8);return JSON.parse(n)}catch(e){return this.logger&&this.logger.error("Crypto",(()=>({messageType:"error",message:e}))),null}}}parseOptions(e){var t,s,n,r;if(!e)return this.defaultOptions;const i={encryptKey:null!==(t=e.encryptKey)&&void 0!==t?t:this.defaultOptions.encryptKey,keyEncoding:null!==(s=e.keyEncoding)&&void 0!==s?s:this.defaultOptions.keyEncoding,keyLength:null!==(n=e.keyLength)&&void 0!==n?n:this.defaultOptions.keyLength,mode:null!==(r=e.mode)&&void 0!==r?r:this.defaultOptions.mode};return-1===this.allowedKeyEncodings.indexOf(i.keyEncoding.toLowerCase())&&(i.keyEncoding=this.defaultOptions.keyEncoding),-1===this.allowedKeyLengths.indexOf(i.keyLength)&&(i.keyLength=this.defaultOptions.keyLength),-1===this.allowedModes.indexOf(i.mode.toLowerCase())&&(i.mode=this.defaultOptions.mode),i}decodeKey(e,t){return"base64"===t.keyEncoding?S.enc.Base64.parse(e):"hex"===t.keyEncoding?S.enc.Hex.parse(e):e}getPaddedKey(e,t){return e=this.decodeKey(e,t),t.encryptKey?S.enc.Utf8.parse(this.SHA256(e).slice(0,32)):e}getMode(e){return"ecb"===e.mode?S.mode.ECB:S.mode.CBC}getIV(e){return"cbc"===e.mode?S.enc.Utf8.parse(this.iv):null}getRandomIV(){return S.lib.WordArray.random(16)}}class ${encrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot encrypt this file. In browsers file encryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.encryptArrayBuffer(s,t):this.encryptString(s,t)}))}encryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16));return this.concatArrayBuffer(s.buffer,yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,t))}))}encryptString(e,t){return i(this,void 0,void 0,(function*(){const s=crypto.getRandomValues(new Uint8Array(16)),n=$.encoder.encode(t).buffer,r=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),i=this.concatArrayBuffer(s.buffer,r);return $.decoder.decode(i)}))}encryptFile(e,t,s){return i(this,void 0,void 0,(function*(){var n,r;if((null!==(n=t.contentLength)&&void 0!==n?n:0)<=0)throw new Error("encryption error. empty content");const i=yield this.getKey(e),a=yield t.toArrayBuffer(),o=yield this.encryptArrayBuffer(i,a);return s.create({name:t.name,mimeType:null!==(r=t.mimeType)&&void 0!==r?r:"application/octet-stream",data:o})}))}decrypt(e,t){return i(this,void 0,void 0,(function*(){if(!(t instanceof ArrayBuffer)&&"string"!=typeof t)throw new Error("Cannot decrypt this file. In browsers file decryption supports only string or ArrayBuffer");const s=yield this.getKey(e);return t instanceof ArrayBuffer?this.decryptArrayBuffer(s,t):this.decryptString(s,t)}))}decryptArrayBuffer(e,t){return i(this,void 0,void 0,(function*(){const s=t.slice(0,16);if(t.slice($.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice($.IV_LENGTH))}))}decryptString(e,t){return i(this,void 0,void 0,(function*(){const s=$.encoder.encode(t).buffer,n=s.slice(0,16),r=s.slice(16),i=yield crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,r);return $.decoder.decode(i)}))}decryptFile(e,t,s){return i(this,void 0,void 0,(function*(){const n=yield this.getKey(e),r=yield t.toArrayBuffer(),i=yield this.decryptArrayBuffer(n,r);return s.create({name:t.name,mimeType:t.mimeType,data:i})}))}getKey(e){return i(this,void 0,void 0,(function*(){const t=yield crypto.subtle.digest("SHA-256",$.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=$.encoder.encode(s.slice(0,32)).buffer;return crypto.subtle.importKey("raw",n,"AES-CBC",!0,["encrypt","decrypt"])}))}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}}$.IV_LENGTH=16,$.encoder=new TextEncoder,$.decoder=new TextDecoder;class D{constructor(e){this.config=e,this.cryptor=new A(Object.assign({},e)),this.fileCryptor=new $}set logger(e){this.cryptor.logger=e,!1===this.config.useRandomIVs&&e.warn("LegacyCryptor","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")}encrypt(e){const t="string"==typeof e?e:D.decoder.decode(e);return{data:this.cryptor.encrypt(t),metadata:null}}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.encryptFile(null===(s=this.config)||void 0===s?void 0:s.cipherKey,e,t)}))}decrypt(e){const t="string"==typeof e.data?e.data:u(e.data);return this.cryptor.decrypt(t)}decryptFile(e,t){return i(this,void 0,void 0,(function*(){if(!this.config.cipherKey)throw new d("File encryption error: cipher key not set.");return this.fileCryptor.decryptFile(this.config.cipherKey,e,t)}))}get identifier(){return""}toString(){return`LegacyCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||w(t)||e.push(`${t}: ${"function"==typeof s?"":s}`),e)),[]).join(", ")} }`}}D.encoder=new TextEncoder,D.decoder=new TextDecoder;class F extends a{set logger(e){if(this.defaultCryptor.identifier===F.LEGACY_IDENTIFIER)e.warn("CryptoModule","'legacyCryptoModule' is deprecated. Use 'aesCbcCryptoModule' instead for new applications."),this.defaultCryptor.logger=e;else{const t=this.cryptors.find((e=>e.identifier===F.LEGACY_IDENTIFIER));t&&(t.logger=e)}}static legacyCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return e.logger&&(e.logger.warn("CryptoModule","'legacyCryptoModule' is deprecated. Use 'aesCbcCryptoModule' instead for new applications."),!1===e.useRandomIVs&&e.logger.warn("CryptoModule","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")),new F({default:new D(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t})),cryptors:[new j({cipherKey:e.cipherKey})]})}static aesCbcCryptoModule(e){var t;if(!e.cipherKey)throw new d("Crypto module error: cipher key not set.");return new F({default:new j({cipherKey:e.cipherKey}),cryptors:[new D(Object.assign(Object.assign({},e),{useRandomIVs:null===(t=e.useRandomIVs)||void 0===t||t}))]})}static withDefaultCryptor(e){return new this({default:e})}encrypt(e){const t=e instanceof ArrayBuffer&&this.defaultCryptor.identifier===F.LEGACY_IDENTIFIER?this.defaultCryptor.encrypt(F.decoder.decode(e)):this.defaultCryptor.encrypt(e);if(!t.metadata)return t.data;if("string"==typeof t.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");const s=this.getHeaderData(t);return this.concatArrayBuffer(s,t.data)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){if(this.defaultCryptor.identifier===x.LEGACY_IDENTIFIER)return this.defaultCryptor.encryptFile(e,t);const s=yield this.getFileData(e),n=yield this.defaultCryptor.encryptFileData(s);if("string"==typeof n.data)throw new Error("Encryption error: encrypted data should be ArrayBuffed.");return t.create({name:e.name,mimeType:"application/octet-stream",data:this.concatArrayBuffer(this.getHeaderData(n),n.data)})}))}decrypt(e){const t="string"==typeof e?c(e):e,s=x.tryParse(t),n=this.getCryptor(s),r=s.length>0?t.slice(s.length-s.metadataLength,s.length):null;if(t.slice(s.length).byteLength<=0)throw new Error("Decryption error: empty content");return n.decrypt({data:t.slice(s.length),metadata:r})}decryptFile(e,t){return i(this,void 0,void 0,(function*(){const s=yield e.data.arrayBuffer(),n=x.tryParse(s),r=this.getCryptor(n);if((null==r?void 0:r.identifier)===x.LEGACY_IDENTIFIER)return r.decryptFile(e,t);const i=(yield this.getFileData(s)).slice(n.length-n.metadataLength,n.length);return t.create({name:e.name,data:yield this.defaultCryptor.decryptFileData({data:s.slice(n.length),metadata:i})})}))}getCryptorFromId(e){const t=this.getAllCryptors().find((t=>e===t.identifier));if(t)return t;throw Error("Unknown cryptor error")}getCryptor(e){if("string"==typeof e){const t=this.getAllCryptors().find((t=>t.identifier===e));if(t)return t;throw new Error("Unknown cryptor error")}if(e instanceof q)return this.getCryptorFromId(e.identifier)}getHeaderData(e){if(!e.metadata)return;const t=x.from(this.defaultCryptor.identifier,e.metadata),s=new Uint8Array(t.length);let n=0;return s.set(t.data,n),n+=t.length-e.metadata.byteLength,s.set(new Uint8Array(e.metadata),n),s.buffer}concatArrayBuffer(e,t){const s=new Uint8Array(e.byteLength+t.byteLength);return s.set(new Uint8Array(e),0),s.set(new Uint8Array(t),e.byteLength),s.buffer}getFileData(e){return i(this,void 0,void 0,(function*(){if(e instanceof ArrayBuffer)return e;if(e instanceof o)return e.toArrayBuffer();throw new Error("Cannot decrypt/encrypt file. In browsers file encrypt/decrypt supported for string, ArrayBuffer or Blob")}))}}F.LEGACY_IDENTIFIER="";class x{static from(e,t){if(e!==x.LEGACY_IDENTIFIER)return new q(e,t.byteLength)}static tryParse(e){const t=new Uint8Array(e);let s,n,r=null;if(t.byteLength>=4&&(s=t.slice(0,4),this.decoder.decode(s)!==x.SENTINEL))return F.LEGACY_IDENTIFIER;if(!(t.byteLength>=5))throw new Error("Decryption error: invalid header version");if(r=t[4],r>x.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let i=5+x.IDENTIFIER_LENGTH;if(!(t.byteLength>=i))throw new Error("Decryption error: invalid crypto identifier");n=t.slice(5,i);let a=null;if(!(t.byteLength>=i+1))throw new Error("Decryption error: invalid metadata length");return a=t[i],i+=1,255===a&&t.byteLength>=i+2&&(a=new Uint16Array(t.slice(i,i+2)).reduce(((e,t)=>(e<<8)+t),0)),new q(this.decoder.decode(n),a)}}x.SENTINEL="PNED",x.LEGACY_IDENTIFIER="",x.IDENTIFIER_LENGTH=4,x.VERSION=1,x.MAX_VERSION=1,x.decoder=new TextDecoder;class q{constructor(e,t){this._identifier=e,this._metadataLength=t}get identifier(){return this._identifier}set identifier(e){this._identifier=e}get metadataLength(){return this._metadataLength}set metadataLength(e){this._metadataLength=e}get version(){return x.VERSION}get length(){return x.SENTINEL.length+1+x.IDENTIFIER_LENGTH+(this.metadataLength<255?1:3)+this.metadataLength}get data(){let e=0;const t=new Uint8Array(this.length),s=new TextEncoder;t.set(s.encode(x.SENTINEL)),e+=x.SENTINEL.length,t[e]=this.version,e++,this.identifier&&t.set(s.encode(this.identifier),e);const n=this.metadataLength;return e+=x.IDENTIFIER_LENGTH,n<255?t[e]=n:t.set([255,n>>8,255&n],e),t}}q.IDENTIFIER_LENGTH=4,q.SENTINEL="PNED";class G extends Error{static create(e,t){return G.isErrorObject(e)?G.createFromError(e):G.createFromServiceResponse(e,t)}static createFromError(e){let t=l.PNUnknownCategory,s="Unknown error",n="Error";if(!e)return new G(s,t,0);if(e instanceof G)return e;if(G.isErrorObject(e)&&(s=e.message,n=e.name),"AbortError"===n||-1!==s.indexOf("Aborted"))t=l.PNCancelledCategory,s="Request cancelled";else if(-1!==s.toLowerCase().indexOf("timeout"))t=l.PNTimeoutCategory,s="Request timeout";else if(-1!==s.toLowerCase().indexOf("network"))t=l.PNNetworkIssuesCategory,s="Network issues";else if("TypeError"===n)t=-1!==s.indexOf("Load failed")||-1!=s.indexOf("Failed to fetch")?l.PNNetworkIssuesCategory:l.PNBadRequestCategory;else if("FetchError"===n){const n=e.code;["ECONNREFUSED","ENETUNREACH","ENOTFOUND","ECONNRESET","EAI_AGAIN"].includes(n)&&(t=l.PNNetworkIssuesCategory),"ECONNREFUSED"===n?s="Connection refused":"ENETUNREACH"===n?s="Network not reachable":"ENOTFOUND"===n?s="Server not found":"ECONNRESET"===n?s="Connection reset by peer":"EAI_AGAIN"===n?s="Name resolution error":"ETIMEDOUT"===n?(t=l.PNTimeoutCategory,s="Request timeout"):s=`Unknown system error: ${e}`}else"Request timeout"===s&&(t=l.PNTimeoutCategory);return new G(s,t,0,e)}static createFromServiceResponse(e,t){let s,n=l.PNUnknownCategory,r="Unknown error",{status:i}=e;if(null!=t||(t=e.body),402===i?r="Not available for used key set. Contact support@pubnub.com":404===i?r="Resource not found":400===i?(n=l.PNBadRequestCategory,r="Bad request"):403===i?(n=l.PNAccessDeniedCategory,r="Access denied"):i>=500&&(n=l.PNServerErrorCategory,r="Internal server error"),"object"==typeof e&&0===Object.keys(e).length&&(n=l.PNMalformedResponseCategory,r="Malformed response (network issues)",i=400),t&&t.byteLength>0){const n=(new TextDecoder).decode(t);if(-1!==e.headers["content-type"].indexOf("text/javascript")||-1!==e.headers["content-type"].indexOf("application/json"))try{const e=JSON.parse(n);if("object"==typeof e)if(Array.isArray(e))"number"==typeof e[0]&&0===e[0]&&e.length>1&&"string"==typeof e[1]&&(s=e[1]);else{if("error"in e&&(1===e.error||!0===e.error)&&"status"in e&&"number"==typeof e.status&&"message"in e&&"service"in e)s=e,i=e.status;else if("errors"in e&&Array.isArray(e.errors)&&e.errors.length>0){s=e;r=e.errors.map((e=>{const t=[];return e.errorCode&&t.push(e.errorCode),e.message&&t.push(e.message),t.join(": ")})).join("; ")}else s=e;"error"in e&&e.error instanceof Error&&(s=e.error)}}catch(e){s=n}else if(-1!==e.headers["content-type"].indexOf("xml")){const e=/(.*)<\/Message>/gi.exec(n);r=e?`Upload to bucket failed: ${e[1]}`:"Upload to bucket failed."}else s=n}return new G(r,n,i,s)}constructor(e,t,s,n){super(e),this.category=t,this.statusCode=s,this.errorData=n,this.name="PubNubAPIError"}toStatus(e){return{error:!0,category:this.category,operation:e,statusCode:this.statusCode,errorData:this.errorData,toJSON:function(){let e;const t=this.errorData;if(t)try{if("object"==typeof t){const s=Object.assign(Object.assign(Object.assign(Object.assign({},"name"in t?{name:t.name}:{}),"message"in t?{message:t.message}:{}),"stack"in t?{stack:t.stack}:{}),t);e=JSON.parse(JSON.stringify(s,G.circularReplacer()))}else e=t}catch(t){e={error:"Could not serialize the error object"}}const s=r(this,["toJSON"]);return JSON.stringify(Object.assign(Object.assign({},s),{errorData:e}))}}}toFormattedMessage(e){return this.errorData&&"object"==typeof this.errorData&&!("name"in this.errorData&&"message"in this.errorData&&"stack"in this.errorData)&&"errors"in this.errorData&&Array.isArray(this.errorData.errors)?`${e}: ${this.message}`:"REST API request processing error, check status for details"}toPubNubError(e,t){return new d(null!=t?t:this.message,this.toStatus(e))}static circularReplacer(){const e=new WeakSet;return function(t,s){if("object"==typeof s&&null!==s){if(e.has(s))return"[Circular]";e.add(s)}return s}}static isErrorObject(e){return!(!e||"object"!=typeof e)&&(e instanceof Error||("name"in e&&"message"in e&&"string"==typeof e.name&&"string"==typeof e.message||"[object Error]"===Object.prototype.toString.call(e)))}}var L;!function(e){e.PNPublishOperation="PNPublishOperation",e.PNSignalOperation="PNSignalOperation",e.PNSubscribeOperation="PNSubscribeOperation",e.PNUnsubscribeOperation="PNUnsubscribeOperation",e.PNWhereNowOperation="PNWhereNowOperation",e.PNHereNowOperation="PNHereNowOperation",e.PNGlobalHereNowOperation="PNGlobalHereNowOperation",e.PNSetStateOperation="PNSetStateOperation",e.PNGetStateOperation="PNGetStateOperation",e.PNHeartbeatOperation="PNHeartbeatOperation",e.PNAddMessageActionOperation="PNAddActionOperation",e.PNRemoveMessageActionOperation="PNRemoveMessageActionOperation",e.PNGetMessageActionsOperation="PNGetMessageActionsOperation",e.PNTimeOperation="PNTimeOperation",e.PNHistoryOperation="PNHistoryOperation",e.PNDeleteMessagesOperation="PNDeleteMessagesOperation",e.PNFetchMessagesOperation="PNFetchMessagesOperation",e.PNMessageCounts="PNMessageCountsOperation",e.PNGetAllUUIDMetadataOperation="PNGetAllUUIDMetadataOperation",e.PNGetUUIDMetadataOperation="PNGetUUIDMetadataOperation",e.PNSetUUIDMetadataOperation="PNSetUUIDMetadataOperation",e.PNRemoveUUIDMetadataOperation="PNRemoveUUIDMetadataOperation",e.PNGetAllChannelMetadataOperation="PNGetAllChannelMetadataOperation",e.PNGetChannelMetadataOperation="PNGetChannelMetadataOperation",e.PNSetChannelMetadataOperation="PNSetChannelMetadataOperation",e.PNRemoveChannelMetadataOperation="PNRemoveChannelMetadataOperation",e.PNGetMembersOperation="PNGetMembersOperation",e.PNSetMembersOperation="PNSetMembersOperation",e.PNGetMembershipsOperation="PNGetMembershipsOperation",e.PNSetMembershipsOperation="PNSetMembershipsOperation",e.PNCreateEntityOperation="PNCreateEntityOperation",e.PNGetEntityOperation="PNGetEntityOperation",e.PNGetAllEntitiesOperation="PNGetAllEntitiesOperation",e.PNUpdateEntityOperation="PNUpdateEntityOperation",e.PNPatchEntityOperation="PNPatchEntityOperation",e.PNRemoveEntityOperation="PNRemoveEntityOperation",e.PNCreateRelationshipOperation="PNCreateRelationshipOperation",e.PNGetRelationshipOperation="PNGetRelationshipOperation",e.PNGetAllRelationshipsOperation="PNGetAllRelationshipsOperation",e.PNUpdateRelationshipOperation="PNUpdateRelationshipOperation",e.PNPatchRelationshipOperation="PNPatchRelationshipOperation",e.PNRemoveRelationshipOperation="PNRemoveRelationshipOperation",e.PNCreateUserOperation="PNCreateUserOperation",e.PNGetUserOperation="PNGetUserOperation",e.PNGetAllUsersOperation="PNGetAllUsersOperation",e.PNUpdateUserOperation="PNUpdateUserOperation",e.PNPatchUserOperation="PNPatchUserOperation",e.PNRemoveUserOperation="PNRemoveUserOperation",e.PNCreateChannelOperation="PNCreateChannelOperation",e.PNGetChannelOperation="PNGetChannelOperation",e.PNGetAllChannelsOperation="PNGetAllChannelsOperation",e.PNUpdateChannelOperation="PNUpdateChannelOperation",e.PNPatchChannelOperation="PNPatchChannelOperation",e.PNRemoveChannelOperation="PNRemoveChannelOperation",e.PNCreateMembershipOperation="PNCreateMembershipOperation",e.PNGetMembershipOperation="PNGetMembershipOperation",e.PNGetAllMembershipsOperation="PNGetAllMembershipsOperation",e.PNUpdateMembershipOperation="PNUpdateMembershipOperation",e.PNPatchMembershipOperation="PNPatchMembershipOperation",e.PNRemoveMembershipOperation="PNRemoveMembershipOperation",e.PNListFilesOperation="PNListFilesOperation",e.PNGenerateUploadUrlOperation="PNGenerateUploadUrlOperation",e.PNPublishFileOperation="PNPublishFileOperation",e.PNPublishFileMessageOperation="PNPublishFileMessageOperation",e.PNGetFileUrlOperation="PNGetFileUrlOperation",e.PNDownloadFileOperation="PNDownloadFileOperation",e.PNDeleteFileOperation="PNDeleteFileOperation",e.PNAddPushNotificationEnabledChannelsOperation="PNAddPushNotificationEnabledChannelsOperation",e.PNRemovePushNotificationEnabledChannelsOperation="PNRemovePushNotificationEnabledChannelsOperation",e.PNPushNotificationEnabledChannelsOperation="PNPushNotificationEnabledChannelsOperation",e.PNRemoveAllPushNotificationsOperation="PNRemoveAllPushNotificationsOperation",e.PNChannelGroupsOperation="PNChannelGroupsOperation",e.PNRemoveGroupOperation="PNRemoveGroupOperation",e.PNChannelsForGroupOperation="PNChannelsForGroupOperation",e.PNAddChannelsToGroupOperation="PNAddChannelsToGroupOperation",e.PNRemoveChannelsFromGroupOperation="PNRemoveChannelsFromGroupOperation",e.PNAccessManagerGrant="PNAccessManagerGrant",e.PNAccessManagerGrantToken="PNAccessManagerGrantToken",e.PNAccessManagerAudit="PNAccessManagerAudit",e.PNAccessManagerRevokeToken="PNAccessManagerRevokeToken",e.PNHandshakeOperation="PNHandshakeOperation",e.PNReceiveMessagesOperation="PNReceiveMessagesOperation"}(L||(L={}));var K=L;class H{constructor(e){this.configuration=e,this.subscriptionWorkerReady=!1,this.accessTokensMap={},this.workerEventsQueue=[],this.callbacks=new Map,this.setupSubscriptionWorker()}set emitStatus(e){this._emitStatus=e}onUserIdChange(e){this.configuration.userId=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onPresenceStateChange(e){this.scheduleEventPost({type:"client-presence-state-update",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel,state:e})}onHeartbeatIntervalChange(e){this.configuration.heartbeatInterval=e,this.scheduleEventPost({type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel})}onTokenChange(e){const t={type:"client-update",heartbeatInterval:this.configuration.heartbeatInterval,clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,workerLogLevel:this.configuration.workerLogLevel};this.parsedAccessToken(e).then((s=>{t.preProcessedToken=s,t.accessToken=e})).then((()=>this.scheduleEventPost(t)))}disconnect(){this.scheduleEventPost({type:"client-disconnect",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}terminate(){this.scheduleEventPost({type:"client-unregister",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,workerLogLevel:this.configuration.workerLogLevel})}makeSendable(e){if(!e.path.startsWith("/v2/subscribe")&&!e.path.endsWith("/heartbeat")&&!e.path.endsWith("/leave"))return this.configuration.transport.makeSendable(e);let t;this.configuration.logger.debug("SubscriptionWorkerMiddleware","Process request with SharedWorker transport.");const s={type:"send-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,request:e,workerLogLevel:this.configuration.workerLogLevel};return e.cancellable&&(t={abort:()=>{const t={type:"cancel-request",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,identifier:e.identifier,workerLogLevel:this.configuration.workerLogLevel};this.scheduleEventPost(t)}}),[new Promise(((t,n)=>{this.callbacks.set(e.identifier,{resolve:t,reject:n}),this.parsedAccessTokenForRequest(e).then((e=>s.preProcessedToken=e)).then((()=>this.scheduleEventPost(s)))})),t]}request(e){return e}scheduleEventPost(e,t=!1){const s=this.sharedSubscriptionWorker;s?s.port.postMessage(e):t?this.workerEventsQueue.splice(0,0,e):this.workerEventsQueue.push(e)}flushScheduledEvents(){const e=this.sharedSubscriptionWorker;if(!e||0===this.workerEventsQueue.length)return;const t=[];for(let e=0;e!t.includes(e))),this.workerEventsQueue.forEach((t=>e.port.postMessage(t))),this.workerEventsQueue=[]}get sharedSubscriptionWorker(){return this.subscriptionWorkerReady?this.subscriptionWorker:null}setupSubscriptionWorker(){if("undefined"!=typeof SharedWorker){try{this.subscriptionWorker=new SharedWorker(this.configuration.workerUrl,`/pubnub-${this.configuration.sdkVersion}`)}catch(e){throw this.configuration.logger.error("SubscriptionWorkerMiddleware",(()=>({messageType:"error",message:e}))),e}this.subscriptionWorker.port.start(),this.scheduleEventPost({type:"client-register",clientIdentifier:this.configuration.clientIdentifier,subscriptionKey:this.configuration.subscriptionKey,userId:this.configuration.userId,heartbeatInterval:this.configuration.heartbeatInterval,workerOfflineClientsCheckInterval:this.configuration.workerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:this.configuration.workerUnsubscribeOfflineClients,workerLogLevel:this.configuration.workerLogLevel},!0),this.subscriptionWorker.port.onmessage=e=>this.handleWorkerEvent(e),this.shouldAnnounceNewerSharedWorkerVersionAvailability()&&localStorage.setItem("PNSubscriptionSharedWorkerVersion",this.configuration.sdkVersion),window.addEventListener("storage",(e=>{"PNSubscriptionSharedWorkerVersion"===e.key&&e.newValue&&this._emitStatus&&this.isNewerSharedWorkerVersion(e.newValue)&&this._emitStatus({error:!1,category:l.PNSharedWorkerUpdatedCategory})}))}}handleWorkerEvent(e){const{data:t}=e;if("shared-worker-ping"===t.type||"shared-worker-connected"===t.type||"shared-worker-console-log"===t.type||"shared-worker-console-dir"===t.type||t.clientIdentifier===this.configuration.clientIdentifier)if("shared-worker-connected"===t.type)this.configuration.logger.trace("SharedWorker","Ready for events processing."),this.subscriptionWorkerReady=!0,this.flushScheduledEvents();else if("shared-worker-console-log"===t.type)this.configuration.logger.debug("SharedWorker",(()=>"string"==typeof t.message||"number"==typeof t.message||"boolean"==typeof t.message?{messageType:"text",message:t.message}:t.message));else if("shared-worker-console-dir"===t.type)this.configuration.logger.debug("SharedWorker",(()=>({messageType:"object",message:t.data,details:t.message?t.message:void 0})));else if("shared-worker-ping"===t.type){const{subscriptionKey:e,clientIdentifier:t}=this.configuration;this.scheduleEventPost({type:"client-pong",subscriptionKey:e,clientIdentifier:t,workerLogLevel:this.configuration.workerLogLevel})}else if("request-process-success"===t.type||"request-process-error"===t.type)if(this.callbacks.has(t.identifier)){const{resolve:e,reject:s}=this.callbacks.get(t.identifier);this.callbacks.delete(t.identifier),"request-process-success"===t.type?e({status:t.response.status,url:t.url,headers:t.response.headers,body:t.response.body}):s(this.errorFromRequestSendingError(t))}else this._emitStatus&&t.url.indexOf("/v2/presence")>=0&&t.url.indexOf("/heartbeat")>=0&&("request-process-success"===t.type&&this.configuration.announceSuccessfulHeartbeats?this._emitStatus({statusCode:t.response.status,error:!1,operation:K.PNHeartbeatOperation,category:l.PNAcknowledgmentCategory}):"request-process-error"===t.type&&this.configuration.announceFailedHeartbeats&&this._emitStatus(this.errorFromRequestSendingError(t).toStatus(K.PNHeartbeatOperation)))}parsedAccessTokenForRequest(e){return i(this,void 0,void 0,(function*(){var t;return this.parsedAccessToken(e.queryParameters?null!==(t=e.queryParameters.auth)&&void 0!==t?t:"":void 0)}))}parsedAccessToken(e){return i(this,void 0,void 0,(function*(){if(e)return this.accessTokensMap[e]?this.accessTokensMap[e]:this.stringifyAccessToken(e).then((([t,s])=>{if(t&&s)return(this.accessTokensMap={[e]:{token:s,expiration:t.timestamp+60*t.ttl}})[e]}))}))}stringifyAccessToken(e){return i(this,void 0,void 0,(function*(){if(!this.configuration.tokenManager)return[void 0,void 0];const t=this.configuration.tokenManager.parseToken(e);if(!t)return[void 0,void 0];const s=e=>e?Object.entries(e).sort((([e],[t])=>e.localeCompare(t))).map((([e,t])=>Object.entries(t||{}).sort((([e],[t])=>e.localeCompare(t))).map((([t,s])=>{return`${e}:${t}=${s?(n=s,Object.entries(n).filter((([e,t])=>t)).map((([e])=>e[0])).sort().join("")):""}`;var n})).join(","))).join(";"):"";let n=[s(t.resources),s(t.patterns),t.authorized_uuid].filter(Boolean).join("|");if("undefined"!=typeof crypto&&crypto.subtle){const e=yield crypto.subtle.digest("SHA-256",(new TextEncoder).encode(n));n=String.fromCharCode(...Array.from(new Uint8Array(e)))}return[t,"undefined"!=typeof btoa?btoa(n):n]}))}errorFromRequestSendingError(e){let t=l.PNUnknownCategory,s="Unknown error";if(e.error)"NETWORK_ISSUE"===e.error.type?t=l.PNNetworkIssuesCategory:"TIMEOUT"===e.error.type?t=l.PNTimeoutCategory:"ABORTED"===e.error.type&&(t=l.PNCancelledCategory),s=`${e.error.message} (${e.identifier})`;else if(e.response){const{url:t,response:s}=e;return G.create({url:t,headers:s.headers,body:s.body,status:s.status},s.body)}return new G(s,t,0,new Error(s))}shouldAnnounceNewerSharedWorkerVersionAvailability(){const e=localStorage.getItem("PNSubscriptionSharedWorkerVersion");return!e||!this.isNewerSharedWorkerVersion(e)}isNewerSharedWorkerVersion(e){const[t,s,n]=this.configuration.sdkVersion.split(".").map(Number),[r,i,a]=e.split(".").map(Number);return r>t||i>s||a>n}}function B(e,t=0){const s=e=>"object"==typeof e&&null!==e&&e.constructor===Object,n=e=>"number"==typeof e&&isFinite(e);if(!s(e))return e;const r={};return Object.keys(e).forEach((i=>{const a=(e=>"string"==typeof e||e instanceof String)(i);let o=i;const c=e[i];if(t<2)if(a&&i.indexOf(",")>=0){o=i.split(",").map(Number).reduce(((e,t)=>e+String.fromCharCode(t)),"")}else(n(i)||a&&!isNaN(Number(i)))&&(o=String.fromCharCode(n(i)?i:parseInt(i,10)));r[o]=s(c)?B(c,t+1):c})),r}const W=e=>{var t,s,n,r,i,a;return e.subscriptionWorkerUrl&&"undefined"==typeof SharedWorker&&(e.subscriptionWorkerUrl=null),Object.assign(Object.assign({},(e=>{var t,s,n,r,i,a,o,c,u,h,l,p,g,b,m;const y=Object.assign({},e);if(null!==(t=y.ssl)&&void 0!==t||(y.ssl=!0),null!==(s=y.transactionalRequestTimeout)&&void 0!==s||(y.transactionalRequestTimeout=15),null!==(n=y.subscribeRequestTimeout)&&void 0!==n||(y.subscribeRequestTimeout=310),null!==(r=y.fileRequestTimeout)&&void 0!==r||(y.fileRequestTimeout=300),null!==(i=y.restore)&&void 0!==i||(y.restore=!0),null!==(a=y.useInstanceId)&&void 0!==a||(y.useInstanceId=!1),null!==(o=y.suppressLeaveEvents)&&void 0!==o||(y.suppressLeaveEvents=!1),null!==(c=y.requestMessageCountThreshold)&&void 0!==c||(y.requestMessageCountThreshold=100),null!==(u=y.autoNetworkDetection)&&void 0!==u||(y.autoNetworkDetection=!1),null!==(h=y.enableEventEngine)&&void 0!==h||(y.enableEventEngine=!0),null!==(l=y.maintainPresenceState)&&void 0!==l||(y.maintainPresenceState=!0),null!==(p=y.useSmartHeartbeat)&&void 0!==p||(y.useSmartHeartbeat=!1),null!==(g=y.keepAlive)&&void 0!==g||(y.keepAlive=!1),y.userId&&y.uuid)throw new d("PubNub client configuration error: use only 'userId'");if(null!==(b=y.userId)&&void 0!==b||(y.userId=y.uuid),!y.userId)throw new d("PubNub client configuration error: 'userId' not set");if(0===(null===(m=y.userId)||void 0===m?void 0:m.trim().length))throw new d("PubNub client configuration error: 'userId' is empty");y.origin||(y.origin=Array.from({length:20},((e,t)=>`ps${t+1}.pndsn.com`)));const f={subscribeKey:y.subscribeKey,publishKey:y.publishKey,secretKey:y.secretKey};void 0!==y.presenceTimeout&&(y.presenceTimeout>320?(y.presenceTimeout=320,console.warn("WARNING: Presence timeout is larger than the maximum. Using maximum value: ",320)):y.presenceTimeout<=0&&(console.warn("WARNING: Presence timeout should be larger than zero."),delete y.presenceTimeout)),void 0!==y.presenceTimeout?y.heartbeatInterval=y.presenceTimeout/2-1:y.presenceTimeout=300;let v=!1,O=!0,S=5,j=!1,k=100,w=!0;return void 0!==y.dedupeOnSubscribe&&"boolean"==typeof y.dedupeOnSubscribe&&(j=y.dedupeOnSubscribe),void 0!==y.maximumCacheSize&&"number"==typeof y.maximumCacheSize&&(k=y.maximumCacheSize),void 0!==y.useRequestId&&"boolean"==typeof y.useRequestId&&(w=y.useRequestId),void 0!==y.announceSuccessfulHeartbeats&&"boolean"==typeof y.announceSuccessfulHeartbeats&&(v=y.announceSuccessfulHeartbeats),void 0!==y.announceFailedHeartbeats&&"boolean"==typeof y.announceFailedHeartbeats&&(O=y.announceFailedHeartbeats),void 0!==y.fileUploadPublishRetryLimit&&"number"==typeof y.fileUploadPublishRetryLimit&&(S=y.fileUploadPublishRetryLimit),Object.assign(Object.assign({},y),{keySet:f,dedupeOnSubscribe:j,maximumCacheSize:k,useRequestId:w,announceSuccessfulHeartbeats:v,announceFailedHeartbeats:O,fileUploadPublishRetryLimit:S})})(e)),{listenToBrowserNetworkEvents:null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t,subscriptionWorkerUrl:e.subscriptionWorkerUrl,subscriptionWorkerOfflineClientsCheckInterval:null!==(s=e.subscriptionWorkerOfflineClientsCheckInterval)&&void 0!==s?s:10,subscriptionWorkerUnsubscribeOfflineClients:null!==(n=e.subscriptionWorkerUnsubscribeOfflineClients)&&void 0!==n&&n,subscriptionWorkerLogVerbosity:null!==(r=e.subscriptionWorkerLogVerbosity)&&void 0!==r&&r,transport:null!==(i=e.transport)&&void 0!==i?i:"fetch",keepAlive:null===(a=e.keepAlive)||void 0===a||a})};var V,z;!function(e){e[e.Trace=0]="Trace",e[e.Debug=1]="Debug",e[e.Info=2]="Info",e[e.Warn=3]="Warn",e[e.Error=4]="Error",e[e.None=5]="None"}(V||(V={}));class J{debug(e){this.log(e)}error(e){this.log(e)}info(e){this.log(e)}trace(e){this.log(e)}warn(e){this.log(e)}toString(){return"ConsoleLogger {}"}log(e){const t=V[e.level],s=t.toLowerCase();console["trace"===s?"debug":s](`${e.timestamp.toISOString()} PubNub-${e.pubNubId} ${t.padEnd(5," ")}${e.location?` ${e.location}`:""} ${this.logMessage(e)}`)}logMessage(e){if("text"===e.messageType)return e.message;if("object"===e.messageType)return`${e.details?`${e.details}\n`:""}${this.formattedObject(e)}`;if("network-request"===e.messageType){const t=!!e.canceled||!!e.failed,s=e.minimumLevel!==V.Trace||t?void 0:this.formattedHeaders(e),n=e.message,r=n.queryParameters&&Object.keys(n.queryParameters).length>0?T(n.queryParameters):void 0,i=`${n.origin}${n.path}${r?`?${r}`:""}`,a=t?void 0:this.formattedBody(e);let o="Sending";t&&(o=`${e.canceled?"Canceled":"Failed"}${e.details?` (${e.details})`:""}`);const c=((null==a?void 0:a.formData)?"FormData":"Method").length;return`${o} HTTP request:\n ${this.paddedString("Method",c)}: ${n.method}\n ${this.paddedString("URL",c)}: ${i}${s?`\n ${this.paddedString("Headers",c)}:\n${s}`:""}${(null==a?void 0:a.formData)?`\n ${this.paddedString("FormData",c)}:\n${a.formData}`:""}${(null==a?void 0:a.body)?`\n ${this.paddedString("Body",c)}:\n${a.body}`:""}`}if("network-response"===e.messageType){const t=e.minimumLevel===V.Trace?this.formattedHeaders(e):void 0,s=this.formattedBody(e),n=((null==s?void 0:s.formData)?"Headers":"Status").length,r=e.message;return`Received HTTP response:\n ${this.paddedString("URL",n)}: ${r.url}\n ${this.paddedString("Status",n)}: ${r.status}${e.details?`\n ${this.paddedString("Details",n)}: ${e.details}`:""}${t?`\n ${this.paddedString("Headers",n)}:\n${t}`:""}${(null==s?void 0:s.body)?`\n ${this.paddedString("Body",n)}:\n${s.body}`:""}`}if("error"===e.messageType){const t=this.formattedErrorStatus(e),s=e.message;return`${s.name}: ${s.message}${t?`\n${t}`:""}`}return""}formattedObject(e){const t=(s,n=1,r=!1)=>{const i=10===n,a=" ".repeat(2*n),o=[],c=(t,s)=>!!e.ignoredKeys&&("function"==typeof e.ignoredKeys?e.ignoredKeys(t,s):e.ignoredKeys.includes(t));if("string"==typeof s)o.push(`${a}- ${s}`);else if("number"==typeof s)o.push(`${a}- ${s}`);else if("boolean"==typeof s)o.push(`${a}- ${s}`);else if(null===s)o.push(`${a}- null`);else if(void 0===s)o.push(`${a}- undefined`);else if("function"==typeof s)o.push(`${a}- `);else if("object"==typeof s)if(Array.isArray(s)||"function"!=typeof s.toString||0===s.toString().indexOf("[object"))if(Array.isArray(s))for(const e of s){const s=r?"":a;if(null===e)o.push(`${s}- null`);else if(void 0===e)o.push(`${s}- undefined`);else if("function"==typeof e)o.push(`${s}- `);else if("object"==typeof e){const r=Array.isArray(e),a=i?"...":t(e,n+1,!r);o.push(`${s}-${r&&!i?"\n":" "}${a}`)}else o.push(`${s}- ${e}`);r=!1}else{const e=s,u=Object.keys(e),h=u.reduce(((t,s)=>Math.max(t,c(s,e)?t:s.length)),0);for(const s of u){if(c(s,e))continue;const u=r?"":a,l=e[s],d=s.padEnd(h," ");if(null===l)o.push(`${u}${d}: null`);else if(void 0===l)o.push(`${u}${d}: undefined`);else if("function"==typeof l)o.push(`${u}${d}: `);else if("object"==typeof l){const e=Array.isArray(l),s=e&&0===l.length,r=!(e||l instanceof String||0!==Object.keys(l).length),a=!e&&"function"==typeof l.toString&&0!==l.toString().indexOf("[object"),c=i?"...":s?"[]":r?"{}":t(l,n+1,a);o.push(`${u}${d}:${i||a||s||r?" ":"\n"}${c}`)}else o.push(`${u}${d}: ${l}`);r=!1}}else o.push(`${r?"":a}${s.toString()}`),r=!1;return o.join("\n")};return t(e.message)}formattedHeaders(e){if(!e.message.headers)return;const t=e.message.headers,s=Object.keys(t).reduce(((e,t)=>Math.max(e,t.length)),0);return Object.keys(t).map((e=>` - ${e.toLowerCase().padEnd(s," ")}: ${t[e]}`)).join("\n")}formattedBody(e){var t;if(!e.message.headers)return;let s,n;const r=e.message.headers,i=null!==(t=r["content-type"])&&void 0!==t?t:r["Content-Type"],a="formData"in e.message?e.message.formData:void 0,o=e.message.body;if(a){const e=a.reduce(((e,{key:t})=>Math.max(e,t.length)),0);s=a.map((({key:t,value:s})=>` - ${t.padEnd(e," ")}: ${s}`)).join("\n")}return o?(n="string"==typeof o?` ${o}`:o instanceof ArrayBuffer||"[object ArrayBuffer]"===Object.prototype.toString.call(o)?!i||-1===i.indexOf("javascript")&&-1===i.indexOf("json")?` ArrayBuffer { byteLength: ${o.byteLength} }`:` ${J.decoder.decode(o)}`:` File { name: ${o.name}${o.contentLength?`, contentLength: ${o.contentLength}`:""}${o.mimeType?`, mimeType: ${o.mimeType}`:""} }`,{body:n,formData:s}):{formData:s}}formattedErrorStatus(e){if(!e.message.status)return;const t=e.message.status,s=t.errorData;let n;if(J.isError(s))n=` ${s.name}: ${s.message}`,s.stack&&(n+=`\n${s.stack.split("\n").map((e=>` ${e}`)).join("\n")}`);else if(s)try{n=` ${JSON.stringify(s)}`}catch(e){n=` ${s}`}return` Category : ${t.category}\n Operation : ${t.operation}\n Status : ${t.statusCode}${n?`\n Error data:\n${n}`:""}`}paddedString(e,t){return e.padEnd(t-e.length," ")}static isError(e){return!!e&&(e instanceof Error||"[object Error]"===Object.prototype.toString.call(e))}}J.decoder=new TextDecoder,function(e){e.Unknown="UnknownEndpoint",e.MessageSend="MessageSendEndpoint",e.Subscribe="SubscribeEndpoint",e.Presence="PresenceEndpoint",e.Files="FilesEndpoint",e.MessageStorage="MessageStorageEndpoint",e.ChannelGroups="ChannelGroupsEndpoint",e.DevicePushNotifications="DevicePushNotificationsEndpoint",e.AppContext="AppContextEndpoint",e.MessageReactions="MessageReactionsEndpoint"}(z||(z={}));class X{static None(){return{shouldRetry:(e,t,s,n)=>!1,getDelay:(e,t)=>-1,validate:()=>!0}}static LinearRetryPolicy(e){var t;return{delay:e.delay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return Q(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=this.delay),1e3*(s+Math.random())},validate(){if(this.delay<2)throw new Error("Delay can not be set less than 2 seconds for retry")}}}static ExponentialRetryPolicy(e){var t;return{minimumDelay:e.minimumDelay,maximumDelay:e.maximumDelay,maximumRetry:e.maximumRetry,excluded:null!==(t=e.excluded)&&void 0!==t?t:[],shouldRetry(e,t,s,n){return Q(e,t,s,null!=n?n:0,this.maximumRetry,this.excluded)},getDelay(e,t){let s=-1;return t&&void 0!==t.headers["retry-after"]&&(s=parseInt(t.headers["retry-after"],10)),-1===s&&(s=Math.min(this.minimumDelay*Math.pow(2,e),this.maximumDelay)),1e3*(s+Math.random())},validate(){if(this.minimumDelay<2)throw new Error("Minimum delay can not be set less than 2 seconds for retry")}}}}const Q=(e,t,s,n,r,i)=>(!s||s!==l.PNCancelledCategory&&s!==l.PNBadRequestCategory&&s!==l.PNAccessDeniedCategory)&&(!Y(e,i)&&(!(n>r)&&(!t||(429===t.status||t.status>=500)))),Y=(e,t)=>!!(t&&t.length>0)&&t.includes(Z(e)),Z=e=>{let t=z.Unknown;return e.path.startsWith("/v2/subscribe")?t=z.Subscribe:e.path.startsWith("/publish/")||e.path.startsWith("/signal/")?t=z.MessageSend:e.path.startsWith("/v2/presence")?t=z.Presence:e.path.startsWith("/v2/history")||e.path.startsWith("/v3/history")?t=z.MessageStorage:e.path.startsWith("/v1/message-actions/")?t=z.MessageReactions:e.path.startsWith("/v1/channel-registration/")||e.path.startsWith("/v2/objects/")?t=z.ChannelGroups:e.path.startsWith("/v1/push/")||e.path.startsWith("/v2/push/")?t=z.DevicePushNotifications:e.path.startsWith("/v1/files/")&&(t=z.Files),t};class ee{constructor(e,t,s){this.previousEntryTimestamp=0,this.pubNubId=e,this.minLogLevel=t,this.loggers=s}get logLevel(){return this.minLogLevel}trace(e,t){this.log(V.Trace,e,t)}debug(e,t){this.log(V.Debug,e,t)}info(e,t){this.log(V.Info,e,t)}warn(e,t){this.log(V.Warn,e,t)}error(e,t){this.log(V.Error,e,t)}log(e,t,s){if(ee[r](i)))}}var te={exports:{}}; +/*! lil-uuid - v0.1 - MIT License - https://github.com/lil-js/uuid */!function(e,t){!function(e){var t="0.1.0",s={3:/^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i,4:/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,5:/^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i,all:/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i};function n(){var e,t,s="";for(e=0;e<32;e++)t=16*Math.random()|0,8!==e&&12!==e&&16!==e&&20!==e||(s+="-"),s+=(12===e?4:16===e?3&t|8:t).toString(16);return s}function r(e,t){var n=s[t||"all"];return n&&n.test(e)||!1}n.isUUID=r,n.VERSION=t,e.uuid=n,e.isUUID=r}(t),null!==e&&(e.exports=t.uuid)}(te,te.exports);var se=t(te.exports),ne={createUUID:()=>se.uuid?se.uuid():se()};const re=(e,t)=>{var s,n,r,i;!e.retryConfiguration&&e.enableEventEngine&&(e.retryConfiguration=X.ExponentialRetryPolicy({minimumDelay:2,maximumDelay:150,maximumRetry:6,excluded:[z.MessageSend,z.Presence,z.Files,z.MessageStorage,z.ChannelGroups,z.DevicePushNotifications,z.AppContext,z.MessageReactions]}));const a=`pn-${ne.createUUID()}`;e.logVerbosity?e.logLevel=V.Debug:void 0===e.logLevel&&(e.logLevel=V.None);const o=new ee(ae(a),e.logLevel,[...null!==(s=e.loggers)&&void 0!==s?s:[],new J]);void 0!==e.logVerbosity&&o.warn("Configuration","'logVerbosity' is deprecated. Use 'logLevel' instead."),null===(n=e.retryConfiguration)||void 0===n||n.validate();const c=e.useRandomIVs;null!==(r=e.useRandomIVs)&&void 0!==r||(e.useRandomIVs=true),void 0!==c&&(o.warn("Configuration","'useRandomIVs' is deprecated. Pass it to 'cryptoModule' instead."),!1===c&&o.warn("Configuration","Setting 'useRandomIVs' to false is insecure and should only be used to support legacy clients.\n Do not disable random IVs in new applications.")),e.origin=ie(null!==(i=e.ssl)&&void 0!==i&&i,e.origin);const u=e.cryptoModule;u&&delete e.cryptoModule;const h=Object.assign(Object.assign({},e),{_pnsdkSuffix:{},_loggerManager:o,_instanceId:a,_cryptoModule:void 0,_cipherKey:void 0,_setupCryptoModule:t,get instanceId(){if(e.useInstanceId)return this._instanceId},getInstanceId(){if(e.useInstanceId)return this._instanceId},getUserId(){return this.userId},setUserId(e){if(!e||"string"!=typeof e||0===e.trim().length)throw new Error("Missing or invalid userId parameter. Provide a valid string userId");this.userId=e},logger(){return this._loggerManager},getAuthKey(){return this.authKey},setAuthKey(e){this.authKey=e},getFilterExpression(){return this.filterExpression},setFilterExpression(e){this.filterExpression=e},getCipherKey(){return this._cipherKey},setCipherKey(t){this._cipherKey=t,t||!this._cryptoModule?t&&this._setupCryptoModule&&(this._cryptoModule=this._setupCryptoModule({cipherKey:t,useRandomIVs:e.useRandomIVs,customEncrypt:this.getCustomEncrypt(),customDecrypt:this.getCustomDecrypt(),logger:this.logger()})):this._cryptoModule=void 0},getCryptoModule(){return this._cryptoModule},getUseRandomIVs:()=>e.useRandomIVs,isSharedWorkerEnabled:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,getKeepPresenceChannelsInPresenceRequests:()=>"Web"===e.sdkFamily&&e.subscriptionWorkerUrl,setPresenceTimeout(e){this.heartbeatInterval=e/2-1,this.presenceTimeout=e},getPresenceTimeout(){return this.presenceTimeout},getHeartbeatInterval(){return this.heartbeatInterval},setHeartbeatInterval(e){this.heartbeatInterval=e},getTransactionTimeout(){return this.transactionalRequestTimeout},getSubscribeTimeout(){return this.subscribeRequestTimeout},getFileTimeout(){return this.fileRequestTimeout},get PubNubFile(){return e.PubNubFile},get version(){return"12.0.2"},getVersion(){return this.version},_addPnsdkSuffix(e,t){this._pnsdkSuffix[e]=`${t}`},_getPnsdkSuffix(e){const t=Object.values(this._pnsdkSuffix).join(e);return t.length>0?e+t:""},getUUID(){return this.getUserId()},setUUID(e){this.setUserId(e)},getCustomEncrypt:()=>e.customEncrypt,getCustomDecrypt:()=>e.customDecrypt});return e.cipherKey?(o.warn("Configuration","'cipherKey' is deprecated. Use 'cryptoModule' instead."),h.setCipherKey(e.cipherKey)):u&&(h._cryptoModule=u),h},ie=(e,t)=>{const s=e?"https://":"http://";return"string"==typeof t?`${s}${t}`:`${s}${t[Math.floor(Math.random()*t.length)]}`},ae=e=>{let t=2166136261;for(let s=0;s>>0;return t.toString(16).padStart(8,"0")};class oe{constructor(e){this.cbor=e}setToken(e){e&&e.length>0?this.token=e:this.token=void 0}getToken(){return this.token}parseToken(e){const t=this.cbor.decodeToken(e);if(void 0!==t){const e=t.res.uuid?Object.keys(t.res.uuid):[],s=Object.keys(t.res.chan),n=Object.keys(t.res.grp),r=t.pat.uuid?Object.keys(t.pat.uuid):[],i=Object.keys(t.pat.chan),a=Object.keys(t.pat.grp),o={version:t.v,timestamp:t.t,ttl:t.ttl,authorized_uuid:t.uuid,signature:t.sig},c=e.length>0,u=s.length>0,h=n.length>0;if(c||u||h){if(o.resources={},c){const s=o.resources.uuids={};e.forEach((e=>s[e]=this.extractPermissions(t.res.uuid[e])))}if(u){const e=o.resources.channels={};s.forEach((s=>e[s]=this.extractPermissions(t.res.chan[s])))}if(h){const e=o.resources.groups={};n.forEach((s=>e[s]=this.extractPermissions(t.res.grp[s])))}}const l=r.length>0,d=i.length>0,p=a.length>0;if(l||d||p){if(o.patterns={},l){const e=o.patterns.uuids={};r.forEach((s=>e[s]=this.extractPermissions(t.pat.uuid[s])))}if(d){const e=o.patterns.channels={};i.forEach((s=>e[s]=this.extractPermissions(t.pat.chan[s])))}if(p){const e=o.patterns.groups={};a.forEach((s=>e[s]=this.extractPermissions(t.pat.grp[s])))}}return t.meta&&Object.keys(t.meta).length>0&&(o.meta=t.meta),o}}extractPermissions(e){const t={read:!1,write:!1,manage:!1,delete:!1,get:!1,update:!1,join:!1};return 128&~e||(t.join=!0),64&~e||(t.update=!0),32&~e||(t.get=!0),8&~e||(t.delete=!0),4&~e||(t.manage=!0),2&~e||(t.write=!0),1&~e||(t.read=!0),t}}var ce;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.PUT="PUT",e.DELETE="DELETE",e.LOCAL="LOCAL"}(ce||(ce={}));class ue{constructor(e,t,s,n){this.publishKey=e,this.secretKey=t,this.hasher=s,this.logger=n}signature(e){const t=e.path.startsWith("/publish")?ce.GET:e.method;let s=`${t}\n${this.publishKey}\n${e.path}\n${this.queryParameters(e.queryParameters)}\n`;if(t===ce.POST||t===ce.PATCH||t===ce.PUT){const t=e.body;let n;t&&t instanceof ArrayBuffer?n=ue.textDecoder.decode(t):t&&"object"!=typeof t&&(n=t),n&&(s+=n)}return this.logger.trace("RequestSignature",(()=>({messageType:"text",message:`Request signature input:\n${s}`}))),`v2.${this.hasher(s,this.secretKey)}`.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}queryParameters(e){return Object.keys(e).sort().map((t=>{const s=e[t];return Array.isArray(s)?s.sort().map((e=>`${t}=${P(e)}`)).join("&"):`${t}=${P(s)}`})).join("&")}}ue.textDecoder=new TextDecoder("utf-8");class he{constructor(e){this.configuration=e;const{clientConfiguration:{keySet:t},shaHMAC:s}=e;t.secretKey&&s&&(this.signatureGenerator=new ue(t.publishKey,t.secretKey,s,this.logger))}get logger(){return this.configuration.clientConfiguration.logger()}makeSendable(e){const t=this.configuration.clientConfiguration.retryConfiguration,s=this.configuration.transport;if(void 0!==t){let n,r,i=!1,a=0;const o={abort:e=>{i=!0,n&&clearTimeout(n),r&&r.abort(e)}};return[new Promise(((o,c)=>{const u=()=>{if(i)return;const[h,d]=s.makeSendable(this.request(e));r=d;const p=(s,r)=>{const i=!r||r.category!==l.PNCancelledCategory,h=(!s||s.status>=400)&&404!==(null==r?void 0:r.statusCode);let d=-1;i&&h&&t.shouldRetry(e,s,null==r?void 0:r.category,a+1)&&(d=t.getDelay(a,s)),d>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${d}ms.`),n=setTimeout((()=>u()),d)):s?o(s):r&&c(r)};h.then((e=>p(e))).catch((e=>p(void 0,e)))};u()})),r?o:void 0]}return s.makeSendable(this.request(e))}request(e){var t;const{clientConfiguration:s}=this.configuration;return(e=this.configuration.transport.request(e)).queryParameters||(e.queryParameters={}),s.useInstanceId&&(e.queryParameters.instanceid=s.getInstanceId()),e.queryParameters.uuid||(e.queryParameters.uuid=s.userId),s.useRequestId&&(e.queryParameters.requestid=e.identifier),e.queryParameters.pnsdk=this.generatePNSDK(),null!==(t=e.origin)&&void 0!==t||(e.origin=s.origin),this.authenticateRequest(e),this.signRequest(e),e}authenticateRequest(e){var t;if(e.path.startsWith("/v2/auth/")||e.path.startsWith("/v3/pam/")||e.path.startsWith("/time"))return;const{clientConfiguration:s,tokenManager:n}=this.configuration,r=null!==(t=n&&n.getToken())&&void 0!==t?t:s.authKey;r&&(e.queryParameters.auth=r)}signRequest(e){this.signatureGenerator&&!e.path.startsWith("/time")&&(e.queryParameters.timestamp=String(Math.floor((new Date).getTime()/1e3)),e.queryParameters.signature=this.signatureGenerator.signature(e))}generatePNSDK(){const{clientConfiguration:e}=this.configuration;if(e.sdkName)return e.sdkName;let t=`PubNub-JS-${e.sdkFamily}`;e.partnerId&&(t+=`-${e.partnerId}`),t+=`/${e.getVersion()}`;const s=e._getPnsdkSuffix(" ");return s.length>0&&(t+=s),t}}class le{constructor(e,t="fetch"){this.logger=e,this.transport=t,e.debug("WebTransport",`Create with configuration:\n - transport: ${t}`),"fetch"===t&&"undefined"==typeof fetch&&(e.warn("WebTransport",`'${t}' not supported in this browser. Fallback to the 'xhr' transport.`),this.transport="xhr"),"fetch"===this.transport&&(le.originalFetch=le.getOriginalFetch(),this.isFetchMonkeyPatched()&&e.warn("WebTransport","Native Web Fetch API 'fetch' function monkey patched."))}makeSendable(e){const t=new AbortController,s={abortController:t,abort:e=>{t.signal.aborted||(this.logger.trace("WebTransport",`On-demand request aborting: ${e}`),t.abort(e))}};return[this.webTransportRequestFromTransportRequest(e).then((t=>(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e}))),this.sendRequest(t,s).then((e=>e.arrayBuffer().then((t=>[e,t])))).then((e=>{const s=e[1].byteLength>0?e[1]:void 0,{status:n,headers:r}=e[0],i={};r.forEach(((e,t)=>i[t]=e.toLowerCase()));const a={status:n,url:t.url,headers:i,body:s};if(this.logger.debug("WebTransport",(()=>({messageType:"network-response",message:a}))),n>=400)throw G.create(a);return a})).catch((t=>{const s=("string"==typeof t?t:t.message).toLowerCase();let n="string"==typeof t?new Error(t):t;throw s.includes("timeout")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Timeout",canceled:!0}))):s.includes("cancel")||s.includes("abort")?(this.logger.debug("WebTransport",(()=>({messageType:"network-request",message:e,details:"Aborted",canceled:!0}))),n=new Error("Aborted"),n.name="AbortError"):s.includes("network")?this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:"Network error",failed:!0}))):this.logger.warn("WebTransport",(()=>({messageType:"network-request",message:e,details:G.create(n).message,failed:!0}))),G.create(n)}))))),s]}request(e){return e}sendRequest(e,t){return i(this,void 0,void 0,(function*(){return"fetch"===this.transport?this.sendFetchRequest(e,t):this.sendXHRRequest(e,t)}))}sendFetchRequest(e,t){return i(this,void 0,void 0,(function*(){let s;const n=new Promise(((n,r)=>{s=setTimeout((()=>{clearTimeout(s),r(new Error("Request timeout")),t.abort("Cancel because of timeout")}),1e3*e.timeout)})),r=new Request(e.url,{method:e.method,headers:e.headers,redirect:"follow",body:e.body});return Promise.race([le.originalFetch(r,{signal:t.abortController.signal,credentials:"omit",cache:"no-cache"}).then((e=>(s&&clearTimeout(s),e))),n])}))}sendXHRRequest(e,t){return i(this,void 0,void 0,(function*(){return new Promise(((s,n)=>{var r;const i=new XMLHttpRequest;i.open(e.method,e.url,!0);let a=!1;i.responseType="arraybuffer",i.timeout=1e3*e.timeout,t.abortController.signal.onabort=()=>{i.readyState!=XMLHttpRequest.DONE&&i.readyState!=XMLHttpRequest.UNSENT&&(a=!0,i.abort())},Object.entries(null!==(r=e.headers)&&void 0!==r?r:{}).forEach((([e,t])=>i.setRequestHeader(e,t))),i.onabort=()=>{n(new Error("Aborted"))},i.ontimeout=()=>{n(new Error("Request timeout"))},i.onerror=()=>{if(!a){const t=this.transportResponseFromXHR(e.url,i);n(new Error(G.create(t).message))}},i.onload=()=>{const e=new Headers;i.getAllResponseHeaders().split("\r\n").forEach((t=>{const[s,n]=t.split(": ");s.length>1&&n.length>1&&e.append(s,n)})),s(new Response(i.response,{status:i.status,headers:e,statusText:i.statusText}))},i.send(e.body)}))}))}webTransportRequestFromTransportRequest(e){return i(this,void 0,void 0,(function*(){let t,s=e.path;if(e.formData&&e.formData.length>0){e.queryParameters={};const s=e.body,n=new FormData;for(const{key:t,value:s}of e.formData)n.append(t,s);try{const e=yield s.toArrayBuffer();n.append("file",new Blob([e],{type:"application/octet-stream"}),s.name)}catch(e){this.logger.warn("WebTransport",(()=>({messageType:"error",message:e})));try{const e=yield s.toFileUri();n.append("file",e,s.name)}catch(e){this.logger.error("WebTransport",(()=>({messageType:"error",message:e})))}}t=n}else if(e.body&&("string"==typeof e.body||e.body instanceof ArrayBuffer))if(e.compressible&&"undefined"!=typeof CompressionStream){const s="string"==typeof e.body?le.encoder.encode(e.body):e.body,n=s.byteLength,r=new ReadableStream({start(e){e.enqueue(s),e.close()}});t=yield new Response(r.pipeThrough(new CompressionStream("deflate"))).arrayBuffer(),this.logger.trace("WebTransport",(()=>{const e=t.byteLength,s=(e/n).toFixed(2);return{messageType:"text",message:`Body of ${n} bytes, compressed by ${s}x to ${e} bytes.`}}))}else t=e.body;return e.queryParameters&&0!==Object.keys(e.queryParameters).length&&(s=`${s}?${T(e.queryParameters)}`),{url:`${e.origin}${s}`,method:e.method,headers:e.headers,timeout:e.timeout,body:t}}))}isFetchMonkeyPatched(e){return!(null!=e?e:fetch).toString().includes("[native code]")&&"fetch"!==fetch.name}transportResponseFromXHR(e,t){const s=t.getAllResponseHeaders().split("\n"),n={};for(const e of s){const[t,s]=e.trim().split(":");t&&s&&(n[t.toLowerCase()]=s.trim())}return{status:t.status,url:e,headers:n,body:t.response}}static getOriginalFetch(){if("undefined"==typeof document||!document.body)return fetch;let e=document.querySelector('iframe[name="pubnub-context-unpatched-fetch"]');return e||(e=document.createElement("iframe"),e.style.display="none",e.name="pubnub-context-unpatched-fetch",e.src="about:blank",document.body.appendChild(e)),e.contentWindow?e.contentWindow.fetch.bind(e.contentWindow):fetch}}le.encoder=new TextEncoder,le.decoder=new TextDecoder;class de{constructor(e){this.params=e,this.requestIdentifier=ne.createUUID(),this._cancellationController=null}get cancellationController(){return this._cancellationController}set cancellationController(e){this._cancellationController=e}abort(e){this&&this.cancellationController&&this.cancellationController.abort(e)}operation(){throw Error("Should be implemented by subclass.")}validate(){}parse(e){return i(this,void 0,void 0,(function*(){return this.deserializeResponse(e)}))}request(){var e,t,s,n,r,i;const a={method:null!==(t=null===(e=this.params)||void 0===e?void 0:e.method)&&void 0!==t?t:ce.GET,path:this.path,queryParameters:this.queryParameters,cancellable:null!==(n=null===(s=this.params)||void 0===s?void 0:s.cancellable)&&void 0!==n&&n,compressible:null!==(i=null===(r=this.params)||void 0===r?void 0:r.compressible)&&void 0!==i&&i,timeout:10,identifier:this.requestIdentifier},o=this.headers;if(o&&(a.headers=o),a.method===ce.POST||a.method===ce.PATCH||a.method===ce.PUT){const[e,t]=[this.body,this.formData];t&&(a.formData=t),e&&(a.body=e)}return a}get headers(){var e,t;return Object.assign({"Accept-Encoding":"gzip, deflate"},null!==(t=null===(e=this.params)||void 0===e?void 0:e.compressible)&&void 0!==t&&t?{"Content-Encoding":"deflate"}:{})}get path(){throw Error("`path` getter should be implemented by subclass.")}get queryParameters(){return{}}get formData(){}get body(){}deserializeResponse(e){const t=de.decoder.decode(e.body),s=e.headers["content-type"];let n;if(!s||-1===s.indexOf("javascript")&&-1===s.indexOf("json"))throw new d("Service response error, check status for details",g(t,e.status));try{n=JSON.parse(t)}catch(s){throw console.error("Error parsing JSON response:",s),new d("Service response error, check status for details",g(t,e.status))}if("status"in n&&"number"==typeof n.status&&n.status>=400)throw G.create(e);return n}}de.decoder=new TextDecoder;var pe;!function(e){e[e.Presence=-2]="Presence",e[e.Message=-1]="Message",e[e.Signal=1]="Signal",e[e.AppContext=2]="AppContext",e[e.MessageAction=3]="MessageAction",e[e.Files=4]="Files",e[e.DataSync=5]="DataSync"}(pe||(pe={}));const ge={user:"user",channel:"channel",membership:"membership",pn_user:"user",pn_channel:"channel",pn_membership:"membership"};class be extends de{constructor(e){var t,s,n,r,i,a;super({cancellable:!0}),this.parameters=e,null!==(t=(r=this.parameters).withPresence)&&void 0!==t||(r.withPresence=false),null!==(s=(i=this.parameters).channelGroups)&&void 0!==s||(i.channelGroups=[]),null!==(n=(a=this.parameters).channels)&&void 0!==n||(a.channels=[])}operation(){return K.PNSubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;return e?t||s?void 0:"`channels` and `channelGroups` both should not be empty":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){let t,s;try{s=de.decoder.decode(e.body);t=JSON.parse(s)}catch(e){console.error("Error parsing JSON response:",e)}if(!t)throw new d("Service response error, check status for details",g(s,e.status));const n=t.m.filter((e=>{const t=void 0===e.b?e.c:e.b;return this.parameters.channels&&this.parameters.channels.includes(t)||this.parameters.channelGroups&&this.parameters.channelGroups.includes(t)})).map((e=>{let{e:t}=e;null!=t||(t=e.c.endsWith("-pnpres")?pe.Presence:pe.Message);const s=I(e.d);if(t!=pe.Signal&&"string"==typeof e.d)return t==pe.Message?{type:pe.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:{type:pe.Files,data:this.fileFromEnvelope(e),pn_mfp:s};if(t==pe.Message)return{type:pe.Message,data:this.messageFromEnvelope(e),pn_mfp:s};if(t===pe.Presence)return{type:pe.Presence,data:this.presenceEventFromEnvelope(e),pn_mfp:s};if(t==pe.Signal)return{type:pe.Signal,data:this.signalFromEnvelope(e),pn_mfp:s};if(t===pe.AppContext)return{type:pe.AppContext,data:this.appContextFromEnvelope(e),pn_mfp:s};if(t===pe.MessageAction)return{type:pe.MessageAction,data:this.messageActionFromEnvelope(e),pn_mfp:s};if(t===pe.DataSync){const t=this.dataSyncFromEnvelope(e);return t?{type:pe.DataSync,data:t,pn_mfp:s}:{type:pe.Message,data:this.messageFromEnvelope(e),pn_mfp:s}}return{type:pe.Files,data:this.fileFromEnvelope(e),pn_mfp:s}}));return{cursor:{timetoken:t.t.t,region:t.t.r},messages:n}}))}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{accept:"text/javascript"})}presenceEventFromEnvelope(e){var t;const{d:s}=e,[n,r]=this.subscriptionChannelFromEnvelope(e),i=n.replace("-pnpres",""),a=null!==r?i:null,o=null!==r?r:i;return"string"!=typeof s&&("data"in s?(s.state=s.data,delete s.data):"action"in s&&"interval"===s.action&&(s.hereNowRefresh=null!==(t=s.here_now_refresh)&&void 0!==t&&t,delete s.here_now_refresh)),Object.assign({channel:i,subscription:r,actualChannel:a,subscribedChannel:o,timetoken:e.p.t},s)}messageFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d),i={channel:t,subscription:s,actualChannel:null!==s?t:null,subscribedChannel:null!==s?s:t,timetoken:e.p.t,publisher:e.i,message:n};return e.u&&(i.userMetadata=e.u),e.cmt&&(i.customMessageType=e.cmt),r&&(i.error=r),i}signalFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,message:e.d};return e.u&&(n.userMetadata=e.u),e.cmt&&(n.customMessageType=e.cmt),n}messageActionFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,publisher:e.i,event:n.event,data:Object.assign(Object.assign({},n.data),{uuid:e.i})}}appContextFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),n=e.d;return{channel:t,subscription:s,timetoken:e.p.t,message:n}}dataSyncFromEnvelope(e){var t;const[s,n]=this.subscriptionChannelFromEnvelope(e),r=e.d,i=null==r?void 0:r.metadata;if(!i||"data-sync"!==i.source||!i.event||!i.type)return;const a=i.className?i.className.split(":"):[],o=a.length>0?a[0]:void 0,c=a.filter((e=>e.length>0)),u=c.length>0?c[c.length-1]:void 0,h=o&&ge[o.toLowerCase()]||i.type,l=void 0!==i.classVersion?Number.parseInt(`${i.classVersion}`,10):NaN,d=Number.isNaN(l)?void 0:l,p=null!==(t=r.data)&&void 0!==t?t:{};let g;return g="delete"===i.event?{id:p.id,deletedAt:p.deletedAt}:"relationship"===i.type?Object.assign(Object.assign({},p),{relationshipClass:u,relationshipClassVersion:d}):Object.assign(Object.assign({},p),{entityClass:u,entityClassVersion:d}),{channel:s,subscription:n,timetoken:e.p.t,message:{version:r.version,event:i.event,source:i.source,type:i.type,objectType:h,className:u,classVersion:d,data:g}}}fileFromEnvelope(e){const[t,s]=this.subscriptionChannelFromEnvelope(e),[n,r]=this.decryptedData(e.d);let i=r;const a={channel:t,subscription:s,timetoken:e.p.t,publisher:e.i};return e.u&&(a.userMetadata=e.u),n?"string"==typeof n?null!=i||(i="Unexpected file information payload data type."):(a.message=n.message,n.file&&(a.file={id:n.file.id,name:n.file.name,url:this.parameters.getFileUrl({id:n.file.id,name:n.file.name,channel:t})})):null!=i||(i="File information payload is missing."),e.cmt&&(a.customMessageType=e.cmt),i&&(a.error=i),a}subscriptionChannelFromEnvelope(e){return[e.c,void 0===e.b?e.c:e.b]}decryptedData(e){if(!this.parameters.crypto||"string"!=typeof e)return[e,void 0];let t,s;try{const s=this.parameters.crypto.decrypt(e);t=s instanceof ArrayBuffer?JSON.parse(me.decoder.decode(s)):s}catch(e){t=null,s=`Error while decrypting message content: ${e.message}`}return[null!=t?t:e,s]}}class me extends be{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${C(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,heartbeat:s,state:n,timetoken:r,region:i,onDemand:a}=this.parameters,o={};return a&&(o["on-demand"]=1),e&&e.length>0&&(o["channel-group"]=e.sort().join(",")),t&&t.length>0&&(o["filter-expr"]=t),s&&(o.heartbeat=s),n&&Object.keys(n).length>0&&(o.state=JSON.stringify(n)),void 0!==r&&"string"==typeof r?r.length>0&&"0"!==r&&(o.tt=r):void 0!==r&&r>0&&(o.tt=r),i&&(o.tr=i),o}}class ye{constructor(){this.hasListeners=!1,this.listeners=[{count:-1,listener:{}}]}set onStatus(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"status"})}set onMessage(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"message"})}set onPresence(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"presence"})}set onSignal(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"signal"})}set onObjects(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"objects"})}set onMessageAction(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"messageAction"})}set onFile(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"file"})}set onDataSync(e){this.updateTypeOrObjectListener({add:!!e,listener:e,type:"dataSync"})}handleEvent(e){if(this.hasListeners)if(e.type===pe.Message)this.announce("message",e.data);else if(e.type===pe.Signal)this.announce("signal",e.data);else if(e.type===pe.Presence)this.announce("presence",e.data);else if(e.type===pe.AppContext){const{data:t}=e,{message:s}=t;if(this.announce("objects",t),"uuid"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"user"})});this.announce("user",u)}else if("channel"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,type:o}=s,c=r(s,["event","type"]),u=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",type:"space"})});this.announce("space",u)}else if("membership"===s.type){const{message:e,channel:n}=t,i=r(t,["message","channel"]),{event:a,data:o}=s,c=r(s,["event","data"]),{uuid:u,channel:h}=o,l=r(o,["uuid","channel"]),d=Object.assign(Object.assign({},i),{spaceId:n,message:Object.assign(Object.assign({},c),{event:"set"===a?"updated":"removed",data:Object.assign(Object.assign({},l),{user:u,space:h})})});this.announce("membership",d)}}else e.type===pe.MessageAction?this.announce("messageAction",e.data):e.type===pe.Files?this.announce("file",e.data):e.type===pe.DataSync&&this.announce("dataSync",e.data)}handleStatus(e){this.hasListeners&&this.announce("status",e)}addListener(e){this.updateTypeOrObjectListener({add:!0,listener:e})}removeListener(e){this.updateTypeOrObjectListener({add:!1,listener:e})}removeAllListeners(){this.listeners=[{count:-1,listener:{}}],this.hasListeners=!1}updateTypeOrObjectListener(e){if(e.type)"function"==typeof e.listener?this.listeners[0].listener[e.type]=e.listener:delete this.listeners[0].listener[e.type];else if(e.listener&&"function"!=typeof e.listener){let t,s=!1;for(t of this.listeners)if(t.listener===e.listener){e.add?(t.count++,s=!0):(t.count--,0===t.count&&this.listeners.splice(this.listeners.indexOf(t),1));break}e.add&&!s&&this.listeners.push({count:1,listener:e.listener})}this.hasListeners=this.listeners.length>1||Object.keys(this.listeners[0]).length>0}announce(e,t){this.listeners.forEach((({listener:s})=>{const n=s[e];n&&n(t)}))}}class fe{constructor(e){this.time=e}onReconnect(e){this.callback=e}startPolling(){this.timeTimer=setInterval((()=>this.callTime()),3e3)}stopPolling(){this.timeTimer&&clearInterval(this.timeTimer),this.timeTimer=null}callTime(){this.time((e=>{e.error||(this.stopPolling(),this.callback&&this.callback())}))}}class ve{constructor(e){this.config=e,e.logger().debug("DedupingManager",(()=>({messageType:"object",message:{maximumCacheSize:e.maximumCacheSize},details:"Create with configuration:"}))),this.maximumCacheSize=e.maximumCacheSize,this.hashHistory=[]}getKey(e){var t;return`${e.timetoken}-${this.hashCode(JSON.stringify(null!==(t=e.message)&&void 0!==t?t:"")).toString()}`}isDuplicate(e){return this.hashHistory.includes(this.getKey(e))}addEntry(e){this.hashHistory.length>=this.maximumCacheSize&&this.hashHistory.shift(),this.hashHistory.push(this.getKey(e))}clearHistory(){this.hashHistory=[]}hashCode(e){let t=0;if(0===e.length)return t;for(let s=0;s{this.pendingChannelSubscriptions.add(e),this.channels[e]={},r&&(this.presenceChannels[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannels[e]={})})),null==s||s.forEach((e=>{this.pendingChannelGroupSubscriptions.add(e),this.channelGroups[e]={},r&&(this.presenceChannelGroups[e]={}),(i||this.configuration.getHeartbeatInterval())&&(this.heartbeatChannelGroups[e]={})})),this.subscriptionStatusAnnounced=!1,this.reconnect()}unsubscribe(e,t=!1){let{channels:s,channelGroups:n}=e;const i=new Set,a=new Set;if(null==s||s.forEach((e=>{e in this.channels&&(delete this.channels[e],a.add(e),e in this.heartbeatChannels&&delete this.heartbeatChannels[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannels&&(delete this.presenceChannels[e],a.add(e))})),null==n||n.forEach((e=>{e in this.channelGroups&&(delete this.channelGroups[e],i.add(e),e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]),e in this.presenceState&&delete this.presenceState[e],e in this.presenceChannelGroups&&(delete this.presenceChannelGroups[e],i.add(e))})),0===a.size&&0===i.size)return;const o=this.lastTimetoken,c=this.currentTimetoken;0===Object.keys(this.channels).length&&0===Object.keys(this.presenceChannels).length&&0===Object.keys(this.channelGroups).length&&0===Object.keys(this.presenceChannelGroups).length&&(this.lastTimetoken="0",this.currentTimetoken="0",this.referenceTimetoken=null,this.storedTimetoken=null,this.region=null,this.reconnectionManager.stopPolling()),this.reconnect(!0),!1!==this.configuration.suppressLeaveEvents||t||(n=Array.from(i),s=Array.from(a),this.leaveCall({channels:s,channelGroups:n},(e=>{const{error:t}=e,i=r(e,["error"]);let a;t&&(e.errorData&&"object"==typeof e.errorData&&"message"in e.errorData&&"string"==typeof e.errorData.message?a=e.errorData.message:"message"in e&&"string"==typeof e.message&&(a=e.message)),this.emitStatus(Object.assign(Object.assign({},i),{error:null!=a&&a,affectedChannels:s,affectedChannelGroups:n,currentTimetoken:c,lastTimetoken:o}))})))}unsubscribeAll(e=!1){this.disconnectedWhileHandledEvent=!0,this.unsubscribe({channels:this.subscribedChannels,channelGroups:this.subscribedChannelGroups},e)}startSubscribeLoop(e=!1){this.disconnectedWhileHandledEvent=!1,this.stopSubscribeLoop();const t=[...Object.keys(this.channelGroups)],s=[...Object.keys(this.channels)];Object.keys(this.presenceChannelGroups).forEach((e=>t.push(`${e}-pnpres`))),Object.keys(this.presenceChannels).forEach((e=>s.push(`${e}-pnpres`))),0===s.length&&0===t.length||(this.subscribeCall(Object.assign(Object.assign(Object.assign({channels:s,channelGroups:t,state:this.presenceState,heartbeat:this.configuration.getPresenceTimeout(),timetoken:this.currentTimetoken},null!==this.region?{region:this.region}:{}),this.configuration.filterExpression?{filterExpression:this.configuration.filterExpression}:{}),{onDemand:!this.subscriptionStatusAnnounced||e}),((e,t)=>{this.processSubscribeResponse(e,t)})),!e&&this.configuration.useSmartHeartbeat&&this.startHeartbeatTimer())}stopSubscribeLoop(){this._subscribeAbort&&(this._subscribeAbort(),this._subscribeAbort=null)}processSubscribeResponse(e,t){if(e.error){if("object"==typeof e.errorData&&"name"in e.errorData&&"AbortError"===e.errorData.name||e.category===l.PNCancelledCategory)return;return void(e.category===l.PNTimeoutCategory?this.startSubscribeLoop():e.category===l.PNNetworkIssuesCategory||e.category===l.PNMalformedResponseCategory?(this.disconnect(),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.emitStatus({category:l.PNNetworkDownCategory})),this.reconnectionManager.onReconnect((()=>{this.configuration.autoNetworkDetection&&!this.isOnline&&(this.isOnline=!0,this.emitStatus({category:l.PNNetworkUpCategory})),this.reconnect(),this.subscriptionStatusAnnounced=!0;const t={category:l.PNReconnectedCategory,operation:e.operation,lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.emitStatus(t)})),this.reconnectionManager.startPolling(),this.emitStatus(Object.assign(Object.assign({},e),{category:l.PNNetworkIssuesCategory}))):e.category===l.PNBadRequestCategory?(this.stopHeartbeatTimer(),this.emitStatus(e)):this.emitStatus(e))}if(this.referenceTimetoken=M(t.cursor.timetoken,this.storedTimetoken),this.storedTimetoken?(this.currentTimetoken=this.storedTimetoken,this.storedTimetoken=null):(this.lastTimetoken=this.currentTimetoken,this.currentTimetoken=t.cursor.timetoken),!this.subscriptionStatusAnnounced){const t={category:l.PNConnectedCategory,operation:e.operation,affectedChannels:Array.from(this.pendingChannelSubscriptions),subscribedChannels:this.subscribedChannels,affectedChannelGroups:Array.from(this.pendingChannelGroupSubscriptions),lastTimetoken:this.lastTimetoken,currentTimetoken:this.currentTimetoken};this.subscriptionStatusAnnounced=!0,this.emitStatus(t),this.pendingChannelGroupSubscriptions.clear(),this.pendingChannelSubscriptions.clear()}const{messages:s}=t,{requestMessageCountThreshold:n,dedupeOnSubscribe:r}=this.configuration;n&&s.length>=n&&this.emitStatus({category:l.PNRequestMessageCountExceededCategory,operation:e.operation});try{const e={timetoken:this.currentTimetoken,region:this.region?this.region:void 0};this.configuration.logger().debug("SubscriptionManager",(()=>({messageType:"object",message:s.map((e=>({type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:e.pn_mfp})}))),details:"Received events:"}))),s.forEach((t=>{if(r&&"message"in t.data&&"timetoken"in t.data){if(this.dedupingManager.isDuplicate(t.data))return void this.configuration.logger().warn("SubscriptionManager",(()=>({messageType:"object",message:t.data,details:"Duplicate message detected (skipped):"})));this.dedupingManager.addEntry(t.data)}this.emitEvent(e,t)}))}catch(e){const t={error:!0,category:l.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}this.region=t.cursor.region,this.disconnectedWhileHandledEvent?this.disconnectedWhileHandledEvent=!1:this.startSubscribeLoop()}setState(e){const{state:t,channels:s,channelGroups:n}=e;null==s||s.forEach((e=>e in this.channels&&(this.presenceState[e]=t))),null==n||n.forEach((e=>e in this.channelGroups&&(this.presenceState[e]=t)))}changePresence(e){const{connected:t,channels:s,channelGroups:n}=e;t?(null==s||s.forEach((e=>this.heartbeatChannels[e]={})),null==n||n.forEach((e=>this.heartbeatChannelGroups[e]={}))):(null==s||s.forEach((e=>{e in this.heartbeatChannels&&delete this.heartbeatChannels[e]})),null==n||n.forEach((e=>{e in this.heartbeatChannelGroups&&delete this.heartbeatChannelGroups[e]})),!1===this.configuration.suppressLeaveEvents&&this.leaveCall({channels:s,channelGroups:n},(e=>this.emitStatus(e)))),this.reconnect()}startHeartbeatTimer(){this.stopHeartbeatTimer();const e=this.configuration.getHeartbeatInterval();e&&0!==e&&(this.configuration.useSmartHeartbeat||this.sendHeartbeat(),this.heartbeatTimer=setInterval((()=>this.sendHeartbeat()),1e3*e))}stopHeartbeatTimer(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}sendHeartbeat(){const e=Object.keys(this.heartbeatChannelGroups),t=Object.keys(this.heartbeatChannels);0===t.length&&0===e.length||this.heartbeatCall({channels:t,channelGroups:e,heartbeat:this.configuration.getPresenceTimeout(),state:this.presenceState},(e=>{e.error&&this.configuration.announceFailedHeartbeats&&this.emitStatus(e),e.error&&this.configuration.autoNetworkDetection&&this.isOnline&&(this.isOnline=!1,this.disconnect(),this.emitStatus({category:l.PNNetworkDownCategory}),this.reconnect()),!e.error&&this.configuration.announceSuccessfulHeartbeats&&this.emitStatus(e)}))}}class Se{constructor(e,t,s){this._payload=e,this.setDefaultPayloadStructure(),this.title=t,this.body=s}get payload(){return this._payload}set title(e){this._title=e}set subtitle(e){this._subtitle=e}set body(e){this._body=e}set badge(e){this._badge=e}set sound(e){this._sound=e}setDefaultPayloadStructure(){}toObject(){return{}}}class je extends Se{constructor(){super(...arguments),this._apnsPushType="apns",this._isSilent=!1}get payload(){return this._payload}set configurations(e){e&&e.length&&(this._configurations=e)}get notification(){return this.payload.aps}get title(){return this._title}set title(e){e&&e.length&&(this.payload.aps.alert.title=e,this._title=e)}get subtitle(){return this._subtitle}set subtitle(e){e&&e.length&&(this.payload.aps.alert.subtitle=e,this._subtitle=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.aps.alert.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.payload.aps.badge=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.payload.aps.sound=e,this._sound=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.aps={alert:{}}}toObject(){const e=Object.assign({},this.payload),{aps:t}=e;let{alert:s}=t;if(this._isSilent&&(t["content-available"]=1),"apns2"===this._apnsPushType){if(!this._configurations||!this._configurations.length)throw new ReferenceError("APNS2 configuration is missing");const t=[];this._configurations.forEach((e=>{t.push(this.objectFromAPNS2Configuration(e))})),t.length&&(e.pn_push=t)}return s&&Object.keys(s).length||delete t.alert,this._isSilent&&(delete t.alert,delete t.badge,delete t.sound,s={}),this._isSilent||s&&Object.keys(s).length?e:null}objectFromAPNS2Configuration(e){if(!e.targets||!e.targets.length)throw new ReferenceError("At least one APNS2 target should be provided");const{collapseId:t,expirationDate:s}=e,n={auth_method:"token",targets:e.targets.map((e=>this.objectFromAPNSTarget(e))),version:"v2"};return t&&t.length&&(n.collapse_id=t),s&&(n.expiration=s.toISOString()),n}objectFromAPNSTarget(e){if(!e.topic||!e.topic.length)throw new TypeError("Target 'topic' undefined.");const{topic:t,environment:s="development",excludedDevices:n=[]}=e,r={topic:t,environment:s};return n.length&&(r.excluded_devices=n),r}}class ke extends Se{get payload(){return this._payload}get notification(){return this.payload.notification}get data(){return this.payload.data}get androidNotification(){var e;return null===(e=this.payload.android)||void 0===e?void 0:e.notification}get title(){return this._title}set title(e){e&&e.length&&(this.payload.notification.title=e,this.androidNotification.title=e,this._title=e)}get body(){return this._body}set body(e){e&&e.length&&(this.payload.notification.body=e,this.androidNotification.body=e,this._body=e)}get badge(){return this._badge}set badge(e){null!=e&&(this.androidNotification.notification_count=e,this._badge=e)}get sound(){return this._sound}set sound(e){e&&e.length&&(this.androidNotification.sound=e,this._sound=e)}get icon(){return this._icon}set icon(e){e&&e.length&&(this.androidNotification.icon=e,this._icon=e)}get tag(){return this._tag}set tag(e){e&&e.length&&(this.androidNotification.tag=e,this._tag=e)}set silent(e){this._isSilent=e}setDefaultPayloadStructure(){this.payload.notification={},this.payload.data={},this.payload.android={notification:{}}}toObject(){var e,t;const s={},n=Object.assign({},this.payload.notification),i=Object.assign({},this.payload.android),a=r(Object.assign({},null!==(e=i.notification)&&void 0!==e?e:{}),["title","body"]);if(this._isSilent){const e={};this._title&&(e.title=this._title),this._body&&(e.body=this._body);for(const[t,s]of Object.entries(a))null!=s&&(e[t]=String(s));this.payload.data&&Object.assign(e,this.payload.data),Object.keys(e).length&&(s.data=e),delete i.notification,Object.keys(i).length&&(s.android=i)}else if(Object.keys(n).length&&(s.notification=n),this.payload.data&&Object.keys(this.payload.data).length&&(s.data=Object.assign({},this.payload.data)),Object.keys(a).length){const e=r(i,["notification"]);s.android=Object.assign(Object.assign({},e),{notification:a})}else{const e=r(i,["notification"]);Object.keys(e).length&&(s.android=e)}const o=r(this.payload,["notification","android","data","pn_exceptions"]);return Object.assign(s,o),(null===(t=this.payload.pn_exceptions)||void 0===t?void 0:t.length)&&(s.pn_exceptions=this.payload.pn_exceptions),Object.keys(s).length?s:null}}class we{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new je(this._payload.apns,e,t),this.fcm=new ke(this._payload.fcm,e,t)}set debugging(e){this._debugging=e}get title(){return this._title}get subtitle(){return this._subtitle}set subtitle(e){this._subtitle=e,this.apns.subtitle=e,this.fcm.subtitle=e}get body(){return this._body}get badge(){return this._badge}set badge(e){this._badge=e,this.apns.badge=e,this.fcm.badge=e}get sound(){return this._sound}set sound(e){this._sound=e,this.apns.sound=e,this.fcm.sound=e}buildPayload(e){const t={};if(e.includes("apns")||e.includes("apns2")){this.apns._apnsPushType=e.includes("apns")?"apns":"apns2";const s=this.apns.toObject();s&&Object.keys(s).length&&(t.pn_apns=s)}if(e.includes("fcm")){const e=this.fcm.toObject();e&&Object.keys(e).length&&(t.pn_fcm=e)}return Object.keys(t).length&&this._debugging&&(t.pn_debug=!0),t}}class Pe{constructor(e=!1){this.sync=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}notify(e){const t=()=>{this.listeners.forEach((t=>{t(e)}))};this.sync?t():setTimeout(t,0)}}class Ce{transition(e,t){var s;if(this.transitionMap.has(t.type))return null===(s=this.transitionMap.get(t.type))||void 0===s?void 0:s(e,t)}constructor(e){this.label=e,this.transitionMap=new Map,this.enterEffects=[],this.exitEffects=[]}on(e,t){return this.transitionMap.set(e,t),this}with(e,t){return[this,e,null!=t?t:[]]}onEnter(e){return this.enterEffects.push(e),this}onExit(e){return this.exitEffects.push(e),this}}class Ne extends Pe{constructor(e){super(!0),this.logger=e,this._pendingEvents=[],this._inTransition=!1}get currentState(){return this._currentState}get currentContext(){return this._currentContext}describe(e){return new Ce(e)}start(e,t){this._currentState=e,this._currentContext=t,this.notify({type:"engineStarted",state:e,context:t})}transition(e){if(!this._currentState)throw this.logger.error("Engine","Finite state machine is not started"),new Error("Start the engine first");if(this._inTransition)return this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine in transition. Enqueue received event:"}))),void this._pendingEvents.push(e);this._inTransition=!0,this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"Event engine received event:"}))),this.notify({type:"eventReceived",event:e});const t=this._currentState.transition(this._currentContext,e);if(t){const[s,n,r]=t;this.logger.trace("Engine",`Exiting state: ${this._currentState.label}`);for(const e of this._currentState.exitEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)});this.logger.trace("Engine",(()=>({messageType:"object",details:`Entering '${s.label}' state with context:`,message:n})));const i=this._currentState;this._currentState=s;const a=this._currentContext;this._currentContext=n,this.notify({type:"transitionDone",fromState:i,fromContext:a,toState:s,toContext:n,event:e});for(const e of r)this.notify({type:"invocationDispatched",invocation:e});for(const e of this._currentState.enterEffects)this.notify({type:"invocationDispatched",invocation:e(this._currentContext)})}else this.logger.warn("Engine",`No transition from '${this._currentState.label}' found for event: ${e.type}`);if(this._inTransition=!1,this._pendingEvents.length>0){const e=this._pendingEvents.shift();e&&(this.logger.trace("Engine",(()=>({messageType:"object",message:e,details:"De-queueing pending event:"}))),this.transition(e))}}}class Ee{constructor(e,t){this.dependencies=e,this.logger=t,this.instances=new Map,this.handlers=new Map}on(e,t){this.handlers.set(e,t)}dispatch(e){if(this.logger.trace("Dispatcher",`Process invocation: ${e.type}`),"CANCEL"===e.type){if(this.instances.has(e.payload)){const t=this.instances.get(e.payload);null==t||t.cancel(),this.instances.delete(e.payload)}return}const t=this.handlers.get(e.type);if(!t)throw this.logger.error("Dispatcher",`Unhandled invocation '${e.type}'`),new Error(`Unhandled invocation '${e.type}'`);const s=t(e.payload,this.dependencies);this.logger.trace("Dispatcher",(()=>({messageType:"object",details:"Call invocation handler with parameters:",message:e.payload,ignoredKeys:["abortSignal"]}))),e.managed&&this.instances.set(e.type,s),s.start()}dispose(){for(const[e,t]of this.instances.entries())t.cancel(),this.instances.delete(e)}}function Te(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function _e(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!1});return s.type=e,s}function Me(e,t){const s=(...s)=>({type:e,payload:t(...s),managed:!0});return s.type=e,s.cancel={type:"CANCEL",payload:e,managed:!1},s}class Re extends Error{constructor(){super("The operation was aborted."),this.name="AbortError",Object.setPrototypeOf(this,new.target.prototype)}}class Ie extends Pe{constructor(){super(...arguments),this._aborted=!1}get aborted(){return this._aborted}throwIfAborted(){if(this._aborted)throw new Re}abort(){this._aborted=!0,this.notify(new Re)}}class Ue{constructor(e,t){this.payload=e,this.dependencies=t}}class Ae extends Ue{constructor(e,t,s){super(e,t),this.asyncFunction=s,this.abortSignal=new Ie}start(){this.asyncFunction(this.payload,this.abortSignal,this.dependencies).catch((e=>{}))}cancel(){this.abortSignal.abort()}}const $e=e=>(t,s)=>new Ae(t,s,e),De=Me("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),Fe=_e("LEAVE",((e,t)=>({channels:e,groups:t}))),xe=_e("EMIT_STATUS",(e=>e)),qe=Me("WAIT",(()=>({}))),Ge=Te("RECONNECT",(()=>({}))),Le=Te("DISCONNECT",((e=!1)=>({isOffline:e}))),Ke=Te("JOINED",((e,t)=>({channels:e,groups:t}))),He=Te("LEFT",((e,t)=>({channels:e,groups:t}))),Be=Te("LEFT_ALL",((e=!1)=>({isOffline:e}))),We=Te("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),Ve=Te("HEARTBEAT_FAILURE",(e=>e)),ze=Te("TIMES_UP",(()=>({})));class Je extends Ee{constructor(e,t){super(t,t.config.logger()),this.on(De.type,$e(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeat:n,presenceState:r,config:i}){s.throwIfAborted();try{yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups},i.maintainPresenceState&&{state:r}),{heartbeat:i.presenceTimeout}));e.transition(We(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==l.PNCancelledCategory)return;e.transition(Ve(t))}}}))))),this.on(Fe.type,$e(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{leave:s,config:n}){if(!n.suppressLeaveEvents)try{s({channels:e.channels,channelGroups:e.groups})}catch(e){}}))))),this.on(qe.type,$e(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(ze())}))))),this.on(xe.type,$e(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s,config:n}){n.announceFailedHeartbeats&&!0===(null==e?void 0:e.error)?s(Object.assign(Object.assign({},e),{operation:K.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:K.PNHeartbeatOperation,category:l.PNAcknowledgmentCategory}))})))))}}const Xe=new Ce("HEARTBEAT_STOPPED");Xe.on(Ke.type,((e,t)=>Xe.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Xe.on(He.type,((e,t)=>Xe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),Xe.on(Ge.type,((e,t)=>Ze.with({channels:e.channels,groups:e.groups}))),Xe.on(Be.type,((e,t)=>et.with(void 0)));const Qe=new Ce("HEARTBEAT_COOLDOWN");Qe.onEnter((()=>qe())),Qe.onExit((()=>qe.cancel)),Qe.on(ze.type,((e,t)=>Ze.with({channels:e.channels,groups:e.groups}))),Qe.on(Ke.type,((e,t)=>Ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Qe.on(He.type,((e,t)=>Ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Fe(t.payload.channels,t.payload.groups)]))),Qe.on(Le.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]]))),Qe.on(Be.type,((e,t)=>et.with(void 0,[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]])));const Ye=new Ce("HEARTBEAT_FAILED");Ye.on(Ke.type,((e,t)=>Ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ye.on(He.type,((e,t)=>Ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Fe(t.payload.channels,t.payload.groups)]))),Ye.on(Ge.type,((e,t)=>Ze.with({channels:e.channels,groups:e.groups}))),Ye.on(Le.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]]))),Ye.on(Be.type,((e,t)=>et.with(void 0,[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]])));const Ze=new Ce("HEARTBEATING");Ze.onEnter((e=>De(e.channels,e.groups))),Ze.onExit((()=>De.cancel)),Ze.on(We.type,((e,t)=>Qe.with({channels:e.channels,groups:e.groups},[xe(Object.assign({},t.payload))]))),Ze.on(Ke.type,((e,t)=>Ze.with({channels:[...e.channels,...t.payload.channels.filter((t=>!e.channels.includes(t)))],groups:[...e.groups,...t.payload.groups.filter((t=>!e.groups.includes(t)))]}))),Ze.on(He.type,((e,t)=>Ze.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[Fe(t.payload.channels,t.payload.groups)]))),Ze.on(Ve.type,((e,t)=>Ye.with(Object.assign({},e),[...t.payload.status?[xe(Object.assign({},t.payload.status))]:[]]))),Ze.on(Le.type,((e,t)=>Xe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]]))),Ze.on(Be.type,((e,t)=>et.with(void 0,[...t.payload.isOffline?[]:[Fe(e.channels,e.groups)]])));const et=new Ce("HEARTBEAT_INACTIVE");et.on(Ke.type,((e,t)=>Ze.with({channels:t.payload.channels,groups:t.payload.groups})));class tt{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ne(e.config.logger()),this.dispatcher=new Je(this.engine,e),e.config.logger().debug("PresenceEventEngine","Create presence event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(et,void 0)}join({channels:e,groups:t}){this.channels=[...this.channels,...(null!=e?e:[]).filter((e=>!this.channels.includes(e)))],this.groups=[...this.groups,...(null!=t?t:[]).filter((e=>!this.groups.includes(e)))],0===this.channels.length&&0===this.groups.length||this.engine.transition(Ke(this.channels.slice(0),this.groups.slice(0)))}leave({channels:e,groups:t}){e&&(this.channels=this.channels.filter((t=>!e.includes(t)))),t&&(this.groups=this.groups.filter((e=>!t.includes(e)))),this.dependencies.presenceState&&(null==e||e.forEach((e=>delete this.dependencies.presenceState[e])),null==t||t.forEach((e=>delete this.dependencies.presenceState[e]))),this.engine.transition(He(null!=e?e:[],null!=t?t:[]))}leaveAll(e=!1){this.dependencies.presenceState&&(this.channels.forEach((e=>delete this.dependencies.presenceState[e])),this.groups.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=[],this.groups=[],this.engine.transition(Be(e))}reconnect(){this.engine.transition(Ge())}disconnect(e=!1){this.engine.transition(Le(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const st=Me("HANDSHAKE",((e,t,s)=>({channels:e,groups:t,onDemand:s}))),nt=Me("RECEIVE_MESSAGES",((e,t,s,n)=>({channels:e,groups:t,cursor:s,onDemand:n}))),rt=_e("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),it=_e("EMIT_STATUS",(e=>e)),at=Te("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),ot=Te("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),ct=Te("HANDSHAKE_SUCCESS",(e=>e)),ut=Te("HANDSHAKE_FAILURE",(e=>e)),ht=Te("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),lt=Te("RECEIVE_FAILURE",(e=>e)),dt=Te("DISCONNECT",((e=!1)=>({isOffline:e}))),pt=Te("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),gt=Te("UNSUBSCRIBE_ALL",(()=>({}))),bt=new Ce("UNSUBSCRIBED");bt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,onDemand:!0}))),bt.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region},onDemand:!0})));const mt=new Ce("HANDSHAKE_STOPPED");mt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(pt.type,((e,{payload:t})=>ft.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),mt.on(ot.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?bt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=e.cursor)||void 0===s?void 0:s.region)||0}})})),mt.on(gt.type,(e=>bt.with()));const yt=new Ce("HANDSHAKE_FAILED");yt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),yt.on(pt.type,((e,{payload:t})=>ft.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),yt.on(ot.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region?t.cursor.region:null!==(n=null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)&&void 0!==n?n:0},onDemand:!0})})),yt.on(gt.type,(e=>bt.with()));const ft=new Ce("HANDSHAKING");ft.onEnter((e=>{var t;return st(e.channels,e.groups,null!==(t=e.onDemand)&&void 0!==t&&t)})),ft.onExit((()=>st.cancel)),ft.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),ft.on(ct.type,((e,{payload:t})=>{var s,n,r,i,a;return St.with({channels:e.channels,groups:e.groups,cursor:{timetoken:(null===(s=e.cursor)||void 0===s?void 0:s.timetoken)?null===(n=e.cursor)||void 0===n?void 0:n.timetoken:t.timetoken,region:t.region},referenceTimetoken:M(t.timetoken,null===(r=e.cursor)||void 0===r?void 0:r.timetoken)},[it({category:l.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),operation:K.PNSubscribeOperation,currentTimetoken:(null===(i=e.cursor)||void 0===i?void 0:i.timetoken)?null===(a=e.cursor)||void 0===a?void 0:a.timetoken:t.timetoken})])})),ft.on(ut.type,((e,t)=>{var s;return yt.with(Object.assign(Object.assign({},e),{reason:t.payload}),[it({category:l.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),ft.on(dt.type,((e,t)=>{var s;if(t.payload.isOffline){const t=G.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation);return yt.with(Object.assign(Object.assign({},e),{reason:t}),[it({category:l.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return mt.with(Object.assign({},e))})),ft.on(ot.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||(null===(s=null==e?void 0:e.cursor)||void 0===s?void 0:s.region)||0},onDemand:!0})})),ft.on(gt.type,(e=>bt.with()));const vt=new Ce("RECEIVE_STOPPED");vt.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),vt.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),vt.on(pt.type,((e,{payload:t})=>{var s;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),vt.on(gt.type,(()=>bt.with(void 0)));const Ot=new Ce("RECEIVE_FAILED");Ot.on(pt.type,((e,{payload:t})=>{var s;return ft.with({channels:e.channels,groups:e.groups,cursor:{timetoken:t.cursor.timetoken?null===(s=t.cursor)||void 0===s?void 0:s.timetoken:e.cursor.timetoken,region:t.cursor.region||e.cursor.region},onDemand:!0})})),Ot.on(at.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),Ot.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0):ft.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},onDemand:!0}))),Ot.on(gt.type,(e=>bt.with(void 0)));const St=new Ce("RECEIVING");St.onEnter((e=>{var t;return nt(e.channels,e.groups,e.cursor,null!==(t=e.onDemand)&&void 0!==t&&t)})),St.onExit((()=>nt.cancel)),St.on(ht.type,((e,{payload:t})=>St.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:M(t.cursor.timetoken)},[rt(e.cursor,t.events)]))),St.on(at.type,((e,{payload:t})=>{var s;if(0===t.channels.length&&0===t.groups.length){let e;return t.isOffline&&(e=null===(s=G.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation).status)||void 0===s?void 0:s.category),bt.with(void 0,[it(Object.assign({category:t.isOffline?l.PNDisconnectedUnexpectedlyCategory:l.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation},e?{error:e}:{}))])}return St.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken,onDemand:!0},[it({category:l.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),St.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?bt.with(void 0,[it({category:l.PNDisconnectedCategory})]):St.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},referenceTimetoken:M(e.cursor.timetoken,`${t.cursor.timetoken}`,e.referenceTimetoken),onDemand:!0},[it({category:l.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),St.on(lt.type,((e,{payload:t})=>{var s;return Ot.with(Object.assign(Object.assign({},e),{reason:t}),[it({category:l.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),St.on(dt.type,((e,t)=>{var s;if(t.payload.isOffline){const t=G.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation);return Ot.with(Object.assign(Object.assign({},e),{reason:t}),[it({category:l.PNDisconnectedUnexpectedlyCategory,operation:K.PNSubscribeOperation,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return vt.with(Object.assign({},e),[it({category:l.PNDisconnectedCategory,operation:K.PNSubscribeOperation})])})),St.on(gt.type,(e=>bt.with(void 0,[it({category:l.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation})])));class jt extends Ee{constructor(e,t){super(t,t.config.logger()),this.on(st.type,$e(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{handshake:n,presenceState:r,config:i}){s.throwIfAborted();try{const a=yield n(Object.assign(Object.assign({abortSignal:s,channels:t.channels,channelGroups:t.groups,filterExpression:i.filterExpression},i.maintainPresenceState&&{state:r}),{onDemand:t.onDemand}));return e.transition(ct(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==l.PNCancelledCategory)return;return e.transition(ut(t))}}}))))),this.on(nt.type,$e(((t,s,n)=>i(this,[t,s,n],void 0,(function*(t,s,{receiveMessages:n,config:r}){s.throwIfAborted();try{const i=yield n({abortSignal:s,channels:t.channels,channelGroups:t.groups,timetoken:t.cursor.timetoken,region:t.cursor.region,filterExpression:r.filterExpression,onDemand:t.onDemand});e.transition(ht(i.cursor,i.messages))}catch(t){if(t instanceof d){if(t.status&&t.status.category==l.PNCancelledCategory)return;if(!s.aborted)return e.transition(lt(t))}}}))))),this.on(rt.type,$e(((e,t,s)=>i(this,[e,t,s],void 0,(function*({cursor:e,events:t},s,{emitMessages:n}){t.length>0&&n(e,t)}))))),this.on(it.type,$e(((e,t,s)=>i(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class kt{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ne(e.config.logger()),this.dispatcher=new jt(this.engine,e),e.config.logger().debug("EventEngine","Create subscribe event engine."),this._unsubscribeEngine=this.engine.subscribe((e=>{"invocationDispatched"===e.type&&this.dispatcher.dispatch(e.invocation)})),this.engine.start(bt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===St.label){const e=this.engine.currentContext;s=e.cursor.timetoken,t=e.referenceTimetoken}return _(s,null!=t?t:"0")}subscribe({channels:e,channelGroups:t,timetoken:s,withPresence:n}){var r;const i=null==e?void 0:e.some((e=>!this.channels.includes(e))),a=null==t?void 0:t.some((e=>!this.groups.includes(e))),o=i||a;if(this.channels=[...this.channels,...null!=e?e:[]],this.groups=[...this.groups,...null!=t?t:[]],n&&(this.channels.map((e=>this.channels.push(`${e}-pnpres`))),this.groups.map((e=>this.groups.push(`${e}-pnpres`)))),s)this.engine.transition(ot(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]])),s));else if(o)this.engine.transition(at(Array.from(new Set([...this.channels,...null!=e?e:[]])),Array.from(new Set([...this.groups,...null!=t?t:[]]))));else{this.dependencies.config.logger().debug("EventEngine","Skipping state transition - all channels/groups already subscribed. Emitting SubscriptionChanged event.");const e=this.engine.currentState,t=this.engine.currentContext;let s="0";if((null==e?void 0:e.label)===St.label&&t){s=null===(r=t.cursor)||void 0===r?void 0:r.timetoken}this.dependencies.emitStatus({category:l.PNSubscriptionChangedCategory,affectedChannels:Array.from(new Set(this.channels)),affectedChannelGroups:Array.from(new Set(this.groups)),currentTimetoken:s})}this.dependencies.join&&this.dependencies.join({channels:Array.from(new Set(this.channels.filter((e=>!e.endsWith("-pnpres"))))),groups:Array.from(new Set(this.groups.filter((e=>!e.endsWith("-pnpres")))))})}unsubscribe({channels:e=[],channelGroups:t=[]}){const s=N(this.channels,[...e,...e.map((e=>`${e}-pnpres`))]),n=N(this.groups,[...t,...t.map((e=>`${e}-pnpres`))]);if(new Set(this.channels).size!==new Set(s).size||new Set(this.groups).size!==new Set(n).size){const r=E(this.channels,e),i=E(this.groups,t);this.dependencies.presenceState&&(null==r||r.forEach((e=>delete this.dependencies.presenceState[e])),null==i||i.forEach((e=>delete this.dependencies.presenceState[e]))),this.channels=s,this.groups=n,this.engine.transition(at(Array.from(new Set(this.channels.slice(0))),Array.from(new Set(this.groups.slice(0))))),this.dependencies.leave&&this.dependencies.leave({channels:r.slice(0),groups:i.slice(0)})}}unsubscribeAll(e=!1){const t=this.getSubscribedChannelGroups(),s=this.getSubscribedChannels();this.channels=[],this.groups=[],this.dependencies.presenceState&&Object.keys(this.dependencies.presenceState).forEach((e=>{delete this.dependencies.presenceState[e]})),this.engine.transition(at(this.channels.slice(0),this.groups.slice(0),e)),this.dependencies.leaveAll&&this.dependencies.leaveAll({channels:s,groups:t,isOffline:e})}reconnect({timetoken:e,region:t}){const s=this.getSubscribedChannels(),n=this.getSubscribedChannels();this.engine.transition(pt(e,t)),this.dependencies.presenceReconnect&&this.dependencies.presenceReconnect({channels:n,groups:s})}disconnect(e=!1){const t=this.getSubscribedChannels(),s=this.getSubscribedChannels();this.engine.transition(dt(e)),this.dependencies.presenceDisconnect&&this.dependencies.presenceDisconnect({channels:s,groups:t,isOffline:e})}getSubscribedChannels(){return Array.from(new Set(this.channels.slice(0)))}getSubscribedChannelGroups(){return Array.from(new Set(this.groups.slice(0)))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}class wt extends de{constructor(e){var t;const s=null!==(t=e.sendByPost)&&void 0!==t&&t;super({method:s?ce.POST:ce.GET,compressible:s}),this.parameters=e,this.parameters.sendByPost=s}operation(){return K.PNPublishOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:s}=this.parameters,n=this.prepareMessagePayload(e);return`/publish/${s.publishKey}/${s.subscribeKey}/0/${P(t)}/0${this.parameters.sendByPost?"":`/${P(n)}`}`}get queryParameters(){const{customMessageType:e,meta:t,replicate:s,storeInHistory:n,ttl:r}=this.parameters,i={};return e&&(i.custom_message_type=e),void 0!==n&&(i.store=n?"1":"0"),void 0!==r&&(i.ttl=r),void 0===s||s||(i.norep="true"),t&&"object"==typeof t&&(i.meta=JSON.stringify(t)),i}get headers(){var e;return this.parameters.sendByPost?Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"}):super.headers}get body(){return this.prepareMessagePayload(this.parameters.message)}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Pt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNSignalOperation}validate(){const{message:e,channel:t,keySet:{publishKey:s}}=this.parameters;return t?e?s?void 0:"Missing 'publishKey'":"Missing 'message'":"Missing 'channel'"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{keySet:{publishKey:e,subscribeKey:t},channel:s,message:n}=this.parameters,r=JSON.stringify(n);return`/signal/${e}/${t}/0/${P(s)}/0/${P(r)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class Ct extends be{operation(){return K.PNReceiveMessagesOperation}validate(){const e=super.validate();return e||(this.parameters.timetoken?this.parameters.region?void 0:"region can not be empty":"timetoken can not be empty")}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${C(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,timetoken:s,region:n,onDemand:r}=this.parameters,i={ee:""};return r&&(i["on-demand"]=1),e&&e.length>0&&(i["channel-group"]=e.sort().join(",")),t&&t.length>0&&(i["filter-expr"]=t),"string"==typeof s?s&&"0"!==s&&s.length>0&&(i.tt=s):s&&s>0&&(i.tt=s),n&&(i.tr=n),i}}class Nt extends be{operation(){return K.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${C(t.sort(),",")}/0`}get queryParameters(){const{channelGroups:e,filterExpression:t,state:s,onDemand:n}=this.parameters,r={ee:""};return n&&(r["on-demand"]=1),e&&e.length>0&&(r["channel-group"]=e.sort().join(",")),t&&t.length>0&&(r["filter-expr"]=t),s&&Object.keys(s).length>0&&(r.state=JSON.stringify(s)),r}}var Et;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Et||(Et={}));class Tt{constructor({channels:e,channelGroups:t}){this.isEmpty=!0,this._channelGroups=new Set((null!=t?t:[]).filter((e=>e.length>0))),this._channels=new Set((null!=e?e:[]).filter((e=>e.length>0))),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size}get length(){return this.isEmpty?0:this._channels.size+this._channelGroups.size}get channels(){return this.isEmpty?[]:Array.from(this._channels)}get channelGroups(){return this.isEmpty?[]:Array.from(this._channelGroups)}contains(e){return!this.isEmpty&&(this._channels.has(e)||this._channelGroups.has(e))}with(e){return new Tt({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new Tt({channels:[...this._channels].filter((t=>!e._channels.has(t))),channelGroups:[...this._channelGroups].filter((t=>!e._channelGroups.has(t)))})}add(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups,...e._channelGroups])),e._channels.size>0&&(this._channels=new Set([...this._channels,...e._channels])),this.isEmpty=0===this._channels.size&&0===this._channelGroups.size,this}remove(e){return e._channelGroups.size>0&&(this._channelGroups=new Set([...this._channelGroups].filter((t=>!e._channelGroups.has(t))))),e._channels.size>0&&(this._channels=new Set([...this._channels].filter((t=>!e._channels.has(t))))),this}removeAll(){return this._channels.clear(),this._channelGroups.clear(),this.isEmpty=!0,this}toString(){return`SubscriptionInput { channels: [${this.channels.join(", ")}], channelGroups: [${this.channelGroups.join(", ")}], is empty: ${this.isEmpty?"true":"false"}} }`}}class _t{constructor(e,t,s,n){this._isSubscribed=!1,this.clones={},this.parents=[],this._id=ne.createUUID(),this.referenceTimetoken=n,this.subscriptionInput=t,this.options=s,this.client=e}get id(){return this._id}get isLastClone(){return 1===Object.keys(this.clones).length}get isSubscribed(){return!!this._isSubscribed||this.parents.length>0&&this.parents.some((e=>e.isSubscribed))}set isSubscribed(e){this.isSubscribed!==e&&(this._isSubscribed=e)}addParentState(e){this.parents.includes(e)||this.parents.push(e)}removeParentState(e){const t=this.parents.indexOf(e);-1!==t&&this.parents.splice(t,1)}storeClone(e,t){this.clones[e]||(this.clones[e]=t)}}class Mt{constructor(e,t="Subscription"){this.subscriptionType=t,this.id=ne.createUUID(),this.eventDispatcher=new ye,this._state=e}get state(){return this._state}get channels(){return this.state.subscriptionInput.channels.slice(0)}get channelGroups(){return this.state.subscriptionInput.channelGroups.slice(0)}set onMessage(e){this.eventDispatcher.onMessage=e}set onPresence(e){this.eventDispatcher.onPresence=e}set onSignal(e){this.eventDispatcher.onSignal=e}set onObjects(e){this.eventDispatcher.onObjects=e}set onMessageAction(e){this.eventDispatcher.onMessageAction=e}set onFile(e){this.eventDispatcher.onFile=e}set onDataSync(e){this.eventDispatcher.onDataSync=e}addListener(e){this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher.removeAllListeners()}handleEvent(e,t){var s;if((!this.state.cursor||e>this.state.cursor)&&(this.state.cursor=e),this.state.referenceTimetoken&&t.data.timetoken({messageType:"text",message:`Event timetoken (${t.data.timetoken}) is older than reference timetoken (${this.state.referenceTimetoken}) for ${this.id} subscription object. Ignoring event.`})));if((null===(s=this.state.options)||void 0===s?void 0:s.filter)&&!this.state.options.filter(t))return void this.state.client.logger.trace(this.subscriptionType,`Event filtered out by filter function for ${this.id} subscription object. Ignoring event.`);const n=Object.values(this.state.clones);n.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription object clones (count: ${n.length}) about received event.`),n.forEach((e=>e.eventDispatcher.handleEvent(t)))}dispose(){const e=Object.keys(this.state.clones);e.length>1?(this.state.client.logger.debug(this.subscriptionType,`Remove subscription object clone on dispose: ${this.id}`),delete this.state.clones[this.id]):1===e.length&&this.state.clones[this.id]&&(this.state.client.logger.debug(this.subscriptionType,`Unsubscribe subscription object on dispose: ${this.id}`),this.unsubscribe())}invalidate(e=!1){this.state._isSubscribed=!1,e&&(delete this.state.clones[this.id],0===Object.keys(this.state.clones).length&&(this.state.client.logger.trace(this.subscriptionType,"Last clone removed. Reset shared subscription state."),this.state.subscriptionInput.removeAll(),this.state.parents=[]))}subscribe(e){this.state.isSubscribed?this.state.client.logger.trace(this.subscriptionType,"Already subscribed. Ignoring subscribe request."):(this.state.client.logger.debug(this.subscriptionType,(()=>e?{messageType:"object",message:e,details:"Subscribe with parameters:"}:{messageType:"text",message:"Subscribe"})),this.state.isSubscribed=!0,this.updateSubscription({subscribing:!0,timetoken:null==e?void 0:e.timetoken}))}unsubscribe(){if(!this.state._isSubscribed||this.state.isSubscribed){if(!this.state._isSubscribed&&this.state.parents.length>0&&this.state.isSubscribed)return void this.state.client.logger.warn(this.subscriptionType,(()=>({messageType:"object",details:"Subscription is subscribed as part of a subscription set. Remove from active sets to unsubscribe:",message:this.state.parents.filter((e=>e.isSubscribed))})));if(!this.state._isSubscribed)return void this.state.client.logger.trace(this.subscriptionType,"Not subscribed. Ignoring unsubscribe request.")}this.state.client.logger.debug(this.subscriptionType,"Unsubscribe"),this.state.isSubscribed=!1,delete this.state.cursor,this.updateSubscription({subscribing:!1})}updateSubscription(e){var t,s;(null==e?void 0:e.timetoken)&&((null===(t=this.state.cursor)||void 0===t?void 0:t.timetoken)&&"0"!==(null===(s=this.state.cursor)||void 0===s?void 0:s.timetoken)?"0"!==e.timetoken&&e.timetoken>this.state.cursor.timetoken&&(this.state.cursor.timetoken=e.timetoken):this.state.cursor={timetoken:e.timetoken});const n=e.subscriptions&&e.subscriptions.length>0?e.subscriptions:void 0;e.subscribing?this.register(Object.assign(Object.assign({},e.timetoken?{cursor:this.state.cursor}:{}),n?{subscriptions:n}:{})):this.unregister(n)}}class Rt extends _t{constructor(e){const t=new Tt({});e.subscriptions.forEach((e=>t.add(e.state.subscriptionInput))),super(e.client,t,e.options,e.client.subscriptionTimetoken),this.subscriptions=e.subscriptions}addSubscription(e){this.subscriptions.includes(e)||(e.state.addParentState(this),this.subscriptions.push(e),this.subscriptionInput.add(e.state.subscriptionInput))}removeSubscription(e,t){const s=this.subscriptions.indexOf(e);-1!==s&&(this.subscriptions.splice(s,1),t||e.state.removeParentState(this),this.subscriptionInput.remove(e.state.subscriptionInput))}removeAllSubscriptions(){this.subscriptions.forEach((e=>e.state.removeParentState(this))),this.subscriptions.splice(0,this.subscriptions.length),this.subscriptionInput.removeAll()}}class It extends Mt{constructor(e){let t;if("client"in e){let s=[];!e.subscriptions&&e.entities?e.entities.forEach((t=>s.push(t.subscription(e.options)))):e.subscriptions&&(s=e.subscriptions),t=new Rt({client:e.client,subscriptions:s,options:e.options}),s.forEach((e=>e.state.addParentState(t))),t.client.logger.debug("SubscriptionSet",(()=>({messageType:"object",details:"Create subscription set with parameters:",message:Object.assign({subscriptions:t.subscriptions},e.options?e.options:{})})))}else t=e.state,t.client.logger.debug("SubscriptionSet","Create subscription set clone");super(t,"SubscriptionSet"),this.state.storeClone(this.id,this),t.subscriptions.forEach((e=>e.addParentSet(this)))}get state(){return super.state}get subscriptions(){return this.state.subscriptions.slice(0)}handleEvent(e,t){var s;this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)&&(this.state._isSubscribed?(super.handleEvent(e,t),this.state.subscriptions.length>0&&this.state.client.logger.trace(this.subscriptionType,`Notify ${this.id} subscription set subscriptions (count: ${this.state.subscriptions.length}) about received event.`),this.state.subscriptions.forEach((s=>s.handleEvent(e,t)))):this.state.client.logger.trace(this.subscriptionType,`Subscription set ${this.id} is not subscribed. Ignoring event.`))}subscriptionInput(e=!1){let t=this.state.subscriptionInput;return this.state.subscriptions.forEach((s=>{e&&s.state.entity.subscriptionsCount>0&&(t=t.without(s.state.subscriptionInput))})),t}cloneEmpty(){return new It({state:this.state})}dispose(){const e=this.state.isLastClone;this.state.subscriptions.forEach((t=>{t.removeParentSet(this),e&&t.state.removeParentState(this.state)})),super.dispose()}invalidate(e=!1){(e?this.state.subscriptions.slice(0):this.state.subscriptions).forEach((t=>{e&&(t.state.entity.decreaseSubscriptionCount(this.state.id),t.removeParentSet(this)),t.invalidate(e)})),e&&this.state.removeAllSubscriptions(),super.invalidate()}addSubscription(e){this.addSubscriptions([e])}addSubscriptions(e){const t=[],s=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?t.push(e):s.push(e)})),{messageType:"object",details:`Add subscriptions to ${this.id} (subscriptions count: ${this.state.subscriptions.length+s.length}):`,message:{addedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>!this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed?s.push(e):t.push(e),e.addParentSet(this),this.state.addSubscription(e)})),0===s.length&&0===t.length||!this.state.isSubscribed||(s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),t.length>0&&this.updateSubscription({subscribing:!0,subscriptions:t}))}removeSubscription(e){this.removeSubscriptions([e])}removeSubscriptions(e){const t=[];this.state.client.logger.debug(this.subscriptionType,(()=>{const t=[],s=[];return e.forEach((e=>{this.state.subscriptions.includes(e)?s.push(e):t.push(e)})),{messageType:"object",details:`Remove subscriptions from ${this.id} (subscriptions count: ${this.state.subscriptions.length}):`,message:{removedSubscriptions:s,ignoredSubscriptions:t}}})),e.filter((e=>this.state.subscriptions.includes(e))).forEach((e=>{e.state.isSubscribed&&t.push(e),e.removeParentSet(this),this.state.removeSubscription(e,e.parentSetsCount>1)})),0!==t.length&&this.state.isSubscribed&&this.updateSubscription({subscribing:!1,subscriptions:t})}addSubscriptionSet(e){this.addSubscriptions(e.subscriptions)}removeSubscriptionSet(e){this.removeSubscriptions(e.subscriptions)}register(e){var t;const s=null!==(t=e.subscriptions)&&void 0!==t?t:this.state.subscriptions;s.forEach((({state:e})=>e.entity.increaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor,s)}unregister(e){const t=null!=e?e:this.state.subscriptions;t.forEach((({state:e})=>e.entity.decreaseSubscriptionCount(this.state.id))),this.state.client.logger.trace(this.subscriptionType,(()=>e?{messageType:"object",message:{subscription:this,subscriptions:e},details:"Unregister subscriptions of subscription set from real-time events:"}:{messageType:"text",message:`Unregister subscription from real-time events: ${this}`})),this.state.client.unregisterEventHandleCapable(this,t)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, clonesCount: ${Object.keys(this.state.clones).length}, isSubscribed: ${e.isSubscribed}, subscriptions: [${e.subscriptions.map((e=>e.toString())).join(", ")}] }`}}class Ut extends _t{constructor(e){var t,s;const n=e.entity.subscriptionNames(null!==(s=null===(t=e.options)||void 0===t?void 0:t.receivePresenceEvents)&&void 0!==s&&s),r=new Tt({[e.entity.subscriptionType==Et.Channel?"channels":"channelGroups"]:n});super(e.client,r,e.options,e.client.subscriptionTimetoken),this.entity=e.entity}}class At extends Mt{constructor(e){"client"in e?e.client.logger.debug("Subscription",(()=>({messageType:"object",details:"Create subscription with parameters:",message:Object.assign({entity:e.entity},e.options?e.options:{})}))):e.state.client.logger.debug("Subscription","Create subscription clone"),super("state"in e?e.state:new Ut(e)),this.parents=[],this.handledUpdates=[],this.state.storeClone(this.id,this)}get state(){return super.state}get parentSetsCount(){return this.parents.length}handleEvent(e,t){var s,n;if(this.state.isSubscribed&&this.state.subscriptionInput.contains(null!==(s=t.data.subscription)&&void 0!==s?s:t.data.channel)){if(this.parentSetsCount>0){const e=I(t.data);if(this.handledUpdates.includes(e))return void this.state.client.logger.trace(this.subscriptionType,`Event (${e}) already handled by ${this.id}. Ignoring.`);this.handledUpdates.push(e),this.handledUpdates.length>10&&this.handledUpdates.shift()}this.state.subscriptionInput.contains(null!==(n=t.data.subscription)&&void 0!==n?n:t.data.channel)&&super.handleEvent(e,t)}}subscriptionInput(e=!1){return e&&this.state.entity.subscriptionsCount>0?new Tt({}):this.state.subscriptionInput}cloneEmpty(){return new At({state:this.state})}dispose(){this.parentSetsCount>0?this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`'${this.state.entity.subscriptionNames()}' subscription still in use. Ignore dispose request.`}))):(this.handledUpdates.splice(0,this.handledUpdates.length),super.dispose())}invalidate(e=!1){e&&this.state.entity.decreaseSubscriptionCount(this.state.id),this.handledUpdates.splice(0,this.handledUpdates.length),super.invalidate(e)}addParentSet(e){this.parents.includes(e)||(this.parents.push(e),this.state.client.logger.trace(this.subscriptionType,`Add parent subscription set for ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`))}removeParentSet(e){const t=this.parents.indexOf(e);-1!==t&&(this.parents.splice(t,1),this.state.client.logger.trace(this.subscriptionType,`Remove parent subscription set from ${this.id}: ${e.id}. Parent subscription set count: ${this.parentSetsCount}`)),0===this.parentSetsCount&&this.handledUpdates.splice(0,this.handledUpdates.length)}addSubscription(e){this.state.client.logger.debug(this.subscriptionType,(()=>({messageType:"text",message:`Create set with subscription: ${e}`})));const t=new It({client:this.state.client,subscriptions:[this,e],options:this.state.options});return this.state.isSubscribed||e.state.isSubscribed?(this.state.client.logger.trace(this.subscriptionType,"Subscribe resulting set because the receiver is already subscribed."),t.subscribe(),t):t}register(e){this.state.entity.increaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Register subscription for real-time events: ${this}`}))),this.state.client.registerEventHandleCapable(this,e.cursor)}unregister(e){this.state.entity.decreaseSubscriptionCount(this.state.id),this.state.client.logger.trace(this.subscriptionType,(()=>({messageType:"text",message:`Unregister subscription from real-time events: ${this}`}))),this.handledUpdates.splice(0,this.handledUpdates.length),this.state.client.unregisterEventHandleCapable(this)}toString(){const e=this.state;return`${this.subscriptionType} { id: ${this.id}, stateId: ${e.id}, entity: ${e.entity.subscriptionNames(!1).pop()}, clonesCount: ${Object.keys(e.clones).length}, isSubscribed: ${e.isSubscribed}, parentSetsCount: ${this.parentSetsCount}, cursor: ${e.cursor?e.cursor.timetoken:"not set"}, referenceTimetoken: ${e.referenceTimetoken?e.referenceTimetoken:"not set"} }`}}class $t extends de{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=(n=this.parameters).channels)&&void 0!==t||(n.channels=[]),null!==(s=(r=this.parameters).channelGroups)&&void 0!==s||(r.channelGroups=[])}operation(){return K.PNGetStateOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;if(!e)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),{channels:s=[],channelGroups:n=[]}=this.parameters,r={channels:{}};return 1===s.length&&0===n.length?r.channels[s[0]]=t.payload:r.channels=t.payload,r}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${C(null!=s?s:[],",")}/uuid/${P(null!=t?t:"")}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Dt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNSetStateOperation}validate(){const{keySet:{subscribeKey:e},state:t,channels:s=[],channelGroups:n=[]}=this.parameters;return e?void 0===t?"Missing State":0===(null==s?void 0:s.length)&&0===(null==n?void 0:n.length)?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{state:this.deserializeResponse(e).payload}}))}get path(){const{keySet:{subscribeKey:e},uuid:t,channels:s}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${C(null!=s?s:[],",")}/uuid/${P(t)}/data`}get queryParameters(){const{channelGroups:e,state:t}=this.parameters,s={state:JSON.stringify(t)};return e&&0!==e.length&&(s["channel-group"]=e.join(",")),s}}class Ft extends de{constructor(e){super({cancellable:!0}),this.parameters=e}operation(){return K.PNHeartbeatOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"Please provide a list of channels and/or channel-groups":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channels:t}=this.parameters;return`/v2/presence/sub-key/${e}/channel/${C(null!=t?t:[],",")}/heartbeat`}get queryParameters(){const{channelGroups:e,state:t,heartbeat:s}=this.parameters,n={heartbeat:`${s}`};return e&&0!==e.length&&(n["channel-group"]=e.join(",")),void 0!==t&&(n.state=JSON.stringify(t)),n}}class xt extends de{constructor(e){super(),this.parameters=e,this.parameters.channelGroups&&(this.parameters.channelGroups=Array.from(new Set(this.parameters.channelGroups))),this.parameters.channels&&(this.parameters.channels=Array.from(new Set(this.parameters.channels)))}operation(){return K.PNUnsubscribeOperation}validate(){const{keySet:{subscribeKey:e},channels:t=[],channelGroups:s=[]}=this.parameters;return e?0===t.length&&0===s.length?"At least one `channel` or `channel group` should be provided.":void 0:"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/presence/sub-key/${t}/channel/${C(null!==(e=null==s?void 0:s.sort())&&void 0!==e?e:[],",")}/leave`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.sort().join(",")}:{}}}class qt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNWhereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return t.payload?{channels:t.payload.channels}:{channels:[]}}))}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/presence/sub-key/${e}/uuid/${P(t)}`}}class Gt extends de{constructor(e){var t,s,n,r,i,a,o,c;super(),this.parameters=e,null!==(t=(i=this.parameters).queryParameters)&&void 0!==t||(i.queryParameters={}),null!==(s=(a=this.parameters).includeUUIDs)&&void 0!==s||(a.includeUUIDs=true),null!==(n=(o=this.parameters).includeState)&&void 0!==n||(o.includeState=false),null!==(r=(c=this.parameters).limit)&&void 0!==r||(c.limit=1e3)}operation(){const{channels:e=[],channelGroups:t=[]}=this.parameters;return 0===e.length&&0===t.length?K.PNGlobalHereNowOperation:K.PNHereNowOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t,s;const n=this.deserializeResponse(e),r="occupancy"in n?1:n.payload.total_channels,i="occupancy"in n?n.occupancy:n.payload.total_occupancy,a={};let o={};const c=this.parameters.limit;let u=!1;if("occupancy"in n){const e=this.parameters.channels[0];o[e]={uuids:null!==(t=n.uuids)&&void 0!==t?t:[],occupancy:i}}else o=null!==(s=n.payload.channels)&&void 0!==s?s:{};return Object.keys(o).forEach((e=>{const t=o[e];a[e]={occupants:this.parameters.includeUUIDs?t.uuids.map((e=>"string"==typeof e?{uuid:e,state:null}:e)):[],name:e,occupancy:t.occupancy},u||t.occupancy!==c||(u=!0)})),{totalChannels:r,totalOccupancy:i,channels:a}}))}get path(){const{keySet:{subscribeKey:e},channels:t,channelGroups:s}=this.parameters;let n=`/v2/presence/sub-key/${e}`;return(t&&t.length>0||s&&s.length>0)&&(n+=`/channel/${C(null!=t?t:[],",")}`),n}get queryParameters(){const{channelGroups:e,includeUUIDs:t,includeState:s,limit:n,offset:r,queryParameters:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},this.operation()===K.PNHereNowOperation?{limit:n}:{}),this.operation()===K.PNHereNowOperation&&null!=r&&r?{offset:r}:{}),t?{}:{disable_uuids:"1"}),null!=s&&s?{state:"1"}:{}),e&&e.length>0?{"channel-group":e.join(",")}:{}),i)}}class Lt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNDeleteMessagesOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v3/history/sub-key/${e}/channel/${P(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Kt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNMessageCounts}validate(){const{keySet:{subscribeKey:e},channels:t,timetoken:s,channelTimetokens:n}=this.parameters;return e?t?s&&n?"`timetoken` and `channelTimetokens` are incompatible together":s||n?n&&n.length>1&&n.length!==t.length?"Length of `channelTimetokens` and `channels` do not match":void 0:"`timetoken` or `channelTimetokens` need to be set":"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).channels}}))}get path(){return`/v3/history/sub-key/${this.parameters.keySet.subscribeKey}/message-counts/${C(this.parameters.channels)}`}get queryParameters(){let{channelTimetokens:e}=this.parameters;return this.parameters.timetoken&&(e=[this.parameters.timetoken]),Object.assign(Object.assign({},1===e.length?{timetoken:e[0]}:{}),e.length>1?{channelsTimetoken:e.join(",")}:{})}}class Ht extends de{constructor(e){var t,s,n;super(),this.parameters=e,e.count?e.count=Math.min(e.count,100):e.count=100,null!==(t=e.stringifiedTimeToken)&&void 0!==t||(e.stringifiedTimeToken=false),null!==(s=e.includeMeta)&&void 0!==s||(e.includeMeta=false),null!==(n=e.logVerbosity)&&void 0!==n||(e.logVerbosity=false)}operation(){return K.PNHistoryOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e),s=t[0],n=t[1],r=t[2];return Array.isArray(s)?{messages:s.map((e=>{const t=this.processPayload(e.message),s={entry:t.payload,timetoken:e.timetoken};return t.error&&(s.error=t.error),e.meta&&(s.meta=e.meta),s})),startTimeToken:n,endTimeToken:r}:{messages:[],startTimeToken:n,endTimeToken:r}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/history/sub-key/${e}/channel/${P(t)}`}get queryParameters(){const{start:e,end:t,reverse:s,count:n,stringifiedTimeToken:r,includeMeta:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:n,include_token:"true"},e?{start:e}:{}),t?{end:t}:{}),r?{string_message_token:"true"}:{}),null!=s?{reverse:s.toString()}:{}),i?{include_meta:"true"}:{})}processPayload(e){const{crypto:t,logVerbosity:s}=this.parameters;if(!t||"string"!=typeof e)return{payload:e};let n,r;try{const s=t.decrypt(e);n=s instanceof ArrayBuffer?JSON.parse(Ht.decoder.decode(s)):s}catch(t){s&&console.log("decryption error",t.message),n=e,r=`Error while decrypting message content: ${t.message}`}return{payload:n,error:r}}}var Bt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Bt||(Bt={}));class Wt extends de{constructor(e){var t,s,n,r,i;super(),this.parameters=e;const a=null!==(t=e.includeMessageActions)&&void 0!==t&&t,o=e.channels.length>1||a?25:100;e.count?e.count=Math.min(e.count,o):e.count=o,e.includeUuid?e.includeUUID=e.includeUuid:null!==(s=e.includeUUID)&&void 0!==s||(e.includeUUID=true),null!==(n=e.stringifiedTimeToken)&&void 0!==n||(e.stringifiedTimeToken=false),null!==(r=e.includeMessageType)&&void 0!==r||(e.includeMessageType=true),null!==(i=e.logVerbosity)&&void 0!==i||(e.logVerbosity=false)}operation(){return K.PNFetchMessagesOperation}validate(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return e?t?void 0!==s&&s&&t.length>1?"History can return actions data for a single channel only. Either pass a single channel or disable the includeMessageActions flag.":void 0:"Missing channels":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){var t;const s=this.deserializeResponse(e),n=null!==(t=s.channels)&&void 0!==t?t:{},r={};return Object.keys(n).forEach((e=>{r[e]=n[e].map((t=>{null===t.message_type&&(t.message_type=Bt.Message);const s=this.processPayload(e,t),n=Object.assign(Object.assign({channel:e,timetoken:t.timetoken,message:s.payload,messageType:t.message_type},t.custom_message_type?{customMessageType:t.custom_message_type}:{}),{uuid:t.uuid});if(t.actions){const e=n;e.actions=t.actions,e.data=t.actions}return t.meta&&(n.meta=t.meta),s.error&&(n.error=s.error),n}))})),s.more?{channels:r,more:s.more}:{channels:r}}))}get path(){const{keySet:{subscribeKey:e},channels:t,includeMessageActions:s}=this.parameters;return`/v3/${s?"history-with-actions":"history"}/sub-key/${e}/channel/${C(t)}`}get queryParameters(){const{start:e,end:t,count:s,includeCustomMessageType:n,includeMessageType:r,includeMeta:i,includeUUID:a,stringifiedTimeToken:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({max:s},e?{start:e}:{}),t?{end:t}:{}),o?{string_message_token:"true"}:{}),void 0!==i&&i?{include_meta:"true"}:{}),a?{include_uuid:"true"}:{}),null!=n?{include_custom_message_type:n?"true":"false"}:{}),r?{include_message_type:"true"}:{})}processPayload(e,t){const{crypto:s,logVerbosity:n}=this.parameters;if(!s||"string"!=typeof t.message)return{payload:t.message};let r,i;try{const e=s.decrypt(t.message);r=e instanceof ArrayBuffer?JSON.parse(Wt.decoder.decode(e)):e}catch(e){n&&console.log("decryption error",e.message),r=t.message,i=`Error while decrypting message content: ${e.message}`}if(!i&&r&&t.message_type==Bt.Files&&"object"==typeof r&&this.isFileMessage(r)){const t=r;return{payload:{message:t.message,file:Object.assign(Object.assign({},t.file),{url:this.parameters.getFileUrl({channel:e,id:t.file.id,name:t.file.name})})},error:i}}return{payload:r,error:i}}isFileMessage(e){return void 0!==e.file}}class Vt extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetMessageActionsOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channel?void 0:"Missing message channel":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);let s=null,n=null;return t.data.length>0&&(s=t.data[0].actionTimetoken,n=t.data[t.data.length-1].actionTimetoken),{data:t.data,more:t.more,start:s,end:n}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}`}get queryParameters(){const{limit:e,start:t,end:s}=this.parameters;return Object.assign(Object.assign(Object.assign({},t?{start:t}:{}),s?{end:s}:{}),e?{limit:e}:{})}}class zt extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNAddMessageActionOperation}validate(){const{keySet:{subscribeKey:e},action:t,channel:s,messageTimetoken:n}=this.parameters;return e?s?n?t?t.value?t.type?t.type.length>15?"Action.type value exceed maximum length of 15":void 0:"Missing Action.type":"Missing Action.value":"Missing Action":"Missing message timetoken":"Missing message channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}/message/${s}`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify(this.parameters.action)}}class Jt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveMessageActionOperation}validate(){const{keySet:{subscribeKey:e},channel:t,messageTimetoken:s,actionTimetoken:n}=this.parameters;return e?t?s?n?void 0:"Missing action timetoken":"Missing message timetoken":"Missing message action channel":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((({data:e})=>({data:e})))}))}get path(){const{keySet:{subscribeKey:e},channel:t,actionTimetoken:s,messageTimetoken:n}=this.parameters;return`/v1/message-actions/${e}/channel/${P(t)}/message/${n}/action/${s}`}}class Xt extends de{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).storeInHistory)&&void 0!==t||(s.storeInHistory=true)}operation(){return K.PNPublishFileMessageOperation}validate(){const{channel:e,fileId:t,fileName:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[2]}}))}get path(){const{message:e,channel:t,keySet:{publishKey:s,subscribeKey:n},fileId:r,fileName:i}=this.parameters,a=Object.assign({file:{name:i,id:r}},e?{message:e}:{});return`/v1/files/publish-file/${s}/${n}/0/${P(t)}/0/${P(this.prepareMessagePayload(a))}`}get queryParameters(){const{customMessageType:e,storeInHistory:t,ttl:s,meta:n}=this.parameters;return Object.assign(Object.assign(Object.assign({store:t?"1":"0"},e?{custom_message_type:e}:{}),s?{ttl:s}:{}),n&&"object"==typeof n?{meta:JSON.stringify(n)}:{})}prepareMessagePayload(e){const{crypto:t}=this.parameters;if(!t)return JSON.stringify(e)||"";const s=t.encrypt(JSON.stringify(e));return JSON.stringify("string"==typeof s?s:u(s))}}class Qt extends de{constructor(e){super({method:ce.LOCAL}),this.parameters=e}operation(){return K.PNGetFileUrlOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return e.url}))}get path(){const{channel:e,id:t,name:s,keySet:{subscribeKey:n}}=this.parameters;return`/v1/files/${n}/channels/${P(e)}/files/${P(t)}/${P(s)}`}}class Yt extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNDeleteFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},id:t,channel:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${P(s)}/files/${P(t)}/${P(n)}`}}class Zt extends de{constructor(e){var t,s;super(),this.parameters=e,null!==(t=(s=this.parameters).limit)&&void 0!==t||(s.limit=100)}operation(){return K.PNListFilesOperation}validate(){if(!this.parameters.channel)return"channel can't be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class es extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNGenerateUploadUrlOperation}validate(){return this.parameters.channel?this.parameters.name?void 0:"'name' can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return{id:t.data.id,name:t.data.name,url:t.file_upload_request.url,formFields:t.file_upload_request.form_fields}}))}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/generate-upload-url`}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){return JSON.stringify({name:this.parameters.name})}}class ts extends de{constructor(e){super({method:ce.POST}),this.parameters=e;const t=e.file.mimeType;t&&(e.formFields=e.formFields.map((e=>"Content-Type"===e.name?{name:e.name,value:t}:e)))}operation(){return K.PNPublishFileOperation}validate(){const{fileId:e,fileName:t,file:s,uploadUrl:n}=this.parameters;return e?t?s?n?void 0:"Validation failed: file upload 'url' can't be empty":"Validation failed: 'file' can't be empty":"Validation failed: file 'name' can't be empty":"Validation failed: file 'id' can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?ts.decoder.decode(e.body):"OK"}}))}request(){return Object.assign(Object.assign({},super.request()),{origin:new URL(this.parameters.uploadUrl).origin,timeout:300})}get path(){const{pathname:e,search:t}=new URL(this.parameters.uploadUrl);return`${e}${t}`}get body(){return this.parameters.file}get formData(){return this.parameters.formFields}}class ss{constructor(e){var t;if(this.parameters=e,this.file=null===(t=this.parameters.PubNubFile)||void 0===t?void 0:t.create(e.file),!this.file)throw new Error("File upload error: unable to create File object.")}process(){return i(this,void 0,void 0,(function*(){let e,t;return this.generateFileUploadUrl().then((s=>(e=s.name,t=s.id,this.uploadFile(s)))).then((e=>{if(204!==e.status)throw new d("Upload to bucket was unsuccessful",{error:!0,statusCode:e.status,category:l.PNUnknownCategory,operation:K.PNPublishFileOperation,errorData:{message:e.message}})})).then((()=>this.publishFileMessage(t,e))).catch((e=>{if(e instanceof d)throw e;const t=e instanceof G?e:G.create(e);throw new d("File upload error.",t.toStatus(K.PNPublishFileOperation))}))}))}generateFileUploadUrl(){return i(this,void 0,void 0,(function*(){const e=new es(Object.assign(Object.assign({},this.parameters),{name:this.file.name,keySet:this.parameters.keySet}));return this.parameters.sendRequest(e)}))}uploadFile(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,PubNubFile:s,crypto:n,cryptography:r}=this.parameters,{id:i,name:a,url:o,formFields:c}=e;return this.parameters.PubNubFile.supportsEncryptFile&&(!t&&n?this.file=yield n.encryptFile(this.file,s):t&&r&&(this.file=yield r.encryptFile(t,this.file,s))),this.parameters.sendRequest(new ts({fileId:i,fileName:a,file:this.file,uploadUrl:o,formFields:c}))}))}publishFileMessage(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i;let a,o={timetoken:"0"},c=this.parameters.fileUploadPublishRetryLimit,u=!1;do{try{o=yield this.parameters.publishFile(Object.assign(Object.assign({},this.parameters),{fileId:e,fileName:t})),u=!0}catch(e){e instanceof d&&(a=e),c-=1}}while(!u&&c>0);if(u)return{status:200,timetoken:o.timetoken,id:e,name:t};throw new d("Publish failed. You may want to execute that operation manually using pubnub.publishFile",{error:!0,category:null!==(n=null===(s=a.status)||void 0===s?void 0:s.category)&&void 0!==n?n:l.PNUnknownCategory,statusCode:null!==(i=null===(r=a.status)||void 0===r?void 0:r.statusCode)&&void 0!==i?i:0,channel:this.parameters.channel,id:e,name:t})}))}}class ns{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return Et.Channel}subscriptionNames(e){return[this._nameOrId,...e&&!this._nameOrId.endsWith("-pnpres")?[`${this._nameOrId}-pnpres`]:[]]}subscription(e){return new At({client:this.client,entity:this,options:e})}get subscriptionsCount(){return this.subscriptionStateIds.length}increaseSubscriptionCount(e){this.subscriptionStateIds.includes(e)||this.subscriptionStateIds.push(e)}decreaseSubscriptionCount(e){{const t=this.subscriptionStateIds.indexOf(e);t>=0&&this.subscriptionStateIds.splice(t,1)}}toString(){return`${this.entityType} { nameOrId: ${this._nameOrId}, subscriptionsCount: ${this.subscriptionsCount} }`}}class rs extends ns{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class is extends ns{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return Et.ChannelGroup}}class as extends ns{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class os extends ns{get entityType(){return"Channel"}get name(){return this._nameOrId}}class cs extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNRemoveChannelsFromGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class us extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNAddChannelsToGroupOperation}validate(){const{keySet:{subscribeKey:e},channels:t,channelGroup:s}=this.parameters;return e?s?t?void 0:"Missing channels":"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class hs extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNChannelsForGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e).payload.channels}}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}`}}class ls extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNRemoveGroupOperation}validate(){return this.parameters.keySet.subscribeKey?this.parameters.channelGroup?void 0:"Missing Channel Group":"Missing Subscribe Key"}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}get path(){const{keySet:{subscribeKey:e},channelGroup:t}=this.parameters;return`/v1/channel-registration/sub-key/${e}/channel-group/${P(t)}/remove`}}class ds extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNChannelGroupsOperation}validate(){if(!this.parameters.keySet.subscribeKey)return"Missing Subscribe Key"}parse(e){return i(this,void 0,void 0,(function*(){return{groups:this.deserializeResponse(e).payload.groups}}))}get path(){return`/v1/channel-registration/sub-key/${this.parameters.keySet.subscribeKey}/channel-group`}}class ps{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List channel group channels with parameters:"})));const s=new hs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List channel group channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}listGroups(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new ds({keySet:this.keySet}),s=e=>{e&&this.logger.debug("PubNub",`List all channel groups success. Received ${e.groups.length} groups.`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add channels to the channel group with parameters:"})));const s=new us(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add channels to the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channels from the channel group with parameters:"})));const s=new cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove channels from the channel group success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteGroup(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove a channel group with parameters:"})));const s=new ls(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub",`Remove a channel group success. Removed '${e.channelGroup}' channel group.'`)};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class gs extends de{constructor(e){var t,s;super(),this.parameters=e,"apns2"===this.parameters.pushGateway&&(null!==(t=(s=this.parameters).environment)&&void 0!==t||(s.environment="development")),this.parameters.count&&this.parameters.count>1e3&&(this.parameters.count=1e3)}operation(){throw Error("Should be implemented in subclass.")}validate(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;return e?s?"add"!==t&&"remove"!==t||"channels"in this.parameters&&0!==this.parameters.channels.length?n?"apns2"!==this.parameters.pushGateway||this.parameters.topic?void 0:"Missing APNS2 topic":"Missing GW Type (pushGateway: fcm or apns2)":"Missing Channels":"Missing Device ID (device)":"Missing Subscribe Key"}get path(){const{keySet:{subscribeKey:e},action:t,device:s,pushGateway:n}=this.parameters;let r="apns2"===n?`/v2/push/sub-key/${e}/devices-apns2/${s}`:`/v1/push/sub-key/${e}/devices/${s}`;return"remove-device"===t&&(r=`${r}/remove`),r}get queryParameters(){const{start:e,count:t}=this.parameters;let s=Object.assign(Object.assign({type:this.parameters.pushGateway},e?{start:e}:{}),t&&t>0?{count:t}:{});if("channels"in this.parameters&&(s[this.parameters.action]=this.parameters.channels.join(",")),"apns2"===this.parameters.pushGateway){const{environment:e,topic:t}=this.parameters;s=Object.assign(Object.assign({},s),{environment:e,topic:t})}return s}}class bs extends gs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove"}))}operation(){return K.PNRemovePushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ms extends gs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return K.PNPushNotificationEnabledChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class ys extends gs{constructor(e){super(Object.assign(Object.assign({},e),{action:"add"}))}operation(){return K.PNAddPushNotificationEnabledChannelsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class fs extends gs{constructor(e){super(Object.assign(Object.assign({},e),{action:"remove-device"}))}operation(){return K.PNRemoveAllPushNotificationsOperation}parse(e){const t=Object.create(null,{parse:{get:()=>super.parse}});return i(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class vs{constructor(e,t,s){this.sendRequest=s,this.logger=e,this.keySet=t}listChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List push-enabled channels with parameters:"})));const s=new ms(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List push-enabled channels success. Received ${e.channels.length} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}addChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add push-enabled channels with parameters:"})));const s=new ys(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Add push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}removeChannels(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push-enabled channels with parameters:"})));const s=new bs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push-enabled channels success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}deleteDevice(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove push notifications for device with parameters:"})));const s=new fs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=()=>{this.logger.debug("PubNub","Remove push notifications for device success.")};return t?this.sendRequest(s,(e=>{e.error||n(),t(e)})):this.sendRequest(s).then((e=>(n(),e)))}))}}class Os extends de{constructor(e){var t,s,n,r,i,a;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(i=e.include).customFields)&&void 0!==s||(i.customFields=false),null!==(n=(a=e.include).totalCount)&&void 0!==n||(a.totalCount=false),null!==(r=e.limit)&&void 0!==r||(e.limit=100)}operation(){return K.PNGetAllChannelMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(","),count:`${e.totalCount}`},s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ss extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}}class js extends de{constructor(e){var t,s,n,r,i,a,o,c,u,h,l,d,p,g,b,m,y,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(l=e.include).customFields)&&void 0!==s||(l.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(m=e.include).customChannelFields)&&void 0!==o||(m.customChannelFields=false),null!==(c=(y=e.include).channelStatusField)&&void 0!==c||(y.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(h=e.limit)&&void 0!==h||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNGetMembershipsOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class ks extends de{constructor(e){var t,s,n,r,i,a,o,c,u,h,l,d,p,g,b,m,y,f;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(l=e.include).customFields)&&void 0!==s||(l.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).channelFields)&&void 0!==a||(b.channelFields=false),null!==(o=(m=e.include).customChannelFields)&&void 0!==o||(m.customChannelFields=false),null!==(c=(y=e.include).channelStatusField)&&void 0!==c||(y.channelStatusField=false),null!==(u=(f=e.include).channelTypeField)&&void 0!==u||(f.channelTypeField=false),null!==(h=e.limit)&&void 0!==h||(e.limit=100),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNSetMembershipsOperation}validate(){const{uuid:e,channels:t}=this.parameters;return e?t&&0!==t.length?void 0:"Channels cannot be empty":"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}/channels`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["channel.status","channel.type","status"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.channelFields&&a.push("channel"),e.channelStatusField&&a.push("channel.status"),e.channelTypeField&&a.push("channel.type"),e.customChannelFields&&a.push("channel.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{channels:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{channel:{id:e}}:{channel:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class ws extends de{constructor(e){var t,s,n,r;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(r=e.include).customFields)&&void 0!==s||(r.customFields=false),null!==(n=e.limit)&&void 0!==n||(e.limit=100)}operation(){return K.PNGetAllUUIDMetadataOperation}get path(){return`/v2/objects/${this.parameters.keySet.subscribeKey}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";return i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e)),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({include:["status","type",...e.customFields?["custom"]:[]].join(",")},void 0!==e.totalCount?{count:`${e.totalCount}`}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ps extends de{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return K.PNGetChannelMetadataOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class Cs extends de{constructor(e){var t,s,n;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true)}operation(){return K.PNSetChannelMetadataOperation}validate(){return this.parameters.channel?this.parameters.data?void 0:"Data cannot be empty":"Channel cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Ns extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e,this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNRemoveUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}}class Es extends de{constructor(e){var t,s,n,r,i,a,o,c,u,h,l,d,p,g,b,m,y,f;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(l=e.include).customFields)&&void 0!==s||(l.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(m=e.include).customUUIDFields)&&void 0!==o||(m.customUUIDFields=false),null!==(c=(y=e.include).UUIDStatusField)&&void 0!==c||(y.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(h=e.limit)&&void 0!==h||(e.limit=100)}operation(){return K.PNSetMembersOperation}validate(){if(!this.parameters.channel)return"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=[];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}}class Ts extends de{constructor(e){var t,s,n,r,i,a,o,c,u,h,l,d,p,g,b,m,y,f;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(l=e.include).customFields)&&void 0!==s||(l.customFields=false),null!==(n=(d=e.include).totalCount)&&void 0!==n||(d.totalCount=false),null!==(r=(p=e.include).statusField)&&void 0!==r||(p.statusField=false),null!==(i=(g=e.include).typeField)&&void 0!==i||(g.typeField=false),null!==(a=(b=e.include).UUIDFields)&&void 0!==a||(b.UUIDFields=false),null!==(o=(m=e.include).customUUIDFields)&&void 0!==o||(m.customUUIDFields=false),null!==(c=(y=e.include).UUIDStatusField)&&void 0!==c||(y.UUIDStatusField=false),null!==(u=(f=e.include).UUIDTypeField)&&void 0!==u||(f.UUIDTypeField=false),null!==(h=e.limit)&&void 0!==h||(e.limit=100)}operation(){return K.PNSetMembersOperation}validate(){const{channel:e,uuids:t}=this.parameters;return e?t&&0!==t.length?void 0:"UUIDs cannot be empty":"Channel cannot be empty"}get path(){const{keySet:{subscribeKey:e},channel:t}=this.parameters;return`/v2/objects/${e}/channels/${P(t)}/uuids`}get queryParameters(){const{include:e,page:t,filter:s,sort:n,limit:r}=this.parameters;let i="";i="string"==typeof n?n:Object.entries(null!=n?n:{}).map((([e,t])=>null!==t?`${e}:${t}`:e));const a=["uuid.status","uuid.type","type"];return e.statusField&&a.push("status"),e.typeField&&a.push("type"),e.customFields&&a.push("custom"),e.UUIDFields&&a.push("uuid"),e.UUIDStatusField&&a.push("uuid.status"),e.UUIDTypeField&&a.push("uuid.type"),e.customUUIDFields&&a.push("uuid.custom"),Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({count:`${e.totalCount}`},a.length>0?{include:a.join(",")}:{}),s?{filter:s}:{}),(null==t?void 0:t.next)?{start:t.next}:{}),(null==t?void 0:t.prev)?{end:t.prev}:{}),r?{limit:r}:{}),i.length?{sort:i}:{})}get headers(){var e;return Object.assign(Object.assign({},null!==(e=super.headers)&&void 0!==e?e:{}),{"Content-Type":"application/json"})}get body(){const{uuids:e,type:t}=this.parameters;return JSON.stringify({[`${t}`]:e.map((e=>"string"==typeof e?{uuid:{id:e}}:{uuid:{id:e.id},status:e.status,type:e.type,custom:e.custom}))})}}class _s extends de{constructor(e){var t,s,n;super(),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNGetUUIDMetadataOperation}validate(){if(!this.parameters.uuid)return"'uuid' cannot be empty"}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ms extends de{constructor(e){var t,s,n;super({method:ce.PATCH}),this.parameters=e,null!==(t=e.include)&&void 0!==t||(e.include={}),null!==(s=(n=e.include).customFields)&&void 0!==s||(n.customFields=true),this.parameters.userId&&(this.parameters.uuid=this.parameters.userId)}operation(){return K.PNSetUUIDMetadataOperation}validate(){return this.parameters.uuid?this.parameters.data?void 0:"Data cannot be empty":"'uuid' cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json"})}get path(){const{keySet:{subscribeKey:e},uuid:t}=this.parameters;return`/v2/objects/${e}/uuids/${P(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Rs{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all UUID metadata objects with parameters:"}))),this._getAllUUIDMetadata(e,t)}))}_getAllUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new ws(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all UUID metadata success. Received ${e.totalCount} UUID metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Get ${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._getUUIDMetadata(e,t)}))}_getUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new _s(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get UUID metadata object success. Received '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set UUID metadata object with parameters:"}))),this._setUUIDMetadata(e,t)}))}_setUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId);const n=new Ms(Object.assign(Object.assign({},e),{keySet:this.keySet})),r=t=>{t&&this.logger.debug("PubNub",`Set UUID metadata object success. Updated '${e.uuid}' UUID metadata object.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.configuration.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} UUID metadata object with parameters:`}))),this._removeUUIDMetadata(e,t)}))}_removeUUIDMetadata(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId);const r=new Ns(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Remove UUID metadata object success. Removed '${n.uuid}' UUID metadata object.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Get all Channel metadata objects with parameters:"}))),this._getAllChannelMetadata(e,t)}))}_getAllChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0);const n=new Os(Object.assign(Object.assign({},s),{keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get all Channel metadata objects success. Received ${e.totalCount} Channel metadata objects.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel metadata object with parameters:"}))),this._getChannelMetadata(e,t)}))}_getChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Ps(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Get Channel metadata object success. Received '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel metadata object with parameters:"}))),this._setChannelMetadata(e,t)}))}_setChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Cs(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Set Channel metadata object success. Updated '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel metadata object with parameters:"}))),this._removeChannelMetadata(e,t)}))}_removeChannelMetadata(e,t){return i(this,void 0,void 0,(function*(){const s=new Ss(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Remove Channel metadata object success. Removed '${e.channel}' Channel metadata object.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get channel members with parameters:"})));const s=new Es(Object.assign(Object.assign({},e),{keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get channel members success. Received ${e.totalCount} channel members.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}setChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set channel members with parameters:"})));const s=new Ts(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Set channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}removeChannelMembers(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove channel members with parameters:"})));const s=new Ts(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Remove channel members success. There are ${e.totalCount} channel members now.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}))}getMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;const n=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),n.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),n.uuid=n.userId),null!==(s=n.uuid)&&void 0!==s||(n.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},n),details:"Get memberships with parameters:"})));const r=new js(Object.assign(Object.assign({},n),{keySet:this.keySet})),i=e=>{e&&this.logger.debug("PubNub",`Get memberships success. Received ${e.totalCount} memberships.`)};return t?this.sendRequest(r,((e,s)=>{i(s),t(e,s)})):this.sendRequest(r).then((e=>(i(e),e)))}))}setMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set memberships with parameters:"})));const n=new ks(Object.assign(Object.assign({},e),{type:"set",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Set memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s;e.userId&&(this.logger.warn("PubNub","'userId' parameter is deprecated. Use 'uuid' instead."),e.uuid=e.userId),null!==(s=e.uuid)&&void 0!==s||(e.uuid=this.configuration.userId),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"})));const n=new ks(Object.assign(Object.assign({},e),{type:"delete",keySet:this.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Remove memberships success. There are ${e.totalCount} memberships now.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n;if(this.logger.warn("PubNub","'fetchMemberships' is deprecated. Use 'pubnub.objects.getChannelMembers' or 'pubnub.objects.getMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch memberships with parameters:"}))),"spaceId"in e){const n=e,r={channel:null!==(s=n.spaceId)&&void 0!==s?s:n.channel,filter:n.filter,limit:n.limit,page:n.page,include:Object.assign({},n.include),sort:n.sort?Object.fromEntries(Object.entries(n.sort).map((([e,t])=>[e.replace("user","uuid"),t]))):void 0},i=e=>({status:e.status,data:e.data.map((e=>({user:e.uuid,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getChannelMembers(r,((e,s)=>{t(e,s?i(s):s)})):this.getChannelMembers(r).then(i)}const r=e,i={uuid:null!==(n=r.userId)&&void 0!==n?n:r.uuid,filter:r.filter,limit:r.limit,page:r.page,include:Object.assign({},r.include),sort:r.sort?Object.fromEntries(Object.entries(r.sort).map((([e,t])=>[e.replace("space","channel"),t]))):void 0},a=e=>({status:e.status,data:e.data.map((e=>({space:e.channel,custom:e.custom,updated:e.updated,eTag:e.eTag}))),totalCount:e.totalCount,next:e.next,prev:e.prev});return t?this.getMemberships(i,((e,s)=>{t(e,s?a(s):s)})):this.getMemberships(i).then(a)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r,i,a,o;if(this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add memberships with parameters:"}))),"spaceId"in e){const i=e,a={channel:null!==(s=i.spaceId)&&void 0!==s?s:i.channel,uuids:null!==(r=null===(n=i.users)||void 0===n?void 0:n.map((e=>"string"==typeof e?e:{id:e.userId,custom:e.custom})))&&void 0!==r?r:i.uuids,limit:0};return t?this.setChannelMembers(a,t):this.setChannelMembers(a)}const c=e,u={uuid:null!==(i=c.userId)&&void 0!==i?i:c.uuid,channels:null!==(o=null===(a=c.spaces)||void 0===a?void 0:a.map((e=>"string"==typeof e?e:{id:e.spaceId,custom:e.custom})))&&void 0!==o?o:c.channels,limit:0};return t?this.setMemberships(u,t):this.setMemberships(u)}))}}class Is extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateUserOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.user?void 0===this.parameters.user.entityClassVersion||null===this.parameters.user.entityClassVersion?"Entity class version cannot be empty":void 0:"User cannot be empty"}get headers(){var e;const t=null!==(e=super.headers)&&void 0!==e?e:{};return Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.user+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/v1/datasync/subkeys/${e}/users`}get body(){return JSON.stringify({data:this.parameters.user})}}class Us extends de{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetAllUsersOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}get path(){return`/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`}get queryParameters(){const{entityClassVersion:e,cursor:t,limit:s,filter:n,sort:r,filterAdvanced:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{entity_class_version:`${e}`}:{}),t?{cursor:t}:{}),s?{limit:`${s}`}:{}),n?{filter:n}:{}),r?{sort:r}:{}),i?{filter_advanced:i}:{})}}class As extends de{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNUpdateUserOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.id?this.parameters.user?void 0===this.parameters.user.entityClassVersion||null===this.parameters.user.entityClassVersion?"Entity class version cannot be empty":void 0:"User cannot be empty":"User id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.user+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/users/${P(t)}`}get body(){return JSON.stringify({data:this.parameters.user})}}class $s extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveUserOperation}validate(){if(!this.parameters.id)return"User id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/users/${P(t)}`}}function Ds(e){return"/"+e.split(".").join("/")}function Fs(e,t,s){const n=[];if(e)for(const[t,s]of Object.entries(e))n.push({op:"add",path:Ds(t),value:s});if(t)for(const[e,s]of Object.entries(t))n.push({op:"replace",path:Ds(e),value:s});if(s)for(const e of s)n.push({op:"remove",path:Ds(e)});return n}class xs extends de{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNPatchUserOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"User id cannot be empty";const e=this.parameters.add&&Object.keys(this.parameters.add).length>0,t=this.parameters.replace&&Object.keys(this.parameters.replace).length>0,s=this.parameters.remove&&this.parameters.remove.length>0;return e||t||s?void 0:"At least one of add, replace, or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/users/${P(t)}`}get body(){const e=e=>Object.fromEntries(Object.entries(e).map((([e,t])=>[`payload.${e}`,t]))),t=Fs(this.parameters.add?e(this.parameters.add):void 0,this.parameters.replace?e(this.parameters.replace):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(t)}}class qs extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetUserOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"User id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/users/${P(t)}`}}class Gs extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateChannelOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.channel?void 0===this.parameters.channel.entityClassVersion||null===this.parameters.channel.entityClassVersion?"Entity class version cannot be empty":void 0:"Channel cannot be empty"}get headers(){var e;const t=null!==(e=super.headers)&&void 0!==e?e:{};return Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.channel+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/v1/datasync/subkeys/${e}/channels`}get body(){return JSON.stringify({data:this.parameters.channel})}}class Ls extends de{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetAllChannelsOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}get path(){return`/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`}get queryParameters(){const{entityClassVersion:e,cursor:t,limit:s,filter:n,sort:r,filterAdvanced:i}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{entity_class_version:`${e}`}:{}),t?{cursor:t}:{}),s?{limit:`${s}`}:{}),n?{filter:n}:{}),r?{sort:r}:{}),i?{filter_advanced:i}:{})}}class Ks extends de{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNUpdateChannelOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.id?this.parameters.channel?void 0===this.parameters.channel.entityClassVersion||null===this.parameters.channel.entityClassVersion?"Entity class version cannot be empty":void 0:"Channel cannot be empty":"Channel id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.channel+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/channels/${P(t)}`}get body(){return JSON.stringify({data:this.parameters.channel})}}class Hs extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveChannelOperation}validate(){if(!this.parameters.id)return"Channel id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/channels/${P(t)}`}}class Bs extends de{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNPatchChannelOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Channel id cannot be empty";const e=this.parameters.add&&Object.keys(this.parameters.add).length>0,t=this.parameters.replace&&Object.keys(this.parameters.replace).length>0,s=this.parameters.remove&&this.parameters.remove.length>0;return e||t||s?void 0:"At least one of add, replace, or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/channels/${P(t)}`}get body(){const e=e=>Object.fromEntries(Object.entries(e).map((([e,t])=>[`payload.${e}`,t]))),t=Fs(this.parameters.add?e(this.parameters.add):void 0,this.parameters.replace?e(this.parameters.replace):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(t)}}class Ws extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetChannelOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Channel id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/channels/${P(t)}`}}class Vs extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateMembershipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.membership?this.parameters.membership.userId?this.parameters.membership.channelId?this.parameters.membership.relationshipClassVersion?void 0:"Relationship class version cannot be empty":"Channel id cannot be empty":"User id cannot be empty":"Membership cannot be empty"}get headers(){var e;const t=null!==(e=super.headers)&&void 0!==e?e:{};return Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.membership+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/v1/datasync/subkeys/${e}/memberships`}get body(){return JSON.stringify({data:this.parameters.membership})}}class zs extends de{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetAllMembershipsOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}get path(){return`/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`}get queryParameters(){const{userId:e,channelId:t,relationshipClassVersion:s,cursor:n,limit:r,filter:i,sort:a,filterAdvanced:o}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},e?{user_id:e}:{}),t?{channel_id:t}:{}),void 0!==s?{relationship_class_version:`${s}`}:{}),n?{cursor:n}:{}),r?{limit:`${r}`}:{}),i?{filter:i}:{}),a?{sort:a}:{}),o?{filter_advanced:o}:{})}}class Js extends de{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNUpdateMembershipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.id?this.parameters.membership?this.parameters.membership.userId?this.parameters.membership.channelId?this.parameters.membership.relationshipClassVersion?void 0:"Relationship class version cannot be empty":"Channel id cannot be empty":"User id cannot be empty":"Membership cannot be empty":"Membership id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.membership+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/memberships/${P(t)}`}get body(){return JSON.stringify({data:this.parameters.membership})}}class Xs extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveMembershipOperation}validate(){if(!this.parameters.id)return"Membership id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/memberships/${P(t)}`}}class Qs extends de{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNPatchMembershipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Membership id cannot be empty";const e=this.parameters.add&&Object.keys(this.parameters.add).length>0,t=this.parameters.replace&&Object.keys(this.parameters.replace).length>0,s=this.parameters.remove&&this.parameters.remove.length>0;return e||t||s?void 0:"At least one of add, replace, or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/memberships/${P(t)}`}get body(){const e=e=>Object.fromEntries(Object.entries(e).map((([e,t])=>[`payload.${e}`,t]))),t=Fs(this.parameters.add?e(this.parameters.add):void 0,this.parameters.replace?e(this.parameters.replace):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(t)}}class Ys extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetMembershipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Membership id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/memberships/${P(t)}`}}class Zs extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateRelationshipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.relationship?this.parameters.relationship.entityAId?this.parameters.relationship.entityBId?this.parameters.relationship.relationshipClass?this.parameters.relationship.relationshipClassVersion?void 0:"Relationship class version cannot be empty":"Relationship class cannot be empty":"Entity B id cannot be empty":"Entity A id cannot be empty":"Relationship cannot be empty"}get headers(){var e;const t=null!==(e=super.headers)&&void 0!==e?e:{};return Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.relationship+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/v1/datasync/subkeys/${e}/relationships`}get body(){return JSON.stringify({data:this.parameters.relationship})}}class en extends de{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetAllRelationshipsOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.relationshipClass)return"Relationship class cannot be empty"}get path(){return`/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/relationships`}get queryParameters(){const{relationshipClass:e,relationshipClassVersion:t,entityAId:s,entityBId:n,cursor:r,limit:i,filter:a,sort:o,filterAdvanced:c}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({relationship_class:e},void 0!==t?{relationship_class_version:`${t}`}:{}),s?{entity_a_id:s}:{}),n?{entity_b_id:n}:{}),r?{cursor:r}:{}),i?{limit:`${i}`}:{}),a?{filter:a}:{}),o?{sort:o}:{}),c?{filter_advanced:c}:{})}}class tn extends de{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNUpdateRelationshipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.id?this.parameters.relationship?this.parameters.relationship.entityAId?this.parameters.relationship.entityBId?this.parameters.relationship.relationshipClassVersion?void 0:"Relationship class version cannot be empty":"Entity B id cannot be empty":"Entity A id cannot be empty":"Relationship cannot be empty":"Relationship id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.relationship+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/relationships/${P(t)}`}get body(){return JSON.stringify({data:this.parameters.relationship})}}class sn extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveRelationshipOperation}validate(){if(!this.parameters.id)return"Relationship id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/relationships/${P(t)}`}}class nn extends de{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNPatchRelationshipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Relationship id cannot be empty";const e=this.parameters.add&&Object.keys(this.parameters.add).length>0,t=this.parameters.replace&&Object.keys(this.parameters.replace).length>0,s=this.parameters.remove&&this.parameters.remove.length>0;return e||t||s?void 0:"At least one of add, replace, or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/relationships/${P(t)}`}get body(){const e=e=>Object.fromEntries(Object.entries(e).map((([e,t])=>[`payload.${e}`,t]))),t=Fs(this.parameters.add?e(this.parameters.add):void 0,this.parameters.replace?e(this.parameters.replace):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(t)}}class rn extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetRelationshipOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Relationship id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/relationships/${P(t)}`}}class an extends de{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateEntityOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.entity?this.parameters.entity.entityClass?void 0===this.parameters.entity.entityClassVersion||null===this.parameters.entity.entityClassVersion?"Entity class version cannot be empty":void 0:"Entity class cannot be empty":"Entity cannot be empty"}get headers(){var e;const t=null!==(e=super.headers)&&void 0!==e?e:{};return Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.entity+json;version=1"})}get path(){const{keySet:{subscribeKey:e}}=this.parameters;return`/v1/datasync/subkeys/${e}/entities`}get body(){return JSON.stringify({data:this.parameters.entity})}}class on extends de{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetAllEntitiesOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.entityClass)return"Entity class cannot be empty"}get path(){return`/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/entities`}get queryParameters(){const{entityClass:e,entityClassVersion:t,cursor:s,limit:n,filter:r,sort:i,filterAdvanced:a}=this.parameters;return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({entity_class:e},void 0!==t?{entity_class_version:`${t}`}:{}),s?{cursor:s}:{}),n?{limit:`${n}`}:{}),r?{filter:r}:{}),i?{sort:i}:{}),a?{filter_advanced:a}:{})}}class cn extends de{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNUpdateEntityOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.id?this.parameters.entity?void 0===this.parameters.entity.entityClassVersion||null===this.parameters.entity.entityClassVersion?"Entity class version cannot be empty":void 0:"Entity cannot be empty":"Entity id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/vnd.pubnub.objects.entity+json;version=1"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/entities/${P(t)}`}get body(){return JSON.stringify({data:this.parameters.entity})}}class un extends de{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveEntityOperation}validate(){if(!this.parameters.id)return"Entity id cannot be empty"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.keys(t).length>0?t:void 0}parse(e){return i(this,void 0,void 0,(function*(){return{status:e.status}}))}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/entities/${P(t)}`}}class hn extends de{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNPatchEntityOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Entity id cannot be empty";const e=this.parameters.add&&Object.keys(this.parameters.add).length>0,t=this.parameters.replace&&Object.keys(this.parameters.replace).length>0,s=this.parameters.remove&&this.parameters.remove.length>0;return e||t||s?void 0:"At least one of add, replace, or remove must be provided"}get headers(){var e;let t=null!==(e=super.headers)&&void 0!==e?e:{};return this.parameters.ifMatchesEtag&&(t=Object.assign(Object.assign({},t),{"If-Match":this.parameters.ifMatchesEtag})),Object.assign(Object.assign({},t),{"Content-Type":"application/json-patch+json"})}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/entities/${P(t)}`}get body(){const e=e=>Object.fromEntries(Object.entries(e).map((([e,t])=>[`payload.${e}`,t]))),t=Fs(this.parameters.add?e(this.parameters.add):void 0,this.parameters.replace?e(this.parameters.replace):void 0,this.parameters.remove?this.parameters.remove.map((e=>`payload.${e}`)):void 0);return JSON.stringify(t)}}class ln extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNGetEntityOperation}parse(e){return i(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){if(!this.parameters.id)return"Entity id cannot be empty"}get path(){const{keySet:{subscribeKey:e},id:t}=this.parameters;return`/v1/datasync/subkeys/${e}/entities/${P(t)}`}}class dn{constructor(e,t){this.keySet=e.keySet,this.configuration=e,this.sendRequest=t}get logger(){return this.configuration.logger()}createEntity(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Entity with parameters:"})));const s=new an(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getEntity(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Entity with parameters:"})));const s=new ln(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllEntities(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get all Entities with parameters:"})));const s=new on(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateEntity(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Entity with parameters:"})));const s=new cn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchEntity(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Entity with parameters:"})));const s=new hn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeEntity(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Entity with parameters:"})));const s=new un(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createRelationship(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Relationship with parameters:"})));const s=new Zs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getRelationship(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Relationship with parameters:"})));const s=new rn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllRelationships(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get all Relationships with parameters:"})));const s=new en(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateRelationship(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Relationship with parameters:"})));const s=new tn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchRelationship(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Relationship with parameters:"})));const s=new nn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeRelationship(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Relationship with parameters:"})));const s=new sn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User with parameters:"})));const s=new Is(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getUser(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get User with parameters:"})));const s=new qs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllUsers(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},s),details:"Get all Users with parameters:"})));const n=new Us(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User with parameters:"})));const s=new As(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchUser(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch User with parameters:"})));const s=new xs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove User with parameters:"})));const s=new $s(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createChannel(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Channel with parameters:"})));const s=new Gs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getChannel(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel with parameters:"})));const s=new Ws(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllChannels(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},s),details:"Get all Channels with parameters:"})));const n=new Ls(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}updateChannel(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Channel with parameters:"})));const s=new Ks(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchChannel(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Channel with parameters:"})));const s=new Bs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeChannel(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel with parameters:"})));const s=new Hs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createMembership(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Membership with parameters:"})));const s=new Vs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getMembership(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Membership with parameters:"})));const s=new Ys(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getAllMemberships(e,t){return i(this,void 0,void 0,(function*(){const s=e&&"function"!=typeof e?e:{};null!=t||(t="function"==typeof e?e:void 0),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},s),details:"Get all Memberships with parameters:"})));const n=new zs(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}updateMembership(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Membership with parameters:"})));const s=new Js(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}patchMembership(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Patch Membership with parameters:"})));const s=new Qs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeMembership(e,t){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Membership with parameters:"})));const s=new Xs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}}class pn extends de{constructor(){super()}operation(){return K.PNTimeOperation}parse(e){return i(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class gn extends de{constructor(e){super(),this.parameters=e}operation(){return K.PNDownloadFileOperation}validate(){const{channel:e,id:t,name:s}=this.parameters;return e?t?s?void 0:"file name can't be empty":"file id can't be empty":"channel can't be empty"}parse(e){return i(this,void 0,void 0,(function*(){const{cipherKey:t,crypto:s,cryptography:n,name:r,PubNubFile:i}=this.parameters,a=e.headers["content-type"];let o,c=e.body;return i.supportsEncryptFile&&(t||s)&&(t&&n?c=yield n.decrypt(t,c):!t&&s&&(o=yield s.decryptFile(i.create({data:c,name:r,mimeType:a}),i))),o||i.create({data:c,name:r,mimeType:a})}))}get path(){const{keySet:{subscribeKey:e},channel:t,id:s,name:n}=this.parameters;return`/v1/files/${e}/channels/${P(t)}/files/${P(s)}/${P(n)}`}}class bn{static notificationPayload(e,t){return new we(e,t)}static generateUUID(){return ne.createUUID()}constructor(e){if(this.eventHandleCapable={},this.entities={},this._configuration=e.configuration,this.cryptography=e.cryptography,this.tokenManager=e.tokenManager,this.transport=e.transport,this.crypto=e.crypto,this.logger.debug("PubNub",(()=>({messageType:"object",message:e.configuration,details:"Create with configuration:",ignoredKeys:(e,t)=>"function"==typeof t[e]||e.startsWith("_")||"keySet"===e||w(e)}))),this._objects=new Rs(this._configuration,this.sendRequest.bind(this)),this._dataSync=new dn(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new ps(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new vs(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new ye,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new tt({heartbeat:(e,t)=>(this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"}))),this.heartbeat(e,t)),leave:e=>{this.logger.trace("PresenceEventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,(()=>{}))},heartbeatDelay:()=>new Promise(((t,s)=>{e=this._configuration.getHeartbeatInterval(),e?setTimeout(t,1e3*e):s(new d("Heartbeat interval has been reset."))})),emitStatus:e=>this.emitStatus(e),config:this._configuration,presenceState:this.presenceState})),this.eventEngine=new kt({handshake:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Handshake with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeHandshake(e)),receiveMessages:e=>(this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Receive messages with parameters:",ignoredKeys:["abortSignal","crypto","timeout","keySet","getFileUrl"]}))),this.subscribeReceiveMessages(e)),delay:e=>new Promise((t=>setTimeout(t,e))),join:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'join' announcement request."):this.join(e)},leave:e=>{var t,s;this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("EventEngine","Ignoring 'leave' announcement request."):this.leave(e)},leaveAll:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.leaveAll(e)},presenceReconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.presenceReconnect(e)},presenceDisconnect:e=>{this.logger.trace("EventEngine",(()=>({messageType:"object",message:Object.assign({},e),details:"Disconnect with parameters:"}))),this.presenceDisconnect(e)},presenceState:this.presenceState,config:this._configuration,emitMessages:(e,t)=>{try{this.logger.debug("EventEngine",(()=>({messageType:"object",message:t.map((e=>{const t=e.type===pe.Message||e.type===pe.Signal?I(e.data.message):void 0;return t?{type:e.type,data:Object.assign(Object.assign({},e.data),{pn_mfp:t})}:e})),details:"Received events:"}))),t.forEach((t=>this.emitEvent(e,t)))}catch(e){const t={error:!0,category:l.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}},emitStatus:e=>this.emitStatus(e)})}else this.logger.debug("PubNub","Using legacy subscription loop management."),this.subscriptionManager=new Oe(this._configuration,((e,t)=>{try{this.emitEvent(e,t)}catch(e){const t={error:!0,category:l.PNUnknownCategory,errorData:e,statusCode:0};this.emitStatus(t)}}),this.emitStatus.bind(this),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.makeSubscribe(e,t)}),((e,t)=>(this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:",ignoredKeys:["crypto","timeout","keySet","getFileUrl"]}))),this.heartbeat(e,t))),((e,t)=>{this.logger.trace("SubscriptionManager",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),this.makeUnsubscribe(e,t)}),this.time.bind(this))}get configuration(){return this._configuration}get _config(){return this.configuration}get authKey(){var e;return null!==(e=this._configuration.authKey)&&void 0!==e?e:void 0}getAuthKey(){return this.authKey}setAuthKey(e){this.logger.debug("PubNub","Auth key updated."),this._configuration.setAuthKey(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}get userId(){return this._configuration.userId}set userId(e){if(!e||"string"!=typeof e||0===e.trim().length){const e=new Error("Missing or invalid userId parameter. Provide a valid string userId");throw this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),e}this.logger.debug("PubNub",`Set user ID: ${e}`),this._configuration.userId=e,this.onUserIdChange&&this.onUserIdChange(this._configuration.userId)}getUserId(){return this._configuration.userId}setUserId(e){this.userId=e}get filterExpression(){var e;return null!==(e=this._configuration.getFilterExpression())&&void 0!==e?e:void 0}getFilterExpression(){return this.filterExpression}set filterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this._configuration.setFilterExpression(e)}setFilterExpression(e){this.logger.debug("PubNub",`Set filter expression: ${e}`),this.filterExpression=e}get cipherKey(){return this._configuration.getCipherKey()}set cipherKey(e){this._configuration.setCipherKey(e)}setCipherKey(e){this.logger.debug("PubNub","Cipher key updated."),this.cipherKey=e}set heartbeatInterval(e){var t;this.logger.debug("PubNub",`Set heartbeat interval: ${e}`),this._configuration.setHeartbeatInterval(e),this.onHeartbeatIntervalChange&&this.onHeartbeatIntervalChange(null!==(t=this._configuration.getHeartbeatInterval())&&void 0!==t?t:0)}setHeartbeatInterval(e){this.heartbeatInterval=e}get logger(){return this._configuration.logger()}getVersion(){return this._configuration.getVersion()}_addPnsdkSuffix(e,t){this.logger.debug("PubNub",`Add '${e}' 'pnsdk' suffix: ${t}`),this._configuration._addPnsdkSuffix(e,t)}getUUID(){return this.userId}setUUID(e){this.logger.warn("PubNub","'setUserId` is deprecated, please use 'setUserId' or 'userId' setter instead."),this.logger.debug("PubNub",`Set UUID: ${e}`),this.userId=e}get customEncrypt(){return this._configuration.getCustomEncrypt()}get customDecrypt(){return this._configuration.getCustomDecrypt()}channel(e){let t=this.entities[`${e}_ch`];return t||(t=this.entities[`${e}_ch`]=new os(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new is(e,this)),t}channelMetadata(e){let t=this.entities[`${e}_chm`];return t||(t=this.entities[`${e}_chm`]=new rs(e,this)),t}userMetadata(e){let t=this.entities[`${e}_um`];return t||(t=this.entities[`${e}_um`]=new as(e,this)),t}subscriptionSet(e){var t,s;{const n=[];return null===(t=e.channels)||void 0===t||t.forEach((e=>n.push(this.channel(e)))),null===(s=e.channelGroups)||void 0===s||s.forEach((e=>n.push(this.channelGroup(e)))),new It({client:this,entities:n,options:e.subscriptionOptions})}}sendRequest(e,t){return i(this,void 0,void 0,(function*(){const s=e.validate();if(s){const e=(n=s,p(Object.assign({message:n},{}),l.PNValidationErrorCategory));if(this.logger.error("PubNub",(()=>({messageType:"error",message:e}))),t)return t(e,null);throw new d("Validation failed, check status for details",e)}var n;const r=e.request(),i=e.operation();r.formData&&r.formData.length>0||i===K.PNDownloadFileOperation?r.timeout=this._configuration.getFileTimeout():i===K.PNSubscribeOperation||i===K.PNReceiveMessagesOperation?r.timeout=this._configuration.getSubscribeTimeout():r.timeout=this._configuration.getTransactionTimeout();const a={error:!1,operation:i,category:l.PNAcknowledgmentCategory,statusCode:0},[o,c]=this.transport.makeSendable(r);return e.cancellationController=c||null,o.then((t=>{if(a.statusCode=t.status,200!==t.status&&204!==t.status){const e=bn.decoder.decode(t.body),s=t.headers["content-type"];if(s||-1!==s.indexOf("javascript")||-1!==s.indexOf("json")){const t=JSON.parse(e);"object"==typeof t&&"error"in t&&t.error&&"object"==typeof t.error&&(a.errorData=t.error)}else a.responseText=e}return e.parse(t)})).then((e=>t?t(a,e):e)).catch((e=>{const s=e instanceof G?e:G.create(e),n=s.toFormattedMessage(i);if(t)return s.category!==l.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:s.toPubNubError(i,n)}))),t(s.toStatus(i),null);const r=s.toPubNubError(i,n);throw s.category!==l.PNCancelledCategory&&this.logger.error("PubNub",(()=>({messageType:"error",message:r}))),r}))}))}destroy(e=!1){this.logger.info("PubNub","Destroying PubNub client."),this._globalSubscriptionSet&&(this._globalSubscriptionSet.invalidate(!0),this._globalSubscriptionSet=void 0),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!0))),this.eventHandleCapable={},this.subscriptionManager?(this.subscriptionManager.unsubscribeAll(e),this.subscriptionManager.disconnect()):this.eventEngine&&this.eventEngine.unsubscribeAll(e),this.presenceEventEngine&&this.presenceEventEngine.leaveAll(e)}stop(){this.logger.warn("PubNub","'stop' is deprecated, please use 'destroy' instead."),this.destroy()}publish(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish with parameters:"})));const s=!1===e.replicate&&!1===e.storeInHistory,n=new wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),r=e=>{e&&this.logger.debug("PubNub",`${s?"Fire":"Publish"} success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}signal(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Signal with parameters:"})));const s=new Pt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Publish success with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fire(e,t){return i(this,void 0,void 0,(function*(){return this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fire with parameters:"}))),null!=t||(t=()=>{}),this.publish(Object.assign(Object.assign({},e),{replicate:!1,storeInHistory:!1}),t)}))}get globalSubscriptionSet(){return this._globalSubscriptionSet||(this._globalSubscriptionSet=this.subscriptionSet({})),this._globalSubscriptionSet}get subscriptionTimetoken(){return this.subscriptionManager?this.subscriptionManager.subscriptionTimetoken:this.eventEngine?this.eventEngine.subscriptionTimetoken:void 0}getSubscribedChannels(){return this.subscriptionManager?this.subscriptionManager.subscribedChannels:this.eventEngine?this.eventEngine.getSubscribedChannels():[]}getSubscribedChannelGroups(){return this.subscriptionManager?this.subscriptionManager.subscribedChannelGroups:this.eventEngine?this.eventEngine.getSubscribedChannelGroups():[]}registerEventHandleCapable(e,t,s){{let n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign(Object.assign({subscription:e},t?{cursor:t}:[]),s?{subscriptions:s}:{}),details:"Register event handle capable:"}))),this.eventHandleCapable[e.state.id]||(this.eventHandleCapable[e.state.id]=e),s&&0!==s.length?(n=new Tt({}),s.forEach((e=>n.add(e.subscriptionInput(!1))))):n=e.subscriptionInput(!1);const r={};r.channels=n.channels,r.channelGroups=n.channelGroups,t&&(r.timetoken=t.timetoken),this.subscriptionManager?this.subscriptionManager.subscribe(r):this.eventEngine&&this.eventEngine.subscribe(r)}}unregisterEventHandleCapable(e,t){{if(!this.eventHandleCapable[e.state.id])return;const s=[];this.logger.trace("PubNub",(()=>({messageType:"object",message:{subscription:e,subscriptions:t},details:"Unregister event handle capable:"})));let n,r=!t||0===t.length;if(!r&&e instanceof It&&e.subscriptions.length===(null==t?void 0:t.length)&&(r=e.subscriptions.every((e=>t.includes(e)))),r&&delete this.eventHandleCapable[e.state.id],t&&0!==t.length?(n=new Tt({}),t.forEach((e=>{const t=e.subscriptionInput(!0);t.isEmpty?s.push(e):n.add(t)}))):(n=e.subscriptionInput(!0),n.isEmpty&&s.push(e)),s.length>0&&this.logger.trace("PubNub",(()=>{const e=[];return s[0]instanceof It?s[0].subscriptions.forEach((t=>e.push(t.state.entity))):s.forEach((t=>e.push(t.state.entity))),{messageType:"object",message:{entities:e},details:"Can't unregister event handle capable because entities still in use:"}})),n.isEmpty)return;{const e=[],t=[];if(Object.values(this.eventHandleCapable).forEach((s=>{const r=s.subscriptionInput(!1),i=r.channelGroups,a=r.channels;e.push(...n.channelGroups.filter((e=>i.includes(e)))),t.push(...n.channels.filter((e=>a.includes(e))))})),(t.length>0||e.length>0)&&(this.logger.trace("PubNub",(()=>{const s=[],r=n=>{const r=n.subscriptionNames(!0),i=n.subscriptionType===Et.Channel?t:e;r.some((e=>i.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof It?e.subscriptions.forEach((e=>{r(e.state.entity)})):e instanceof At&&r(e.state.entity)}));let i="Some entities still in use:";return t.length+e.length===n.length&&(i="Can't unregister event handle capable because entities still in use:"),{messageType:"object",message:{entities:s},details:i}})),n.remove(new Tt({channels:t,channelGroups:e})),n.isEmpty))return}const i={};i.channels=n.channels,i.channelGroups=n.channelGroups,this.subscriptionManager?this.subscriptionManager.unsubscribe(i):this.eventEngine&&this.eventEngine.unsubscribe(i)}}subscribe(e){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Subscribe with parameters:"})));const t=this.subscriptionSet(Object.assign(Object.assign({},e),{subscriptionOptions:{receivePresenceEvents:e.withPresence}}));this.globalSubscriptionSet.addSubscriptionSet(t),t.dispose();const s="number"==typeof e.timetoken?`${e.timetoken}`:e.timetoken;this.globalSubscriptionSet.subscribe({timetoken:s})}}makeSubscribe(e,t){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const s=new me(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)}));if(this.sendRequest(s,((e,n)=>{var r;this.subscriptionManager&&(null===(r=this.subscriptionManager.abort)||void 0===r?void 0:r.identifier)===s.requestIdentifier&&(this.subscriptionManager.abort=null),t(e,n)})),this.subscriptionManager){const e=()=>s.abort("Cancel long-poll subscribe request");e.identifier=s.requestIdentifier,this.subscriptionManager.abort=e}}}unsubscribe(e){{if(this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Unsubscribe with parameters:"}))),!this._globalSubscriptionSet)return void this.logger.debug("PubNub","There are no active subscriptions. Ignore.");const t=this.globalSubscriptionSet.subscriptions.filter((t=>{var s,n;const r=t.subscriptionInput(!1);if(r.isEmpty)return!1;for(const t of null!==(s=e.channels)&&void 0!==s?s:[])if(r.contains(t))return!0;for(const t of null!==(n=e.channelGroups)&&void 0!==n?n:[])if(r.contains(t))return!0}));t.length>0&&this.globalSubscriptionSet.removeSubscriptions(t)}}makeUnsubscribe(e,t){{let{channels:s,channelGroups:n}=e;if(this._configuration.getKeepPresenceChannelsInPresenceRequests()||(n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),s&&(s=s.filter((e=>!e.endsWith("-pnpres"))))),0===(null!=n?n:[]).length&&0===(null!=s?s:[]).length)return t({error:!1,operation:K.PNUnsubscribeOperation,category:l.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new xt({channels:s,channelGroups:n,keySet:this._configuration.keySet}),t)}}unsubscribeAll(){this.logger.debug("PubNub","Unsubscribe all channels and groups"),this._globalSubscriptionSet&&this._globalSubscriptionSet.invalidate(!1),Object.values(this.eventHandleCapable).forEach((e=>e.invalidate(!1))),this.eventHandleCapable={},this.subscriptionManager?this.subscriptionManager.unsubscribeAll():this.eventEngine&&this.eventEngine.unsubscribeAll()}disconnect(e=!1){this.logger.debug("PubNub",`Disconnect (while offline? ${e?"yes":"no"})`),this.subscriptionManager?this.subscriptionManager.disconnect():this.eventEngine&&this.eventEngine.disconnect(e)}reconnect(e){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Reconnect with parameters:"}))),this.subscriptionManager?this.subscriptionManager.reconnect():this.eventEngine&&this.eventEngine.reconnect(null!=e?e:{})}subscribeHandshake(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new Nt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel subscribe handshake request")}));return this.sendRequest(t).then((e=>(s(),e.cursor)))}}))}subscribeReceiveMessages(e){return i(this,void 0,void 0,(function*(){{this._configuration.isSharedWorkerEnabled()||(e.onDemand=!1);const t=new Ct(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),s=e.abortSignal.subscribe((e=>{t.abort("Cancel long-poll subscribe request")}));return this.sendRequest(t).then((e=>(s(),e)))}}))}getMessageActions(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get message actions with parameters:"})));const s=new Vt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Get message actions success. Received ${e.data.length} message actions.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}addMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Add message action with parameters:"})));const s=new zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Message action add success. Message action added with timetoken: ${e.data.actionTimetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}removeMessageAction(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove message action with parameters:"})));const s=new Jt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Message action remove success. Removed message action with ${e.actionTimetoken} timetoken.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}fetchMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch messages with parameters:"})));const s=new Wt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule(),getFileUrl:this.getFileUrl.bind(this)})),n=e=>{if(!e)return;const t=Object.values(e.channels).reduce(((e,t)=>e+t.length),0);this.logger.debug("PubNub",`Fetch messages success. Received ${t} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteMessages(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete messages with parameters:"})));const s=new Lt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub","Delete messages success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}messageCounts(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get messages count with parameters:"})));const s=new Kt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{if(!t)return;const s=Object.values(t.channels).reduce(((e,t)=>e+t),0);this.logger.debug("PubNub",`Get messages count success. There are ${s} messages since provided reference timetoken${e.channelTimetokens?e.channelTimetokens.join(","):""}.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}history(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch history with parameters:"})));const s=new Ht(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Fetch history success. Received ${e.messages.length} messages.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}hereNow(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Here now with parameters:"})));const s=new Gt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`Here now success. There are ${e.totalOccupancy} participants in ${e.totalChannels} channels.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}whereNow(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Where now with parameters:"})));const n=new qt({uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet}),r=e=>{e&&this.logger.debug("PubNub",`Where now success. Currently present in ${e.channels.length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}getState(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get presence state with parameters:"})));const n=new $t(Object.assign(Object.assign({},e),{uuid:null!==(s=e.uuid)&&void 0!==s?s:this._configuration.userId,keySet:this._configuration.keySet})),r=e=>{e&&this.logger.debug("PubNub",`Get presence state success. Received presence state for ${Object.keys(e.channels).length} channels.`)};return t?this.sendRequest(n,((e,s)=>{r(s),t(e,s)})):this.sendRequest(n).then((e=>(r(e),e)))}}))}setState(e,t){return i(this,void 0,void 0,(function*(){var s,n;{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set presence state with parameters:"})));const{keySet:r,userId:i}=this._configuration,a=this._configuration.getPresenceTimeout();let o;if(this._configuration.enableEventEngine&&this.presenceState){const t=this.presenceState;null===(s=e.channels)||void 0===s||s.forEach((s=>t[s]=e.state)),"channelGroups"in e&&(null===(n=e.channelGroups)||void 0===n||n.forEach((s=>t[s]=e.state))),this.onPresenceStateChange&&this.onPresenceStateChange(this.presenceState)}o="withHeartbeat"in e&&e.withHeartbeat?new Ft(Object.assign(Object.assign({},e),{keySet:r,heartbeat:a})):new Dt(Object.assign(Object.assign({},e),{keySet:r,uuid:i}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof Ft?" Presence state has been set using heartbeat endpoint.":""))};return this.subscriptionManager&&(this.subscriptionManager.setState(e),this.onPresenceStateChange&&this.onPresenceStateChange(this.subscriptionManager.presenceState)),t?this.sendRequest(o,((e,s)=>{c(s),t(e,s)})):this.sendRequest(o).then((e=>(c(e),e)))}}))}presence(e){var t;this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Change presence with parameters:"}))),null===(t=this.subscriptionManager)||void 0===t||t.changePresence(e)}heartbeat(e,t){return i(this,void 0,void 0,(function*(){var s;{this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Heartbeat with parameters:"})));let{channels:n,channelGroups:r}=e;if(r&&(r=r.filter((e=>!e.endsWith("-pnpres")))),n&&(n=n.filter((e=>!e.endsWith("-pnpres")))),0===(null!=r?r:[]).length&&0===(null!=n?n:[]).length){const e={error:!1,operation:K.PNHeartbeatOperation,category:l.PNAcknowledgmentCategory,statusCode:200};return this.logger.trace("PubNub","There are no active subscriptions. Ignore."),t?t(e,{}):Promise.resolve(e)}const i=new Ft(Object.assign(Object.assign({},e),{channels:[...new Set(n)],channelGroups:[...new Set(r)],keySet:this._configuration.keySet})),a=e=>{e&&this.logger.trace("PubNub","Heartbeat success.")},o=null===(s=e.abortSignal)||void 0===s?void 0:s.subscribe((e=>{i.abort("Cancel long-poll subscribe request")}));return t?this.sendRequest(i,((e,s)=>{a(s),o&&o(),t(e,s)})):this.sendRequest(i).then((e=>(a(e),o&&o(),e)))}}))}join(e){var t,s;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Join with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'join' announcement request."):this.presenceEventEngine?this.presenceEventEngine.join(e):this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&this.presenceState&&Object.keys(this.presenceState).length>0&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}presenceReconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence reconnect with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.reconnect():this.heartbeat(Object.assign(Object.assign({channels:e.channels,channelGroups:e.groups},this._configuration.maintainPresenceState&&{state:this.presenceState}),{heartbeat:this._configuration.getPresenceTimeout()}),(()=>{}))}leave(e){var t,s,n;this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave with parameters:"}))),e&&0===(null!==(t=e.channels)&&void 0!==t?t:[]).length&&0===(null!==(s=e.groups)&&void 0!==s?s:[]).length?this.logger.trace("PubNub","Ignoring 'leave' announcement request."):this.presenceEventEngine?null===(n=this.presenceEventEngine)||void 0===n||n.leave(e):this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}leaveAll(e={}){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Leave all with parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.leaveAll(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}presenceDisconnect(e){this.logger.trace("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Presence disconnect parameters:"}))),this.presenceEventEngine?this.presenceEventEngine.disconnect(!!e.isOffline):e.isOffline||this.makeUnsubscribe({channels:e.channels,channelGroups:e.groups},(()=>{}))}grantToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Token error: PAM module disabled")}))}revokeToken(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Revoke Token error: PAM module disabled")}))}get token(){return this.tokenManager&&this.tokenManager.getToken()}getToken(){return this.token}set token(e){this.tokenManager&&this.tokenManager.setToken(e),this.onAuthenticationChange&&this.onAuthenticationChange(e)}setToken(e){this.logger.debug("PubNub","Access token updated."),this.token=e}parseToken(e){return this.logger.debug("PubNub","Parse access token."),this.tokenManager&&this.tokenManager.parseToken(e)}grant(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant error: PAM module disabled")}))}audit(e,t){return i(this,void 0,void 0,(function*(){throw new Error("Grant Permissions error: PAM module disabled")}))}get objects(){return this._objects}get dataSync(){return this._dataSync}fetchUsers(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUsers' is deprecated. Use 'pubnub.objects.getAllUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all User objects with parameters:"}))),this.objects._getAllUUIDMetadata(e,t)}))}fetchUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchUser' is deprecated. Use 'pubnub.objects.getUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Fetch${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._getUUIDMetadata(e,t)}))}createUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}updateUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateUser' is deprecated. Use 'pubnub.objects.setUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User object with parameters:"}))),this.objects._setUUIDMetadata(e,t)}))}removeUser(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeUser' is deprecated. Use 'pubnub.objects.removeUUIDMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{uuid:this.userId},details:`Remove${e&&"function"!=typeof e?"":" current"} User object with parameters:`}))),this.objects._removeUUIDMetadata(e,t)}))}fetchSpaces(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpaces' is deprecated. Use 'pubnub.objects.getAllChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:e&&"function"!=typeof e?e:{},details:"Fetch all Space objects with parameters:"}))),this.objects._getAllChannelMetadata(e,t)}))}fetchSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'fetchSpace' is deprecated. Use 'pubnub.objects.getChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Fetch Space object with parameters:"}))),this.objects._getChannelMetadata(e,t)}))}createSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'createSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}updateSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'updateSpace' is deprecated. Use 'pubnub.objects.setChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Space object with parameters:"}))),this.objects._setChannelMetadata(e,t)}))}removeSpace(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'removeSpace' is deprecated. Use 'pubnub.objects.removeChannelMetadata' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Space object with parameters:"}))),this.objects._removeChannelMetadata(e,t)}))}fetchMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.fetchMemberships(e,t)}))}addMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.objects.addMemberships(e,t)}))}updateMemberships(e,t){return i(this,void 0,void 0,(function*(){return this.logger.warn("PubNub","'addMemberships' is deprecated. Use 'pubnub.objects.setChannelMembers' or 'pubnub.objects.setMemberships' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update memberships with parameters:"}))),this.objects.addMemberships(e,t)}))}removeMemberships(e,t){return i(this,void 0,void 0,(function*(){var s,n,r;{if(this.logger.warn("PubNub","'removeMemberships' is deprecated. Use 'pubnub.objects.removeMemberships' or 'pubnub.objects.removeChannelMembers' instead."),this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove memberships with parameters:"}))),"spaceId"in e){const r=e,i={channel:null!==(s=r.spaceId)&&void 0!==s?s:r.channel,uuids:null!==(n=r.userIds)&&void 0!==n?n:r.uuids,limit:0};return t?this.objects.removeChannelMembers(i,t):this.objects.removeChannelMembers(i)}const i=e,a={uuid:i.userId,channels:null!==(r=i.spaceIds)&&void 0!==r?r:i.channels,limit:0};return t?this.objects.removeMemberships(a,t):this.objects.removeMemberships(a)}}))}get channelGroups(){return this._channelGroups}get push(){return this._push}sendFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Send file with parameters:"})));const s=new ss(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,fileUploadPublishRetryLimit:this._configuration.fileUploadPublishRetryLimit,file:e.file,sendRequest:this.sendRequest.bind(this),publishFile:this.publishFile.bind(this),crypto:this._configuration.getCryptoModule(),cryptography:this.cryptography?this.cryptography:void 0})),n={error:!1,operation:K.PNPublishFileOperation,category:l.PNAcknowledgmentCategory,statusCode:0},r=e=>{e&&this.logger.debug("PubNub",`Send file success. File shared with ${e.id} ID.`)};return s.process().then((e=>(n.statusCode=e.status,r(e),t?t(n,e):e))).catch((e=>{let s;throw e instanceof d?s=e.status:e instanceof G&&(s=e.toStatus(n.operation)),this.logger.error("PubNub",(()=>({messageType:"error",message:new d("File sending error. Check status for details",s)}))),t&&s&&t(s,null),new d("REST API request processing error. Check status for details",s)}))}}))}publishFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Publish file message with parameters:"})));const s=new Xt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub",`Publish file message success. File message published with timetoken: ${e.timetoken}`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}listFiles(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"List files with parameters:"})));const s=new Zt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=e=>{e&&this.logger.debug("PubNub",`List files success. There are ${e.count} uploaded files.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}getFileUrl(e){var t;{const s=this.transport.request(new Qt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})).request()),n=null!==(t=s.queryParameters)&&void 0!==t?t:{},r=Object.keys(n).map((e=>{const t=n[e];return Array.isArray(t)?t.map((t=>`${e}=${P(t)}`)).join("&"):`${e}=${P(t)}`})).join("&");return`${s.origin}${s.path}?${r}`}}downloadFile(e,t){return i(this,void 0,void 0,(function*(){{if(!this._configuration.PubNubFile)throw new Error("Validation failed: 'PubNubFile' not configured or file upload not supported by the platform.");this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Download file with parameters:"})));const s=new gn(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet,PubNubFile:this._configuration.PubNubFile,cryptography:this.cryptography?this.cryptography:void 0,crypto:this._configuration.getCryptoModule()})),n=e=>{e&&this.logger.debug("PubNub","Download file success.")};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):yield this.sendRequest(s).then((e=>(n(e),e)))}}))}deleteFile(e,t){return i(this,void 0,void 0,(function*(){{this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Delete file with parameters:"})));const s=new Yt(Object.assign(Object.assign({},e),{keySet:this._configuration.keySet})),n=t=>{t&&this.logger.debug("PubNub",`Delete file success. Deleted file with ${e.id} ID.`)};return t?this.sendRequest(s,((e,s)=>{n(s),t(e,s)})):this.sendRequest(s).then((e=>(n(e),e)))}}))}time(e){return i(this,void 0,void 0,(function*(){this.logger.debug("PubNub","Get service time.");const t=new pn,s=e=>{e&&this.logger.debug("PubNub",`Get service time success. Current timetoken: ${e.timetoken}`)};return e?this.sendRequest(t,((t,n)=>{s(n),e(t,n)})):this.sendRequest(t).then((e=>(s(e),e)))}))}emitStatus(e){var t;null===(t=this.eventDispatcher)||void 0===t||t.handleStatus(e)}emitEvent(e,t){var s;this._globalSubscriptionSet&&this._globalSubscriptionSet.handleEvent(e,t),null===(s=this.eventDispatcher)||void 0===s||s.handleEvent(t),Object.values(this.eventHandleCapable).forEach((s=>{s!==this._globalSubscriptionSet&&s.handleEvent(e,t)}))}set onStatus(e){this.eventDispatcher&&(this.eventDispatcher.onStatus=e)}set onMessage(e){this.eventDispatcher&&(this.eventDispatcher.onMessage=e)}set onPresence(e){this.eventDispatcher&&(this.eventDispatcher.onPresence=e)}set onSignal(e){this.eventDispatcher&&(this.eventDispatcher.onSignal=e)}set onObjects(e){this.eventDispatcher&&(this.eventDispatcher.onObjects=e)}set onMessageAction(e){this.eventDispatcher&&(this.eventDispatcher.onMessageAction=e)}set onFile(e){this.eventDispatcher&&(this.eventDispatcher.onFile=e)}set onDataSync(e){this.eventDispatcher&&(this.eventDispatcher.onDataSync=e)}addListener(e){this.eventDispatcher&&this.eventDispatcher.addListener(e)}removeListener(e){this.eventDispatcher&&this.eventDispatcher.removeListener(e)}removeAllListeners(){this.eventDispatcher&&this.eventDispatcher.removeAllListeners()}encrypt(e,t){this.logger.warn("PubNub","'encrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s&&"string"==typeof e){const t=s.encrypt(e);return"string"==typeof t?t:u(t)}if(!this.crypto)throw new Error("Encryption error: cypher key not set");return this.crypto.encrypt(e,t)}decrypt(e,t){this.logger.warn("PubNub","'decrypt' is deprecated. Use cryptoModule instead.");const s=this._configuration.getCryptoModule();if(!t&&s){const t=s.decrypt(e);return t instanceof ArrayBuffer?JSON.parse((new TextDecoder).decode(t)):t}if(!this.crypto)throw new Error("Decryption error: cypher key not set");return this.crypto.decrypt(e,t)}encryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File encryption error. File constructor not configured.");if("string"!=typeof e&&!this._configuration.getCryptoModule())throw new Error("File encryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File encryption error. File encryption not available");return this.cryptography.encryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.encryptFile(t,this._configuration.PubNubFile)}))}decryptFile(e,t){return i(this,void 0,void 0,(function*(){var s;if("string"!=typeof e&&(t=e),!t)throw new Error("File encryption error. Source file is missing.");if(!this._configuration.PubNubFile)throw new Error("File decryption error. File constructor not configured.");if("string"==typeof e&&!this._configuration.getCryptoModule())throw new Error("File decryption error. Crypto module not configured.");if("string"==typeof e){if(!this.cryptography)throw new Error("File decryption error. File decryption not available");return this.cryptography.decryptFile(e,t,this._configuration.PubNubFile)}return null===(s=this._configuration.getCryptoModule())||void 0===s?void 0:s.decryptFile(t,this._configuration.PubNubFile)}))}}bn.decoder=new TextDecoder,bn.OPERATIONS=K,bn.CATEGORIES=l,bn.Endpoint=z,bn.ExponentialRetryPolicy=X.ExponentialRetryPolicy,bn.LinearRetryPolicy=X.LinearRetryPolicy,bn.NoneRetryPolicy=X.None,bn.LogLevel=V;class mn{constructor(e,t){this.decode=e,this.base64ToBinary=t}decodeToken(e){let t="";e.length%4==3?t="=":e.length%4==2&&(t="==");const s=e.replace(/-/gi,"+").replace(/_/gi,"/")+t,n=this.decode(this.base64ToBinary(s));return"object"==typeof n?n:void 0}}class yn extends bn{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,r=W(e),i=Object.assign(Object.assign({},r),{sdkFamily:"Web"});i.PubNubFile=o;const a=re(i,(e=>{if(e.cipherKey){return new F({default:new D(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new j({cipherKey:e.cipherKey})]})}}));let u,h;e.subscriptionWorkerLogVerbosity?e.subscriptionWorkerLogLevel=V.Debug:void 0===e.subscriptionWorkerLogLevel&&(e.subscriptionWorkerLogLevel=V.None),void 0!==e.subscriptionWorkerLogVerbosity&&a.logger().warn("Configuration","'subscriptionWorkerLogVerbosity' is deprecated. Use 'subscriptionWorkerLogLevel' instead."),a.getCryptoModule()&&(a.getCryptoModule().logger=a.logger()),u=new oe(new mn((e=>B(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(h=new A({secretKey:a.secretKey,cipherKey:a.getCipherKey(),useRandomIVs:a.getUseRandomIVs(),customEncrypt:a.getCustomEncrypt(),customDecrypt:a.getCustomDecrypt(),logger:a.logger()}));let l,d=()=>{},p=()=>{},g=()=>{},b=()=>{};l=new $;let m=new le(a.logger(),i.transport);if(r.subscriptionWorkerUrl)try{const e=new H({clientIdentifier:a._instanceId,subscriptionKey:a.subscribeKey,userId:a.getUserId(),workerUrl:r.subscriptionWorkerUrl,sdkVersion:a.getVersion(),heartbeatInterval:a.getHeartbeatInterval(),announceSuccessfulHeartbeats:a.announceSuccessfulHeartbeats,announceFailedHeartbeats:a.announceFailedHeartbeats,workerOfflineClientsCheckInterval:i.subscriptionWorkerOfflineClientsCheckInterval,workerUnsubscribeOfflineClients:i.subscriptionWorkerUnsubscribeOfflineClients,workerLogLevel:i.subscriptionWorkerLogLevel,tokenManager:u,transport:m,logger:a.logger()});p=t=>e.onPresenceStateChange(t),d=t=>e.onHeartbeatIntervalChange(t),g=t=>e.onTokenChange(t),b=t=>e.onUserIdChange(t),m=e,r.subscriptionWorkerUnsubscribeOfflineClients&&"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("pagehide",(t=>{t.persisted||e.terminate()}),{once:!0})}catch(e){a.logger().error("PubNub",(()=>({messageType:"error",message:e})))}else s&&a.logger().warn("PubNub","SharedWorker not supported in this browser. Fallback to the original transport.");const y=new he({clientConfiguration:a,tokenManager:u,transport:m});if(super({configuration:a,transport:y,cryptography:l,tokenManager:u,crypto:h}),this.File=o,this.onHeartbeatIntervalChange=d,this.onAuthenticationChange=g,this.onPresenceStateChange=p,this.onUserIdChange=b,m instanceof H){m.emitStatus=this.emitStatus.bind(this);const e=this.disconnect.bind(this);this.disconnect=t=>{m.disconnect(),e()}}(null===(t=e.listenToBrowserNetworkEvents)||void 0===t||t)&&"undefined"!=typeof window&&window.addEventListener&&(window.addEventListener("offline",(()=>{this.networkDownDetected()})),window.addEventListener("online",(()=>{this.networkUpDetected()})))}networkDownDetected(){this.logger.debug("PubNub","Network down detected"),this.emitStatus({category:yn.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:yn.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return yn.CryptoModule=F,yn})); diff --git a/lib/core/endpoints/data_sync/channel/create.js b/lib/core/endpoints/data_sync/channel/create.js index 70052251c..d03154668 100644 --- a/lib/core/endpoints/data_sync/channel/create.js +++ b/lib/core/endpoints/data_sync/channel/create.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class CreateChannelRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNCreateChannelOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.channel) return 'Channel cannot be empty'; diff --git a/lib/core/endpoints/data_sync/channel/get-all.js b/lib/core/endpoints/data_sync/channel/get-all.js index 1cf77d7bb..4ec4a48f2 100644 --- a/lib/core/endpoints/data_sync/channel/get-all.js +++ b/lib/core/endpoints/data_sync/channel/get-all.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -36,6 +45,14 @@ class GetAllChannelsRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllChannelsOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } get path() { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/channels`; } diff --git a/lib/core/endpoints/data_sync/channel/get.js b/lib/core/endpoints/data_sync/channel/get.js index 4a7604b90..c2e8cd1e3 100644 --- a/lib/core/endpoints/data_sync/channel/get.js +++ b/lib/core/endpoints/data_sync/channel/get.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class GetChannelRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetChannelOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Channel id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/channel/patch.js b/lib/core/endpoints/data_sync/channel/patch.js index 59234a96d..5be9797c0 100644 --- a/lib/core/endpoints/data_sync/channel/patch.js +++ b/lib/core/endpoints/data_sync/channel/patch.js @@ -8,6 +8,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -32,6 +41,14 @@ class PatchChannelRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNPatchChannelOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Channel id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/channel/update.js b/lib/core/endpoints/data_sync/channel/update.js index 530e0558c..3312e6592 100644 --- a/lib/core/endpoints/data_sync/channel/update.js +++ b/lib/core/endpoints/data_sync/channel/update.js @@ -6,6 +6,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -29,6 +38,14 @@ class UpdateChannelRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNUpdateChannelOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Channel id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/entity/create.js b/lib/core/endpoints/data_sync/entity/create.js index 5e5e626e4..1615e603f 100644 --- a/lib/core/endpoints/data_sync/entity/create.js +++ b/lib/core/endpoints/data_sync/entity/create.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class CreateEntityRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNCreateEntityOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.entity) return 'Entity cannot be empty'; diff --git a/lib/core/endpoints/data_sync/entity/get-all.js b/lib/core/endpoints/data_sync/entity/get-all.js index 8611a3691..2bc93360c 100644 --- a/lib/core/endpoints/data_sync/entity/get-all.js +++ b/lib/core/endpoints/data_sync/entity/get-all.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -36,6 +45,14 @@ class GetAllEntitiesRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllEntitiesOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.entityClass) return 'Entity class cannot be empty'; diff --git a/lib/core/endpoints/data_sync/entity/get.js b/lib/core/endpoints/data_sync/entity/get.js index 89c9fe919..02a7bbf9b 100644 --- a/lib/core/endpoints/data_sync/entity/get.js +++ b/lib/core/endpoints/data_sync/entity/get.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class GetEntityRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetEntityOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Entity id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/entity/patch.js b/lib/core/endpoints/data_sync/entity/patch.js index e26581132..fd9649405 100644 --- a/lib/core/endpoints/data_sync/entity/patch.js +++ b/lib/core/endpoints/data_sync/entity/patch.js @@ -8,6 +8,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -32,6 +41,14 @@ class PatchEntityRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNPatchEntityOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Entity id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/entity/update.js b/lib/core/endpoints/data_sync/entity/update.js index 59a10cbd5..fa1aa0927 100644 --- a/lib/core/endpoints/data_sync/entity/update.js +++ b/lib/core/endpoints/data_sync/entity/update.js @@ -7,6 +7,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -30,6 +39,14 @@ class UpdateEntityRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNUpdateEntityOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Entity id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/membership/create.js b/lib/core/endpoints/data_sync/membership/create.js index 5f0465700..f6e618679 100644 --- a/lib/core/endpoints/data_sync/membership/create.js +++ b/lib/core/endpoints/data_sync/membership/create.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class CreateMembershipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNCreateMembershipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.membership) return 'Membership cannot be empty'; diff --git a/lib/core/endpoints/data_sync/membership/get-all.js b/lib/core/endpoints/data_sync/membership/get-all.js index 24eed2965..04ffa8074 100644 --- a/lib/core/endpoints/data_sync/membership/get-all.js +++ b/lib/core/endpoints/data_sync/membership/get-all.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -36,6 +45,14 @@ class GetAllMembershipsRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllMembershipsOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } get path() { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/memberships`; } diff --git a/lib/core/endpoints/data_sync/membership/get.js b/lib/core/endpoints/data_sync/membership/get.js index 1c813b804..328fc0e9d 100644 --- a/lib/core/endpoints/data_sync/membership/get.js +++ b/lib/core/endpoints/data_sync/membership/get.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class GetMembershipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetMembershipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Membership id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/membership/patch.js b/lib/core/endpoints/data_sync/membership/patch.js index 54e3576d7..4b6f22771 100644 --- a/lib/core/endpoints/data_sync/membership/patch.js +++ b/lib/core/endpoints/data_sync/membership/patch.js @@ -8,6 +8,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -32,6 +41,14 @@ class PatchMembershipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNPatchMembershipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Membership id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/membership/update.js b/lib/core/endpoints/data_sync/membership/update.js index 12d096a57..d88f056c7 100644 --- a/lib/core/endpoints/data_sync/membership/update.js +++ b/lib/core/endpoints/data_sync/membership/update.js @@ -6,6 +6,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -29,6 +38,14 @@ class UpdateMembershipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNUpdateMembershipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Membership id cannot be empty'; @@ -38,6 +55,8 @@ class UpdateMembershipRequest extends request_1.AbstractRequest { return 'User id cannot be empty'; if (!this.parameters.membership.channelId) return 'Channel id cannot be empty'; + if (!this.parameters.membership.relationshipClassVersion) + return 'Relationship class version cannot be empty'; } get headers() { var _a; diff --git a/lib/core/endpoints/data_sync/relationship/create.js b/lib/core/endpoints/data_sync/relationship/create.js index 85e216e2f..0d3706408 100644 --- a/lib/core/endpoints/data_sync/relationship/create.js +++ b/lib/core/endpoints/data_sync/relationship/create.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class CreateRelationshipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNCreateRelationshipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.relationship) return 'Relationship cannot be empty'; diff --git a/lib/core/endpoints/data_sync/relationship/get-all.js b/lib/core/endpoints/data_sync/relationship/get-all.js index 191bd8537..c41b3c5e9 100644 --- a/lib/core/endpoints/data_sync/relationship/get-all.js +++ b/lib/core/endpoints/data_sync/relationship/get-all.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -36,6 +45,14 @@ class GetAllRelationshipsRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllRelationshipsOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.relationshipClass) return 'Relationship class cannot be empty'; diff --git a/lib/core/endpoints/data_sync/relationship/get.js b/lib/core/endpoints/data_sync/relationship/get.js index 88e6fb306..ef244806c 100644 --- a/lib/core/endpoints/data_sync/relationship/get.js +++ b/lib/core/endpoints/data_sync/relationship/get.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class GetRelationshipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetRelationshipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Relationship id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/relationship/patch.js b/lib/core/endpoints/data_sync/relationship/patch.js index c335d955c..3ffab6fb7 100644 --- a/lib/core/endpoints/data_sync/relationship/patch.js +++ b/lib/core/endpoints/data_sync/relationship/patch.js @@ -8,6 +8,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -32,6 +41,14 @@ class PatchRelationshipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNPatchRelationshipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Relationship id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/relationship/update.js b/lib/core/endpoints/data_sync/relationship/update.js index 77e6e1ee0..dda1eb34c 100644 --- a/lib/core/endpoints/data_sync/relationship/update.js +++ b/lib/core/endpoints/data_sync/relationship/update.js @@ -6,6 +6,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -29,6 +38,14 @@ class UpdateRelationshipRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNUpdateRelationshipOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'Relationship id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/user/create.js b/lib/core/endpoints/data_sync/user/create.js index 0d6cca6fa..78cdcb7c8 100644 --- a/lib/core/endpoints/data_sync/user/create.js +++ b/lib/core/endpoints/data_sync/user/create.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class CreateUserRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNCreateUserOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.user) return 'User cannot be empty'; diff --git a/lib/core/endpoints/data_sync/user/get-all.js b/lib/core/endpoints/data_sync/user/get-all.js index ebf470d5e..9ccac8f5d 100644 --- a/lib/core/endpoints/data_sync/user/get-all.js +++ b/lib/core/endpoints/data_sync/user/get-all.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -36,6 +45,14 @@ class GetAllUsersRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetAllUsersOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } get path() { return `/v1/datasync/subkeys/${this.parameters.keySet.subscribeKey}/users`; } diff --git a/lib/core/endpoints/data_sync/user/get.js b/lib/core/endpoints/data_sync/user/get.js index b7037038f..a6cf3a9b6 100644 --- a/lib/core/endpoints/data_sync/user/get.js +++ b/lib/core/endpoints/data_sync/user/get.js @@ -4,6 +4,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -26,6 +35,14 @@ class GetUserRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNGetUserOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'User id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/user/patch.js b/lib/core/endpoints/data_sync/user/patch.js index 360c7fdac..8d230ecc8 100644 --- a/lib/core/endpoints/data_sync/user/patch.js +++ b/lib/core/endpoints/data_sync/user/patch.js @@ -8,6 +8,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -32,6 +41,14 @@ class PatchUserRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNPatchUserOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'User id cannot be empty'; diff --git a/lib/core/endpoints/data_sync/user/update.js b/lib/core/endpoints/data_sync/user/update.js index 8fd35528e..73e58f637 100644 --- a/lib/core/endpoints/data_sync/user/update.js +++ b/lib/core/endpoints/data_sync/user/update.js @@ -6,6 +6,15 @@ * * @internal */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; @@ -29,6 +38,14 @@ class UpdateUserRequest extends request_1.AbstractRequest { operation() { return operations_1.default.PNUpdateUserOperation; } + parse(response) { + return __awaiter(this, void 0, void 0, function* () { + // The DataSync service returns the object envelope ({ data } or { data, meta }) without a + // top-level HTTP status; surface `response.status` so callers can inspect it (parity with remove). + const parsed = this.deserializeResponse(response); + return Object.assign(Object.assign({}, parsed), { status: response.status }); + }); + } validate() { if (!this.parameters.id) return 'User id cannot be empty'; diff --git a/lib/types/index.d.ts b/lib/types/index.d.ts index 711a35094..76e784e4b 100644 --- a/lib/types/index.d.ts +++ b/lib/types/index.d.ts @@ -10826,13 +10826,17 @@ declare namespace PubNub { /** * Membership properties for update (PUT) requests. * - * PUT is a full replacement — `userId` and `channelId` are required. + * PUT is a full replacement — `userId`, `channelId`, and `relationshipClassVersion` are required. + * The server rejects a PUT that omits `relationshipClassVersion` (`SYN-0004: must not be null`), + * mirroring {@link UpdateRelationshipProperties}. */ export type UpdateMembershipProperties = { /** User ID reference. */ userId: string; /** Channel ID reference. */ channelId: string; + /** Version of the Membership relationship class. */ + relationshipClassVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload. */ @@ -10842,18 +10846,16 @@ declare namespace PubNub { /** * Membership resource as returned from the server. * - * Note: server responses are shaped like a relationship — `entityAId` corresponds - * to `channelId` and `entityBId` corresponds to `userId`. */ export type MembershipObject = { /** Unique identifier. */ id: string; - /** Channel ID (server returns this as `entityAId`). */ - entityAId: string; - /** User ID (server returns this as `entityBId`). */ - entityBId: string; + /** Channel ID reference. */ + channelId: string; + /** User ID reference. */ + userId: string; /** Relationship class. */ - relationshipClass: string; + relationshipClass?: string; /** Version of the relationship class schema. */ relationshipClassVersion: number; /** Lifecycle status. */