From 0c83fb4b3de315f048b72c12650069987ede29e0 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:27:49 +0530 Subject: [PATCH 01/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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/20] 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. */ From 2bf1a7536979a36533b6876e6fe2afaf318792b8 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 27 Jul 2026 09:49:18 +0530 Subject: [PATCH 20/20] refactor: dataSync apis signature update to improve user experience by not typinf domain keywords during parameter property inputs, update method name conventions to align with existing methods. update parse token to parse dataSync related permissions and projection definitions details. added more patch operation variants which are supported. --- src/core/components/token_manager.ts | 70 ++- src/core/constants/operations.ts | 20 +- .../endpoints/data_sync/channel/create.ts | 15 +- .../channel/{get-all.ts => fetch-all.ts} | 13 +- .../data_sync/channel/{get.ts => fetch.ts} | 10 +- src/core/endpoints/data_sync/channel/patch.ts | 31 +- .../endpoints/data_sync/channel/update.ts | 14 +- src/core/endpoints/data_sync/entity/create.ts | 18 +- .../entity/{get-all.ts => fetch-all.ts} | 13 +- .../data_sync/entity/{get.ts => fetch.ts} | 10 +- src/core/endpoints/data_sync/entity/patch.ts | 31 +- src/core/endpoints/data_sync/entity/update.ts | 14 +- .../endpoints/data_sync/membership/create.ts | 21 +- .../membership/{get-all.ts => fetch-all.ts} | 13 +- .../data_sync/membership/{get.ts => fetch.ts} | 10 +- .../endpoints/data_sync/membership/patch.ts | 31 +- .../endpoints/data_sync/membership/update.ts | 20 +- .../data_sync/relationship/create.ts | 24 +- .../relationship/{get-all.ts => fetch-all.ts} | 13 +- .../relationship/{get.ts => fetch.ts} | 10 +- .../endpoints/data_sync/relationship/patch.ts | 32 +- .../data_sync/relationship/update.ts | 20 +- src/core/endpoints/data_sync/user/create.ts | 15 +- .../user/{get-all.ts => fetch-all.ts} | 13 +- .../data_sync/user/{get.ts => fetch.ts} | 10 +- src/core/endpoints/data_sync/user/patch.ts | 31 +- src/core/endpoints/data_sync/user/update.ts | 14 +- src/core/pubnub-data-sync.ts | 300 +++++----- src/core/types/api/access-manager.ts | 65 ++- src/core/types/api/data-sync.ts | 536 ++++++++++++------ src/transport/middleware.ts | 11 +- 31 files changed, 941 insertions(+), 507 deletions(-) rename src/core/endpoints/data_sync/channel/{get-all.ts => fetch-all.ts} (84%) rename src/core/endpoints/data_sync/channel/{get.ts => fetch.ts} (84%) rename src/core/endpoints/data_sync/entity/{get-all.ts => fetch-all.ts} (85%) rename src/core/endpoints/data_sync/entity/{get.ts => fetch.ts} (83%) rename src/core/endpoints/data_sync/membership/{get-all.ts => fetch-all.ts} (84%) rename src/core/endpoints/data_sync/membership/{get.ts => fetch.ts} (84%) rename src/core/endpoints/data_sync/relationship/{get-all.ts => fetch-all.ts} (85%) rename src/core/endpoints/data_sync/relationship/{get.ts => fetch.ts} (83%) rename src/core/endpoints/data_sync/user/{get-all.ts => fetch-all.ts} (85%) rename src/core/endpoints/data_sync/user/{get.ts => fetch.ts} (84%) diff --git a/src/core/components/token_manager.ts b/src/core/components/token_manager.ts index d2a734c5f..d3e69eef2 100644 --- a/src/core/components/token_manager.ts +++ b/src/core/components/token_manager.ts @@ -13,6 +13,17 @@ import { Payload } from '../types/api'; // -------------------------------------------------------- // region Types +/** + * DataSync scope wire keys as stored in the token `res` / `pat` sections. + */ +type DataSyncWireKey = 'datasync:entities' | 'datasync:relationships' | 'datasync:memberships'; + +/** + * Raw bit-encoded permissions section (`res` or `pat`) stored in the access token. + */ +type RawTokenPermissions = Record<'chan' | 'grp' | 'uuid', Record> & + Partial>>; + /** * Raw parsed token. * @@ -37,12 +48,12 @@ type RawToken = { /** * Permissions granted to specific resources. */ - res: Record<'chan' | 'grp' | 'uuid', Record>; + res: RawTokenPermissions; /** * Permissions granted to resources which match specified regular expression. */ - pat: Record<'chan' | 'grp' | 'uuid', Record>; + pat: RawTokenPermissions; /** * The uuid that is exclusively authorized to use this token to make API requests. @@ -146,6 +157,9 @@ export class TokenManager { } } + const resourceDataSync = this.extractDataSyncScopes(parsed.res); + if (resourceDataSync) (result.resources ??= {}).dataSync = resourceDataSync; + const uuidPatterns = uuidPatternPermissions.length > 0; const channelPatterns = channelPatternPermissions.length > 0; const groupPatterns = groupPatternPermissions.length > 0; @@ -169,6 +183,9 @@ export class TokenManager { } } + const patternDataSync = this.extractDataSyncScopes(parsed.pat); + if (patternDataSync) (result.patterns ??= {}).dataSync = patternDataSync; + if (parsed.meta && Object.keys(parsed.meta).length > 0) result.meta = parsed.meta; return result; @@ -205,4 +222,53 @@ export class TokenManager { return permissionsResult; } + + /** + * Extract DataSync permission scopes from a token permissions section. + * + * The `datasync:*` wire keys are only present for tokens which granted DataSync permissions, so a + * result is returned only when at least one scope carries permissions. + * + * @param section - Raw `res` or `pat` permissions section decoded from the token. + * + * @returns Human-readable DataSync permission scopes, or `undefined` when none are granted. + */ + private extractDataSyncScopes(section: RawTokenPermissions): PAM.DataSyncScopePermissions | undefined { + const dataSyncScopes: [keyof PAM.DataSyncScopePermissions, DataSyncWireKey][] = [ + ['entities', 'datasync:entities'], + ['relationships', 'datasync:relationships'], + ['memberships', 'datasync:memberships'], + ]; + + let result: PAM.DataSyncScopePermissions | undefined; + + dataSyncScopes.forEach(([scope, wireKey]) => { + const permissions = section[wireKey]; + if (!permissions) return; + + const ids = Object.keys(permissions); + if (ids.length === 0) return; + + const scopeResult: Record = ((result ??= {})[scope] = {}); + ids.forEach((id) => (scopeResult[id] = this.extractDataSyncPermissions(permissions[id]))); + }); + + return result; + } + + /** + * Extract DataSync resource access permission information. + * + * @param permissions - Bit-encoded resource permissions. + * + * @returns Human-readable DataSync resource permissions. + */ + private extractDataSyncPermissions(permissions: number): PAM.DataSyncPermissions { + return { + create: (permissions & 16) === 16, + get: (permissions & 32) === 32, + update: (permissions & 64) === 64, + delete: (permissions & 8) === 8, + }; + } } diff --git a/src/core/constants/operations.ts b/src/core/constants/operations.ts index 2487172ee..5e83bd191 100644 --- a/src/core/constants/operations.ts +++ b/src/core/constants/operations.ts @@ -187,12 +187,12 @@ enum RequestOperation { /** * Get entity REST API operation. */ - PNGetEntityOperation = 'PNGetEntityOperation', + PNFetchEntityOperation = 'PNFetchEntityOperation', /** * Get all entities REST API operation. */ - PNGetAllEntitiesOperation = 'PNGetAllEntitiesOperation', + PNFetchEntitiesOperation = 'PNFetchEntitiesOperation', /** * Update entity REST API operation. @@ -217,12 +217,12 @@ enum RequestOperation { /** * Get relationship REST API operation. */ - PNGetRelationshipOperation = 'PNGetRelationshipOperation', + PNFetchRelationshipOperation = 'PNFetchRelationshipOperation', /** * Get all relationships REST API operation. */ - PNGetAllRelationshipsOperation = 'PNGetAllRelationshipsOperation', + PNFetchRelationshipsOperation = 'PNFetchRelationshipsOperation', /** * Update relationship REST API operation. @@ -247,12 +247,12 @@ enum RequestOperation { /** * Get user REST API operation. */ - PNGetUserOperation = 'PNGetUserOperation', + PNFetchUserOperation = 'PNFetchUserOperation', /** * Get all users REST API operation. */ - PNGetAllUsersOperation = 'PNGetAllUsersOperation', + PNFetchUsersOperation = 'PNFetchUsersOperation', /** * Update user REST API operation. @@ -277,12 +277,12 @@ enum RequestOperation { /** * Get channel REST API operation. */ - PNGetChannelOperation = 'PNGetChannelOperation', + PNFetchChannelOperation = 'PNFetchChannelOperation', /** * Get all channels REST API operation. */ - PNGetAllChannelsOperation = 'PNGetAllChannelsOperation', + PNFetchChannelsOperation = 'PNFetchChannelsOperation', /** * Update channel REST API operation. @@ -307,12 +307,12 @@ enum RequestOperation { /** * Get membership REST API operation. */ - PNGetMembershipOperation = 'PNGetMembershipOperation', + PNFetchMembershipOperation = 'PNFetchMembershipOperation', /** * Get all memberships REST API operation. */ - PNGetAllMembershipsOperation = 'PNGetAllMembershipsOperation', + PNFetchMembershipsOperation = 'PNFetchMembershipsOperation', /** * Update membership REST API operation. diff --git a/src/core/endpoints/data_sync/channel/create.ts b/src/core/endpoints/data_sync/channel/create.ts index a50c9fe31..444cd394e 100644 --- a/src/core/endpoints/data_sync/channel/create.ts +++ b/src/core/endpoints/data_sync/channel/create.ts @@ -52,8 +52,8 @@ export class CreateChannelRequest extends AbstractRequest< +export class FetchChannelsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class GetAllChannelsRequest { @@ -70,13 +70,14 @@ export class GetAllChannelsRequest extends AbstractRequest< +export class FetchChannelRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class GetChannelRequest ext } operation(): RequestOperation { - return RequestOperation.PNGetChannelOperation; + return RequestOperation.PNFetchChannelOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/channel/patch.ts b/src/core/endpoints/data_sync/channel/patch.ts index 4e5d31f49..aec5f44d8 100644 --- a/src/core/endpoints/data_sync/channel/patch.ts +++ b/src/core/endpoints/data_sync/channel/patch.ts @@ -2,8 +2,9 @@ * 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. + * Accepts `add`/`replace`/`test` (dot-notation key-value pairs), `remove` + * (dot-notation paths), and `move`/`copy` (dot-notation from → path pairs), + * converting them to JSON Patch operations on the wire. * * @internal */ @@ -60,10 +61,15 @@ export class PatchChannelRequest 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'; + const { add, replace, remove, move, copy, test } = this.parameters; + const hasAdd = add && Object.keys(add).length > 0; + const hasReplace = replace && Object.keys(replace).length > 0; + const hasRemove = remove && remove.length > 0; + const hasMove = move && move.length > 0; + const hasCopy = copy && copy.length > 0; + const hasTest = test && Object.keys(test).length > 0; + if (!hasAdd && !hasReplace && !hasRemove && !hasMove && !hasCopy && !hasTest) + return 'At least one of add, replace, remove, move, copy, or test must be provided'; } protected get headers(): Record | undefined { @@ -87,17 +93,10 @@ export class PatchChannelRequest } 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 { add, replace, remove, move, copy, test } = this.parameters; - 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); + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); return JSON.stringify(jsonPatchOps); } } diff --git a/src/core/endpoints/data_sync/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts index c4aef3c77..af5d9fee0 100644 --- a/src/core/endpoints/data_sync/channel/update.ts +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -56,8 +56,8 @@ export class UpdateChannelRequest } 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) + if (!this.parameters.class) return 'Entity class cannot be empty'; + if (!this.parameters.data) return 'Entity data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } @@ -76,6 +76,16 @@ export class CreateEntityRequest } protected get body(): ArrayBuffer | string | undefined { - return JSON.stringify({ data: this.parameters.entity }); + const { id, class: entityClass, data } = this.parameters; + + return JSON.stringify({ + data: { + ...(id !== undefined ? { id } : {}), + entityClass, + entityClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/endpoints/data_sync/entity/get-all.ts b/src/core/endpoints/data_sync/entity/fetch-all.ts similarity index 85% rename from src/core/endpoints/data_sync/entity/get-all.ts rename to src/core/endpoints/data_sync/entity/fetch-all.ts index 93d287613..fe738a30d 100644 --- a/src/core/endpoints/data_sync/entity/get-all.ts +++ b/src/core/endpoints/data_sync/entity/fetch-all.ts @@ -1,5 +1,5 @@ /** - * Get All Entities REST API module. + * Fetch Entities REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.GetAllEntitiesParameters & { +type RequestParameters = DataSync.FetchEntitiesParameters & { /** * PubNub REST API access key set. */ @@ -38,11 +38,11 @@ type RequestParameters = DataSync.GetAllEntitiesParameters & { // endregion /** - * Get All Entities request. + * Fetch Entities request. * * @internal */ -export class GetAllEntitiesRequest extends AbstractRequest< +export class FetchEntitiesRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class GetAllEntitiesRequest { @@ -74,6 +74,7 @@ export class GetAllEntitiesRequest extends AbstractRequest { +export class FetchEntityRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } operation(): RequestOperation { - return RequestOperation.PNGetEntityOperation; + return RequestOperation.PNFetchEntityOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/patch.ts index 0a7f4a6d5..2ea639467 100644 --- a/src/core/endpoints/data_sync/entity/patch.ts +++ b/src/core/endpoints/data_sync/entity/patch.ts @@ -2,8 +2,9 @@ * 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. + * Accepts `add`/`replace`/`test` (dot-notation key-value pairs), `remove` + * (dot-notation paths), and `move`/`copy` (dot-notation from/path pairs), and + * converts them to JSON Patch operations on the wire. * * @internal */ @@ -60,10 +61,15 @@ export class PatchEntityRequest e 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'; + const { add, replace, remove, move, copy, test } = this.parameters; + const hasAdd = add && Object.keys(add).length > 0; + const hasReplace = replace && Object.keys(replace).length > 0; + const hasRemove = remove && remove.length > 0; + const hasMove = move && move.length > 0; + const hasCopy = copy && copy.length > 0; + const hasTest = test && Object.keys(test).length > 0; + if (!hasAdd && !hasReplace && !hasRemove && !hasMove && !hasCopy && !hasTest) + return 'At least one of add, replace, remove, move, copy, or test must be provided'; } protected get headers(): Record | undefined { @@ -87,17 +93,10 @@ export class PatchEntityRequest e } 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 { add, replace, remove, move, copy, test } = this.parameters; - 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); + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); return JSON.stringify(jsonPatchOps); } } diff --git a/src/core/endpoints/data_sync/entity/update.ts b/src/core/endpoints/data_sync/entity/update.ts index 1b957f40d..60084eb14 100644 --- a/src/core/endpoints/data_sync/entity/update.ts +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -57,8 +57,8 @@ export class UpdateEntityRequest 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) + if (!this.parameters.data) return 'Entity data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } @@ -83,6 +83,14 @@ export class UpdateEntityRequest } protected get body(): ArrayBuffer | string | undefined { - return JSON.stringify({ data: this.parameters.entity }); + const { data } = this.parameters; + + return JSON.stringify({ + data: { + entityClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/endpoints/data_sync/membership/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 00ecffea4..82fef21e0 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -52,10 +52,10 @@ export class CreateMembershipRequest | undefined { @@ -76,6 +76,17 @@ export class CreateMembershipRequest extends AbstractRequest< +export class FetchMembershipsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class GetAllMembershipsRequest { @@ -71,6 +71,7 @@ export class GetAllMembershipsRequest extends AbstractRequest< +export class FetchMembershipRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class GetMembershipRequest { diff --git a/src/core/endpoints/data_sync/membership/patch.ts b/src/core/endpoints/data_sync/membership/patch.ts index 05f4f41bd..44bf67b37 100644 --- a/src/core/endpoints/data_sync/membership/patch.ts +++ b/src/core/endpoints/data_sync/membership/patch.ts @@ -2,8 +2,9 @@ * 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. + * Accepts `add`/`replace`/`test` (dot-notation key-value pairs), `remove` + * (dot-notation paths), and `move`/`copy` (dot-notation `{ from, path }` pairs) + * and converts them to JSON Patch operations on the wire. * * @internal */ @@ -60,10 +61,15 @@ export class PatchMembershipRequest 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'; + const { add, replace, remove, move, copy, test } = this.parameters; + const hasAdd = add && Object.keys(add).length > 0; + const hasReplace = replace && Object.keys(replace).length > 0; + const hasRemove = remove && remove.length > 0; + const hasMove = move && move.length > 0; + const hasCopy = copy && copy.length > 0; + const hasTest = test && Object.keys(test).length > 0; + if (!hasAdd && !hasReplace && !hasRemove && !hasMove && !hasCopy && !hasTest) + return 'At least one of add, replace, remove, move, copy, or test must be provided'; } protected get headers(): Record | undefined { @@ -87,17 +93,10 @@ export class PatchMembershipRequest' on the wire. - const prefixWithPayload = (input: Record) => - Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const { add, replace, remove, move, copy, test } = this.parameters; - 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); + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); return JSON.stringify(jsonPatchOps); } } diff --git a/src/core/endpoints/data_sync/membership/update.ts b/src/core/endpoints/data_sync/membership/update.ts index eb0aeb62c..547dccc00 100644 --- a/src/core/endpoints/data_sync/membership/update.ts +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -56,10 +56,10 @@ export class UpdateMembershipRequest | undefined { @@ -83,6 +83,16 @@ export class UpdateMembershipRequest | undefined { @@ -77,6 +77,18 @@ export class CreateRelationshipRequest extends AbstractRequest< +export class FetchRelationshipsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class GetAllRelationshipsRequest { @@ -84,6 +84,7 @@ export class GetAllRelationshipsRequest extends AbstractRequest< +export class FetchRelationshipRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class GetRelationshipRequest { diff --git a/src/core/endpoints/data_sync/relationship/patch.ts b/src/core/endpoints/data_sync/relationship/patch.ts index 6e14be759..1c8782c44 100644 --- a/src/core/endpoints/data_sync/relationship/patch.ts +++ b/src/core/endpoints/data_sync/relationship/patch.ts @@ -2,8 +2,10 @@ * 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. + * Accepts `add` and `replace` (dot-notation key-value pairs), `remove` + * (dot-notation paths), `move` and `copy` (`{ from, path }` dot-notation pairs), + * and `test` (dot-notation key-value pairs) and converts them to JSON Patch + * operations on the wire. * * @internal */ @@ -60,10 +62,15 @@ export class PatchRelationshipRequest 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'; + const { add, replace, remove, move, copy, test } = this.parameters; + const hasAdd = add && Object.keys(add).length > 0; + const hasReplace = replace && Object.keys(replace).length > 0; + const hasRemove = remove && remove.length > 0; + const hasMove = move && move.length > 0; + const hasCopy = copy && copy.length > 0; + const hasTest = test && Object.keys(test).length > 0; + if (!hasAdd && !hasReplace && !hasRemove && !hasMove && !hasCopy && !hasTest) + return 'At least one of add, replace, remove, move, copy, or test must be provided'; } protected get headers(): Record | undefined { @@ -87,17 +94,10 @@ export class PatchRelationshipRequest) => - Object.fromEntries(Object.entries(input).map(([key, value]) => [`payload.${key}`, value])); + const { add, replace, remove, move, copy, test } = this.parameters; - 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); + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); return JSON.stringify(jsonPatchOps); } } diff --git a/src/core/endpoints/data_sync/relationship/update.ts b/src/core/endpoints/data_sync/relationship/update.ts index 46efeef4d..a0cf13585 100644 --- a/src/core/endpoints/data_sync/relationship/update.ts +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -56,10 +56,10 @@ export class UpdateRelationshipRequest | undefined { @@ -83,6 +83,16 @@ export class UpdateRelationshipRequest ext } validate(): string | undefined { - if (!this.parameters.user) return 'User cannot be empty'; - if (this.parameters.user.entityClassVersion === undefined || this.parameters.user.entityClassVersion === null) + if (!this.parameters.data) return 'User data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } @@ -75,6 +75,15 @@ export class CreateUserRequest ext } protected get body(): ArrayBuffer | string | undefined { - return JSON.stringify({ data: this.parameters.user }); + const { id, data } = this.parameters; + + return JSON.stringify({ + data: { + ...(id !== undefined ? { id } : {}), + entityClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/endpoints/data_sync/user/get-all.ts b/src/core/endpoints/data_sync/user/fetch-all.ts similarity index 85% rename from src/core/endpoints/data_sync/user/get-all.ts rename to src/core/endpoints/data_sync/user/fetch-all.ts index 6a889f381..133a46f46 100644 --- a/src/core/endpoints/data_sync/user/get-all.ts +++ b/src/core/endpoints/data_sync/user/fetch-all.ts @@ -1,5 +1,5 @@ /** - * Get All Users REST API module. + * Fetch Users REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.GetAllUsersParameters & { +type RequestParameters = DataSync.FetchUsersParameters & { /** * PubNub REST API access key set. */ @@ -38,11 +38,11 @@ type RequestParameters = DataSync.GetAllUsersParameters & { // endregion /** - * Get All Users request. + * Fetch Users request. * * @internal */ -export class GetAllUsersRequest extends AbstractRequest< +export class FetchUsersRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class GetAllUsersRequest e } operation(): RequestOperation { - return RequestOperation.PNGetAllUsersOperation; + return RequestOperation.PNFetchUsersOperation; } async parse(response: TransportResponse): Promise { @@ -70,13 +70,14 @@ export class GetAllUsersRequest e protected get queryParameters(): Query { const { entityClassVersion, cursor, limit, filter, sort, filterAdvanced } = this.parameters; + const sorting = DataSync.serializeDataSyncSort(sort); return { ...(entityClassVersion !== undefined ? { entity_class_version: `${entityClassVersion}` } : {}), ...(cursor ? { cursor } : {}), ...(limit ? { limit: `${limit}` } : {}), ...(filter ? { filter } : {}), - ...(sort ? { sort } : {}), + ...(sorting.length ? { sort: sorting } : {}), ...(filterAdvanced ? { filter_advanced: filterAdvanced } : {}), }; } diff --git a/src/core/endpoints/data_sync/user/get.ts b/src/core/endpoints/data_sync/user/fetch.ts similarity index 84% rename from src/core/endpoints/data_sync/user/get.ts rename to src/core/endpoints/data_sync/user/fetch.ts index 61f3438e9..f6df1654c 100644 --- a/src/core/endpoints/data_sync/user/get.ts +++ b/src/core/endpoints/data_sync/user/fetch.ts @@ -1,5 +1,5 @@ /** - * Get User REST API module. + * Fetch User REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.GetUserParameters & { +type RequestParameters = DataSync.FetchUserParameters & { /** * PubNub REST API access key set. */ @@ -28,17 +28,17 @@ type RequestParameters = DataSync.GetUserParameters & { // endregion /** - * Get User request. + * Fetch User request. * * @internal */ -export class GetUserRequest extends AbstractRequest { +export class FetchUserRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } operation(): RequestOperation { - return RequestOperation.PNGetUserOperation; + return RequestOperation.PNFetchUserOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/patch.ts index c04a92688..73b2754a9 100644 --- a/src/core/endpoints/data_sync/user/patch.ts +++ b/src/core/endpoints/data_sync/user/patch.ts @@ -2,8 +2,9 @@ * 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. + * Accepts `add`/`replace`/`test` (dot-notation key-value pairs), `remove` + * (dot-notation paths), and `move`/`copy` (dot-notation `{ from, path }` pairs) + * and converts them to JSON Patch operations on the wire. * * @internal */ @@ -57,10 +58,15 @@ export class PatchUserRequest exten 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'; + const { add, replace, remove, move, copy, test } = this.parameters; + const hasAdd = add && Object.keys(add).length > 0; + const hasReplace = replace && Object.keys(replace).length > 0; + const hasRemove = remove && remove.length > 0; + const hasMove = move && move.length > 0; + const hasCopy = copy && copy.length > 0; + const hasTest = test && Object.keys(test).length > 0; + if (!hasAdd && !hasReplace && !hasRemove && !hasMove && !hasCopy && !hasTest) + return 'At least one of add, replace, remove, move, copy, or test must be provided'; } protected get headers(): Record | undefined { @@ -84,17 +90,10 @@ export class PatchUserRequest exten } 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 { add, replace, remove, move, copy, test } = this.parameters; - 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); + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); return JSON.stringify(jsonPatchOps); } } diff --git a/src/core/endpoints/data_sync/user/update.ts b/src/core/endpoints/data_sync/user/update.ts index acd641c16..7f0c2e103 100644 --- a/src/core/endpoints/data_sync/user/update.ts +++ b/src/core/endpoints/data_sync/user/update.ts @@ -56,8 +56,8 @@ export class UpdateUserRequest ext 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) + if (!this.parameters.data) return 'User data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } @@ -82,6 +82,14 @@ export class UpdateUserRequest ext } protected get body(): ArrayBuffer | string | undefined { - return JSON.stringify({ data: this.parameters.user }); + const { data } = this.parameters; + + return JSON.stringify({ + data: { + entityClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index 531e30a96..47f2e943c 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -3,35 +3,35 @@ */ import { CreateUserRequest } from './endpoints/data_sync/user/create'; -import { GetAllUsersRequest } from './endpoints/data_sync/user/get-all'; +import { FetchUsersRequest } from './endpoints/data_sync/user/fetch-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 { FetchUserRequest } from './endpoints/data_sync/user/fetch'; import { CreateChannelRequest } from './endpoints/data_sync/channel/create'; -import { GetAllChannelsRequest } from './endpoints/data_sync/channel/get-all'; +import { FetchChannelsRequest } from './endpoints/data_sync/channel/fetch-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 { FetchChannelRequest } from './endpoints/data_sync/channel/fetch'; import { CreateMembershipRequest } from './endpoints/data_sync/membership/create'; -import { GetAllMembershipsRequest } from './endpoints/data_sync/membership/get-all'; +import { FetchMembershipsRequest } from './endpoints/data_sync/membership/fetch-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 { FetchMembershipRequest } from './endpoints/data_sync/membership/fetch'; import { CreateRelationshipRequest } from './endpoints/data_sync/relationship/create'; -import { GetAllRelationshipsRequest } from './endpoints/data_sync/relationship/get-all'; +import { FetchRelationshipsRequest } from './endpoints/data_sync/relationship/fetch-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 { FetchRelationshipRequest } from './endpoints/data_sync/relationship/fetch'; import { CreateEntityRequest } from './endpoints/data_sync/entity/create'; -import { GetAllEntitiesRequest } from './endpoints/data_sync/entity/get-all'; +import { FetchEntitiesRequest } from './endpoints/data_sync/entity/fetch-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 { FetchEntityRequest } from './endpoints/data_sync/entity/fetch'; import { KeySet, ResultCallback, SendRequestFunction } from './types/api'; import { PrivateClientConfiguration } from './interfaces/configuration'; import * as DataSync from './types/api/data-sync'; @@ -144,7 +144,7 @@ export default class PubNubDataSync { } // endregion - // region Get Entity + // region Fetch Entity /** * Fetch a specific Entity. @@ -152,9 +152,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getEntity( - parameters: DataSync.GetEntityParameters, - callback: ResultCallback, + public fetchEntity( + parameters: DataSync.FetchEntityParameters, + callback: ResultCallback, ): void; /** @@ -162,9 +162,9 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get entity response. + * @returns Asynchronous fetch entity response. */ - public async getEntity(parameters: DataSync.GetEntityParameters): Promise; + public async fetchEntity(parameters: DataSync.FetchEntityParameters): Promise; /** * Fetch a specific Entity. @@ -172,26 +172,26 @@ export default class PubNubDataSync { * @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 fetch entity response or `void` in case if `callback` provided. */ - async getEntity( - parameters: DataSync.GetEntityParameters, - callback?: ResultCallback, - ): Promise { + async fetchEntity( + parameters: DataSync.FetchEntityParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get Entity with parameters:', + details: 'Fetch Entity with parameters:', })); - const request = new GetEntityRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchEntityRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Get All Entities + // region Fetch Entities /** * Fetch a paginated list of Entities for a given Entity Class. @@ -199,9 +199,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getAllEntities( - parameters: DataSync.GetAllEntitiesParameters, - callback: ResultCallback, + public fetchEntities( + parameters: DataSync.FetchEntitiesParameters, + callback: ResultCallback, ): void; /** @@ -209,9 +209,9 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get all entities response. + * @returns Asynchronous fetch entities response. */ - public async getAllEntities(parameters: DataSync.GetAllEntitiesParameters): Promise; + public async fetchEntities(parameters: DataSync.FetchEntitiesParameters): Promise; /** * Fetch a paginated list of Entities for a given Entity Class. @@ -219,19 +219,19 @@ export default class PubNubDataSync { * @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 fetch entities response or `void` in case if `callback` provided. */ - async getAllEntities( - parameters: DataSync.GetAllEntitiesParameters, - callback?: ResultCallback, - ): Promise { + async fetchEntities( + parameters: DataSync.FetchEntitiesParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get all Entities with parameters:', + details: 'Fetch Entities with parameters:', })); - const request = new GetAllEntitiesRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchEntitiesRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -441,7 +441,7 @@ export default class PubNubDataSync { } // endregion - // region Get Relationship + // region Fetch Relationship /** * Fetch a specific Relationship. @@ -449,9 +449,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getRelationship( - parameters: DataSync.GetRelationshipParameters, - callback: ResultCallback, + public fetchRelationship( + parameters: DataSync.FetchRelationshipParameters, + callback: ResultCallback, ): void; /** @@ -459,11 +459,11 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get relationship response. + * @returns Asynchronous fetch relationship response. */ - public async getRelationship( - parameters: DataSync.GetRelationshipParameters, - ): Promise; + public async fetchRelationship( + parameters: DataSync.FetchRelationshipParameters, + ): Promise; /** * Fetch a specific Relationship. @@ -471,26 +471,26 @@ export default class PubNubDataSync { * @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 fetch relationship response or `void` in case if `callback` provided. */ - async getRelationship( - parameters: DataSync.GetRelationshipParameters, - callback?: ResultCallback, - ): Promise { + async fetchRelationship( + parameters: DataSync.FetchRelationshipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get Relationship with parameters:', + details: 'Fetch Relationship with parameters:', })); - const request = new GetRelationshipRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchRelationshipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Get All Relationships + // region Fetch Relationships /** * Fetch a paginated list of Relationships. @@ -498,9 +498,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getAllRelationships( - parameters: DataSync.GetAllRelationshipsParameters, - callback: ResultCallback, + public fetchRelationships( + parameters: DataSync.FetchRelationshipsParameters, + callback: ResultCallback, ): void; /** @@ -508,11 +508,11 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get all relationships response. + * @returns Asynchronous fetch relationships response. */ - public async getAllRelationships( - parameters: DataSync.GetAllRelationshipsParameters, - ): Promise; + public async fetchRelationships( + parameters: DataSync.FetchRelationshipsParameters, + ): Promise; /** * Fetch a paginated list of Relationships. @@ -520,19 +520,19 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get all relationships response or `void` in case if `callback` provided. + * @returns Asynchronous fetch relationships response or `void` in case if `callback` provided. */ - async getAllRelationships( - parameters: DataSync.GetAllRelationshipsParameters, - callback?: ResultCallback, - ): Promise { + async fetchRelationships( + parameters: DataSync.FetchRelationshipsParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get all Relationships with parameters:', + details: 'Fetch Relationships with parameters:', })); - const request = new GetAllRelationshipsRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchRelationshipsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -746,7 +746,7 @@ export default class PubNubDataSync { } // endregion - // region Get User + // region Fetch User /** * Fetch a specific User. @@ -754,16 +754,16 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getUser(parameters: DataSync.GetUserParameters, callback: ResultCallback): void; + public fetchUser(parameters: DataSync.FetchUserParameters, callback: ResultCallback): void; /** * Fetch a specific User. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get user response. + * @returns Asynchronous fetch user response. */ - public async getUser(parameters: DataSync.GetUserParameters): Promise; + public async fetchUser(parameters: DataSync.FetchUserParameters): Promise; /** * Fetch a specific User. @@ -771,33 +771,33 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get user response or `void` in case if `callback` provided. + * @returns Asynchronous fetch user response or `void` in case if `callback` provided. */ - async getUser( - parameters: DataSync.GetUserParameters, - callback?: ResultCallback, - ): Promise { + async fetchUser( + parameters: DataSync.FetchUserParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get User with parameters:', + details: 'Fetch User with parameters:', })); - const request = new GetUserRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchUserRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Get All Users + // region Fetch Users /** * Fetch a paginated list of Users. * * @param callback - Request completion handler callback. */ - public getAllUsers(callback: ResultCallback): void; + public fetchUsers(callback: ResultCallback): void; /** * Fetch a paginated list of Users. @@ -805,9 +805,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getAllUsers( - parameters: DataSync.GetAllUsersParameters, - callback: ResultCallback, + public fetchUsers( + parameters: DataSync.FetchUsersParameters, + callback: ResultCallback, ): void; /** @@ -815,9 +815,9 @@ export default class PubNubDataSync { * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all users response. + * @returns Asynchronous fetch users response. */ - public async getAllUsers(parameters?: DataSync.GetAllUsersParameters): Promise; + public async fetchUsers(parameters?: DataSync.FetchUsersParameters): Promise; /** * Fetch a paginated list of Users. @@ -825,23 +825,23 @@ export default class PubNubDataSync { * @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. + * @returns Asynchronous fetch users response or `void` in case if `callback` provided. */ - async getAllUsers( - parametersOrCallback?: DataSync.GetAllUsersParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.GetAllUsersParameters = + async fetchUsers( + parametersOrCallback?: DataSync.FetchUsersParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.FetchUsersParameters = 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:', + details: 'Fetch Users with parameters:', })); - const request = new GetAllUsersRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchUsersRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -1049,7 +1049,7 @@ export default class PubNubDataSync { } // endregion - // region Get Channel + // region Fetch Channel /** * Fetch a specific Channel. @@ -1057,9 +1057,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getChannel( - parameters: DataSync.GetChannelParameters, - callback: ResultCallback, + public fetchChannel( + parameters: DataSync.FetchChannelParameters, + callback: ResultCallback, ): void; /** @@ -1067,9 +1067,9 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get channel response. + * @returns Asynchronous fetch channel response. */ - public async getChannel(parameters: DataSync.GetChannelParameters): Promise; + public async fetchChannel(parameters: DataSync.FetchChannelParameters): Promise; /** * Fetch a specific Channel. @@ -1077,33 +1077,33 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get channel response or `void` in case if `callback` provided. + * @returns Asynchronous fetch channel response or `void` in case if `callback` provided. */ - async getChannel( - parameters: DataSync.GetChannelParameters, - callback?: ResultCallback, - ): Promise { + async fetchChannel( + parameters: DataSync.FetchChannelParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get Channel with parameters:', + details: 'Fetch Channel with parameters:', })); - const request = new GetChannelRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchChannelRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Get All Channels + // region Fetch Channels /** * Fetch a paginated list of Channels. * * @param callback - Request completion handler callback. */ - public getAllChannels(callback: ResultCallback): void; + public fetchChannels(callback: ResultCallback): void; /** * Fetch a paginated list of Channels. @@ -1111,9 +1111,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getAllChannels( - parameters: DataSync.GetAllChannelsParameters, - callback: ResultCallback, + public fetchChannels( + parameters: DataSync.FetchChannelsParameters, + callback: ResultCallback, ): void; /** @@ -1121,9 +1121,9 @@ export default class PubNubDataSync { * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all channels response. + * @returns Asynchronous fetch channels response. */ - public async getAllChannels(parameters?: DataSync.GetAllChannelsParameters): Promise; + public async fetchChannels(parameters?: DataSync.FetchChannelsParameters): Promise; /** * Fetch a paginated list of Channels. @@ -1131,23 +1131,23 @@ export default class PubNubDataSync { * @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. + * @returns Asynchronous fetch channels response or `void` in case if `callback` provided. */ - async getAllChannels( - parametersOrCallback?: DataSync.GetAllChannelsParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.GetAllChannelsParameters = + async fetchChannels( + parametersOrCallback?: DataSync.FetchChannelsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.FetchChannelsParameters = 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:', + details: 'Fetch Channels with parameters:', })); - const request = new GetAllChannelsRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchChannelsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -1357,7 +1357,7 @@ export default class PubNubDataSync { } // endregion - // region Get Membership + // region Fetch Membership /** * Fetch a specific Membership. @@ -1365,9 +1365,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getMembership( - parameters: DataSync.GetMembershipParameters, - callback: ResultCallback, + public fetchMembership( + parameters: DataSync.FetchMembershipParameters, + callback: ResultCallback, ): void; /** @@ -1375,9 +1375,9 @@ export default class PubNubDataSync { * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get membership response. + * @returns Asynchronous fetch membership response. */ - public async getMembership(parameters: DataSync.GetMembershipParameters): Promise; + public async fetchMembership(parameters: DataSync.FetchMembershipParameters): Promise; /** * Fetch a specific Membership. @@ -1385,33 +1385,33 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous get membership response or `void` in case if `callback` provided. + * @returns Asynchronous fetch membership response or `void` in case if `callback` provided. */ - async getMembership( - parameters: DataSync.GetMembershipParameters, - callback?: ResultCallback, - ): Promise { + async fetchMembership( + parameters: DataSync.FetchMembershipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Get Membership with parameters:', + details: 'Fetch Membership with parameters:', })); - const request = new GetMembershipRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchMembershipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Get All Memberships + // region Fetch Memberships /** * Fetch a paginated list of Memberships. * * @param callback - Request completion handler callback. */ - public getAllMemberships(callback: ResultCallback): void; + public fetchMemberships(callback: ResultCallback): void; /** * Fetch a paginated list of Memberships. @@ -1419,9 +1419,9 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public getAllMemberships( - parameters: DataSync.GetAllMembershipsParameters, - callback: ResultCallback, + public fetchMemberships( + parameters: DataSync.FetchMembershipsParameters, + callback: ResultCallback, ): void; /** @@ -1429,11 +1429,11 @@ export default class PubNubDataSync { * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all memberships response. + * @returns Asynchronous fetch memberships response. */ - public async getAllMemberships( - parameters?: DataSync.GetAllMembershipsParameters, - ): Promise; + public async fetchMemberships( + parameters?: DataSync.FetchMembershipsParameters, + ): Promise; /** * Fetch a paginated list of Memberships. @@ -1441,23 +1441,23 @@ export default class PubNubDataSync { * @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. + * @returns Asynchronous fetch memberships response or `void` in case if `callback` provided. */ - async getAllMemberships( - parametersOrCallback?: DataSync.GetAllMembershipsParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.GetAllMembershipsParameters = + async fetchMemberships( + parametersOrCallback?: DataSync.FetchMembershipsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.FetchMembershipsParameters = 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:', + details: 'Fetch Memberships with parameters:', })); - const request = new GetAllMembershipsRequest({ ...parameters, keySet: this.keySet }); + const request = new FetchMembershipsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); diff --git a/src/core/types/api/access-manager.ts b/src/core/types/api/access-manager.ts index 9559850dd..d931e47da 100644 --- a/src/core/types/api/access-manager.ts +++ b/src/core/types/api/access-manager.ts @@ -383,12 +383,22 @@ export type Token = { /** * Permissions granted to specific resources. */ - resources?: Partial>>; + resources?: Partial>> & { + /** + * DataSync entity-level permissions granted to specific resources. + */ + dataSync?: DataSyncScopePermissions; + }; /** * Permissions granted to resources which match specified regular expression. */ - patterns?: Partial>>; + patterns?: Partial>> & { + /** + * DataSync entity-level permissions granted to resources which match specified regular expression. + */ + dataSync?: DataSyncScopePermissions; + }; /** * The uuid that is exclusively authorized to use this token to make API requests. @@ -494,6 +504,57 @@ export type Permissions = { join: boolean; }; +/** + * Granted DataSync entity-level permissions. + * + * Applies to parsed DataSync entities, relationships, and memberships. Only the CRUD-relevant + * operations are exposed. + */ +export type DataSyncPermissions = { + /** + * Resource `create` permission. + */ + create: boolean; + + /** + * Resource `get` permission. + */ + get: boolean; + + /** + * Resource `update` permission. + */ + update: boolean; + + /** + * Resource `delete` permission. + */ + delete: boolean; +}; + +/** + * Parsed DataSync permission scopes. + * + * Decoded from the token `res` / `pat` wire keys `datasync:entities` / `datasync:relationships` / + * `datasync:memberships`. + */ +export type DataSyncScopePermissions = { + /** + * DataSync `entity` permissions keyed by concrete entity id or RegEx pattern. + */ + entities?: Record; + + /** + * DataSync `relationship` permissions keyed by composite relationship id or RegEx pattern. + */ + relationships?: Record; + + /** + * DataSync `membership` permissions keyed by composite membership id or RegEx pattern. + */ + memberships?: Record; +}; + // endregion // -------------------------------------------------------- diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index ff2aa9846..907969607 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -89,12 +89,38 @@ type PagedRequestParameters = { filter?: string; /** - * Sort expression. Comma-separated fields, optionally prefixed with + (asc) or - (desc). - * Example: "+name,-createdAt" + * Sort expression. + * + * Either a raw string (comma-separated fields, optionally prefixed with + (asc) or - (desc), + * e.g. `"+name,-createdAt"`), or a map of field → direction that is serialized to the + * `field:order` form the service expects (e.g. `{ firstName: 'desc' }` → `firstName:desc`). + * Specify `null` as the direction for the service default (ascending). */ - sort?: string; + sort?: DataSyncSort; }; +/** + * Sorting options for paginated DataSync list requests. + * + * Prefer the object form (`{ firstName: 'desc' }`), which is normalized to the `field:order` + * form the service expects. A raw string is passed through unchanged. + */ +export type DataSyncSort = string | Record; + +/** + * Serialize a {@link DataSyncSort} into the query value the service expects. + * + * A raw string is passed through unchanged. An object is turned into a list of `field:order` + * entries (a `null` direction emits the bare field name, letting the service apply its default + * ascending order). Mirrors the App Context `getAllChannelMetadata` sort handling. + * + * @internal + */ +export function serializeDataSyncSort(sort?: DataSyncSort): string | string[] { + if (typeof sort === 'string') return sort; + return Object.entries(sort ?? {}).map(([option, order]) => (order !== null ? `${option}:${order}` : option)); +} + /** * Single-entity response envelope. */ @@ -136,14 +162,53 @@ type DataSyncPagedResponse = { /** * JSON Patch operation as defined by RFC 6902. * - * Internal wire format. Developers use `add`/`replace`/`remove` with dot notation instead. + * Internal wire format. Developers use `add`/`replace`/`remove`/`move`/`copy`/`test` with dot + * notation instead. `from` is the source location for `move`/`copy`; `value` carries the operand + * for `add`/`replace`/`test`. * * @internal */ export type JsonPatchOperation = { - op: 'add' | 'remove' | 'replace'; + op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test'; path: string; value?: unknown; + from?: string; +}; + +/** + * A source → destination path pair (dot notation) for JSON Patch `move` and `copy` operations. + */ +export type PatchMovePath = { + /** Dot-notation source path (RFC 6902 `from`). */ + from: string; + + /** Dot-notation destination path (RFC 6902 `path`). */ + path: string; +}; + +/** + * User-friendly JSON Patch input (dot notation), converted to RFC 6902 operations on the wire. + * + * @internal + */ +export type JsonPatchInput = { + /** Fields to add (dot path → value). */ + add?: Record; + + /** Fields to replace (dot path → value). */ + replace?: Record; + + /** Dot-notation paths to remove. */ + remove?: string[]; + + /** Source → destination path pairs to move. */ + move?: PatchMovePath[]; + + /** Source → destination path pairs to copy. */ + copy?: PatchMovePath[]; + + /** Fields to test (dot path → expected value). */ + test?: Record; }; /** @@ -159,19 +224,19 @@ export function toJsonPointer(dotPath: string): string { } /** - * Convert `add`, `replace`, and `remove` parameters to JSON Patch operations (wire format). + * Convert user-friendly dot-notation patch input 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. + * - Each `{ from, path }` pair in `move` becomes a "move" operation. + * - Each `{ from, path }` pair in `copy` becomes a "copy" operation. + * - Each key in `test` becomes a "test" operation. * * @internal */ -export function toJsonPatchOperations( - add?: Record, - replace?: Record, - remove?: string[], -): JsonPatchOperation[] { +export function toJsonPatchOperations(input: JsonPatchInput): JsonPatchOperation[] { + const { add, replace, remove, move, copy, test } = input; const ops: JsonPatchOperation[] = []; if (add) { @@ -192,6 +257,24 @@ export function toJsonPatchOperations( } } + if (move) { + for (const { from, path } of move) { + ops.push({ op: 'move', from: toJsonPointer(from), path: toJsonPointer(path) }); + } + } + + if (copy) { + for (const { from, path } of copy) { + ops.push({ op: 'copy', from: toJsonPointer(from), path: toJsonPointer(path) }); + } + } + + if (test) { + for (const [dotPath, value] of Object.entries(test)) { + ops.push({ op: 'test', path: toJsonPointer(dotPath), value }); + } + } + return ops; } @@ -200,16 +283,15 @@ export function toJsonPatchOperations( // -------------------------------------------------------- /** - * Entity properties for create requests. + * Entity data properties for create requests. * - * Includes `entityClass` since it must be set at creation time and is immutable afterward. + * The mutable, versioned payload of an entity. `class` (immutable) and `id` live at the + * top level of {@link CreateEntityParameters}; everything that can change over the entity's + * lifetime is grouped here under `data`. */ -export type CreateEntityProperties = { - /** Entity class this entity belongs to. */ - entityClass: string; - +export type CreateEntityData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -219,13 +301,15 @@ export type CreateEntityProperties = { }; /** - * Entity properties for update (PUT) requests. + * Entity data properties for update (PUT) requests. * - * `entityClass` is immutable after creation and therefore excluded from updates. + * The mutable, versioned payload of an entity. `id` lives at the top level of + * {@link UpdateEntityParameters}. `entityClass` is immutable after creation and therefore + * has no place in updates. */ -export type UpdateEntityProperties = { +export type UpdateEntityData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -273,25 +357,28 @@ export type EntityObject = { */ export type CreateEntityParameters = { /** - * Entity properties to create. + * Optional entity ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + + /** Entity class this entity belongs to. Set at creation time and immutable afterward. */ + class: string; + + /** + * Mutable, versioned entity data (class version, status, and payload). * - * 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; - }; + * These fields map into the request body envelope. `id` and `class` are kept at the top + * level because they identify the resource, while everything in `data` is what the entity + * carries and can change over its lifetime. + */ + data: CreateEntityData; }; /** * Get Entity request parameters. */ -export type GetEntityParameters = { +export type FetchEntityParameters = { /** Entity ID. */ id: string; }; @@ -301,7 +388,7 @@ export type GetEntityParameters = { * * `entityClass` is required — entities are always listed within the context of their class. */ -export type GetAllEntitiesParameters = PagedRequestParameters & { +export type FetchEntitiesParameters = PagedRequestParameters & { /** Entity class name to filter by (required). */ entityClass: string; @@ -322,15 +409,15 @@ export type GetAllEntitiesParameters = PagedRequestParameters & { /** * Update Entity request parameters (full replacement via PUT). * - * `entityClass` is immutable after creation — only `entityClassVersion`, `status`, + * `entityClass` is immutable after creation — only `classVersion`, `status`, * and `payload` can be updated. */ export type UpdateEntityParameters = { /** Entity ID. */ id: string; - /** Complete entity properties for replacement (excludes immutable `entityClass`). */ - entity: UpdateEntityProperties; + /** Complete, mutable entity data for replacement (excludes immutable `entityClass`). */ + data: UpdateEntityData; /** * ETag for optimistic concurrency control. @@ -395,6 +482,45 @@ export type PatchEntityParameters = { */ remove?: string[]; + /** + * Source → destination path pairs to move (RFC 6902 "move"). + * + * The value at each `from` is removed and re-added at `path`. Both are dot-notation paths used + * exactly as provided (prefix with `payload.` to target payload fields). + * + * @example + * ```typescript + * move: [{ from: 'payload.legacyName', path: 'payload.displayName' }] + * ``` + */ + move?: PatchMovePath[]; + + /** + * Source → destination path pairs to copy (RFC 6902 "copy"). + * + * The value at each `from` is duplicated to `path`. Both are dot-notation paths used exactly as + * provided (prefix with `payload.` to target payload fields). + * + * @example + * ```typescript + * copy: [{ from: 'payload.displayName', path: 'payload.previousName' }] + * ``` + */ + copy?: PatchMovePath[]; + + /** + * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). + * + * The patch fails if the value at any path does not equal the expected value. Keys are used + * exactly as provided (prefix with `payload.` for payload fields). + * + * @example + * ```typescript + * test: { 'status': 'active' } + * ``` + */ + test?: Record; + /** * ETag for optimistic concurrency control. * If provided, the patch only succeeds if the server's ETag matches. @@ -422,10 +548,10 @@ export type RemoveEntityParameters = { export type CreateEntityResponse = DataSyncEntityResponse; /** Response for getting a single entity. */ -export type GetEntityResponse = DataSyncEntityResponse; +export type FetchEntityResponse = DataSyncEntityResponse; /** Response for listing entities. */ -export type GetAllEntitiesResponse = DataSyncPagedResponse; +export type FetchEntitiesResponse = DataSyncPagedResponse; /** Response for updating an entity (PUT). */ export type UpdateEntityResponse = DataSyncEntityResponse; @@ -444,22 +570,15 @@ export type RemoveEntityResponse = { // -------------------------------------------------------- /** - * Relationship properties for create requests. + * Relationship data properties for create requests. * - * Both `entityAId` and `entityBId` must be set at creation time. + * The mutable, versioned payload of a relationship. `id`, `class`, `entityAId`, and `entityBId` + * live at the top level of {@link CreateRelationshipParameters} (identity + immutable structure); + * everything that can change over the relationship's lifetime is grouped here under `data`. */ -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; - +export type CreateRelationshipData = { /** Version of the relationship class schema. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -469,21 +588,15 @@ export type CreateRelationshipProperties = { }; /** - * Relationship properties for update (PUT) requests. + * Relationship data 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`. + * The mutable, versioned payload of a relationship. `id`, `entityAId`, and `entityBId` live at the + * top level of {@link UpdateRelationshipParameters}. `relationshipClass` is immutable after creation + * and therefore has no place in updates. The server rejects a PUT that omits `classVersion`. */ -export type UpdateRelationshipProperties = { - /** First entity ID in the relationship. */ - entityAId: string; - - /** Second entity ID in the relationship. */ - entityBId: string; - +export type UpdateRelationshipData = { /** Version of the relationship class schema. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -537,23 +650,28 @@ export type RelationshipObject = { */ 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; - }; + * Optional relationship ID. + * Server auto-generates a UUID if not provided. + */ + id?: string; + + /** Relationship class this relationship belongs to. Set at creation time and immutable afterward. */ + class: string; + + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Mutable, versioned relationship data (class version, status, and payload). */ + data: CreateRelationshipData; }; /** * Get Relationship request parameters. */ -export type GetRelationshipParameters = { +export type FetchRelationshipParameters = { /** Relationship ID. */ id: string; }; @@ -561,7 +679,7 @@ export type GetRelationshipParameters = { /** * Get All Relationships request parameters. */ -export type GetAllRelationshipsParameters = PagedRequestParameters & { +export type FetchRelationshipsParameters = PagedRequestParameters & { /** Relationship class name (required by the server). */ relationshipClass: string; @@ -590,8 +708,14 @@ export type UpdateRelationshipParameters = { /** Relationship ID. */ id: string; - /** Complete relationship properties for replacement. */ - relationship: UpdateRelationshipProperties; + /** First entity ID in the relationship. */ + entityAId: string; + + /** Second entity ID in the relationship. */ + entityBId: string; + + /** Complete, mutable relationship data for replacement (excludes immutable `relationshipClass`). */ + data: UpdateRelationshipData; /** * ETag for optimistic concurrency control. @@ -615,13 +739,13 @@ export type PatchRelationshipParameters = { /** * Fields to add, using dot-notation keys. * - * Each key is a dot-delimited path to the target field within `payload`. + * Each key is a dot-delimited path to the target field (prefix with `payload.` to target payload fields). * The SDK converts these to JSON Patch "add" operations. * * @example * ```typescript * add: { - * 'tags.0': 'mentor', + * 'payload.tags.0': 'mentor', * } * ``` */ @@ -630,31 +754,49 @@ export type PatchRelationshipParameters = { /** * Fields to replace, using dot-notation keys. * - * Each key is a dot-delimited path to the target field within `payload`. + * Each key is a dot-delimited path to the target field (prefix with `payload.` to target payload fields). * The SDK converts these to JSON Patch "replace" operations. * * @example * ```typescript * replace: { - * 'role': 'admin', - * 'permissions.read': true, + * 'payload.role': 'admin', + * 'payload.permissions.read': true, * } * ``` */ 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: ['payload.tempFlag', 'payload.legacyField'] * ``` */ remove?: string[]; + /** + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is removed and re-added at `path`. + */ + move?: PatchMovePath[]; + + /** + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is duplicated to `path`. + */ + copy?: PatchMovePath[]; + + /** + * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). The patch fails if the + * value at any path does not equal the expected value. Keys are used as provided (prefix with `payload.` for payload fields). + */ + test?: Record; + /** * ETag for optimistic concurrency control. * If provided, the patch only succeeds if the server's ETag matches. @@ -682,10 +824,10 @@ export type RemoveRelationshipParameters = { export type CreateRelationshipResponse = DataSyncEntityResponse; /** Response for getting a single relationship. */ -export type GetRelationshipResponse = DataSyncEntityResponse; +export type FetchRelationshipResponse = DataSyncEntityResponse; /** Response for listing relationships. */ -export type GetAllRelationshipsResponse = DataSyncPagedResponse; +export type FetchRelationshipsResponse = DataSyncPagedResponse; /** Response for updating a relationship (PUT). */ export type UpdateRelationshipResponse = DataSyncEntityResponse; @@ -704,11 +846,14 @@ export type RemoveRelationshipResponse = { // -------------------------------------------------------- /** - * User properties for create requests. + * User data properties for create requests. + * + * The mutable, versioned payload of a user. `id` lives at the top level of + * {@link CreateUserParameters}; everything that can change over the user's lifetime is here. */ -export type CreateUserProperties = { +export type CreateUserData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -753,23 +898,24 @@ export type UserObject = { */ export type CreateUserParameters = { /** - * 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; - }; + id?: string; + + /** Mutable, versioned user data (class version, status, and payload). */ + data: CreateUserData; }; /** - * User properties for update (PUT) requests. + * User data properties for update (PUT) requests. + * + * The mutable, versioned payload of a user. `id` lives at the top level of + * {@link UpdateUserParameters}. */ -export type UpdateUserProperties = { +export type UpdateUserData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -781,7 +927,7 @@ export type UpdateUserProperties = { /** * Get User request parameters. */ -export type GetUserParameters = { +export type FetchUserParameters = { /** User ID. */ id: string; }; @@ -789,7 +935,7 @@ export type GetUserParameters = { /** * Get All Users request parameters. */ -export type GetAllUsersParameters = PagedRequestParameters & { +export type FetchUsersParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns users for the latest version. */ @@ -808,8 +954,8 @@ export type UpdateUserParameters = { /** User ID. */ id: string; - /** Complete user properties for replacement. */ - user: UpdateUserProperties; + /** Complete, mutable user data for replacement. */ + data: UpdateUserData; /** * ETag for optimistic concurrency control. @@ -848,6 +994,24 @@ export type PatchUserParameters = { */ remove?: string[]; + /** + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is removed and re-added at `path`. + */ + move?: PatchMovePath[]; + + /** + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is duplicated to `path`. + */ + copy?: PatchMovePath[]; + + /** + * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). The patch fails if the + * value at any path does not equal the expected value. Keys are used as provided (prefix with `payload.` for payload fields). + */ + test?: Record; + /** * ETag for optimistic concurrency control. */ @@ -873,10 +1037,10 @@ export type RemoveUserParameters = { export type CreateUserResponse = DataSyncEntityResponse; /** Response for getting a single user. */ -export type GetUserResponse = DataSyncEntityResponse; +export type FetchUserResponse = DataSyncEntityResponse; /** Response for listing users. */ -export type GetAllUsersResponse = DataSyncPagedResponse; +export type FetchUsersResponse = DataSyncPagedResponse; /** Response for updating a user (PUT). */ export type UpdateUserResponse = DataSyncEntityResponse; @@ -895,11 +1059,14 @@ export type RemoveUserResponse = { // -------------------------------------------------------- /** - * Channel properties for create requests. + * Channel data properties for create requests. + * + * The mutable, versioned payload of a channel. `id` lives at the top level of + * {@link CreateChannelParameters}; everything that can change over the channel's lifetime is here. */ -export type CreateChannelProperties = { +export type CreateChannelData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -909,11 +1076,14 @@ export type CreateChannelProperties = { }; /** - * Channel properties for update (PUT) requests. + * Channel data properties for update (PUT) requests. + * + * The mutable, versioned payload of a channel. `id` lives at the top level of + * {@link UpdateChannelParameters}. */ -export type UpdateChannelProperties = { +export type UpdateChannelData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -958,21 +1128,19 @@ export type ChannelObject = { */ export type CreateChannelParameters = { /** - * 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; - }; + id?: string; + + /** Mutable, versioned channel data (class version, status, and payload). */ + data: CreateChannelData; }; /** * Get Channel request parameters. */ -export type GetChannelParameters = { +export type FetchChannelParameters = { /** Channel ID. */ id: string; }; @@ -980,7 +1148,7 @@ export type GetChannelParameters = { /** * Get All Channels request parameters. */ -export type GetAllChannelsParameters = PagedRequestParameters & { +export type FetchChannelsParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns channels for the latest version. */ @@ -999,8 +1167,8 @@ export type UpdateChannelParameters = { /** Channel ID. */ id: string; - /** Complete channel properties for replacement. */ - channel: UpdateChannelProperties; + /** Complete, mutable channel data for replacement. */ + data: UpdateChannelData; /** * ETag for optimistic concurrency control. @@ -1037,6 +1205,24 @@ export type PatchChannelParameters = { */ remove?: string[]; + /** + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is removed and re-added at `path`. + */ + move?: PatchMovePath[]; + + /** + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is duplicated to `path`. + */ + copy?: PatchMovePath[]; + + /** + * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). The patch fails if the + * value at any path does not equal the expected value. Keys are used as provided (prefix with `payload.` for payload fields). + */ + test?: Record; + /** * ETag for optimistic concurrency control. */ @@ -1062,10 +1248,10 @@ export type RemoveChannelParameters = { export type CreateChannelResponse = DataSyncEntityResponse; /** Response for getting a single channel. */ -export type GetChannelResponse = DataSyncEntityResponse; +export type FetchChannelResponse = DataSyncEntityResponse; /** Response for listing channels. */ -export type GetAllChannelsResponse = DataSyncPagedResponse; +export type FetchChannelsResponse = DataSyncPagedResponse; /** Response for updating a channel (PUT). */ export type UpdateChannelResponse = DataSyncEntityResponse; @@ -1084,19 +1270,15 @@ export type RemoveChannelResponse = { // -------------------------------------------------------- /** - * Membership properties for create requests. + * Membership data properties for create requests. * - * Both `userId` and `channelId` must be set at creation time. + * The mutable, versioned payload of a membership. `id`, `userId`, and `channelId` live at the + * top level of {@link CreateMembershipParameters} (identity + immutable structure); everything + * that can change over the membership's lifetime is grouped here under `data`. */ -export type CreateMembershipProperties = { - /** User ID reference. */ - userId: string; - - /** Channel ID reference. */ - channelId: string; - +export type CreateMembershipData = { /** Version of the Membership relationship class. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -1106,21 +1288,15 @@ export type CreateMembershipProperties = { }; /** - * Membership properties for update (PUT) requests. + * Membership data properties for update (PUT) requests. * - * 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}. + * The mutable, versioned payload of a membership. `id`, `userId`, and `channelId` live at the top + * level of {@link UpdateMembershipParameters}. The server rejects a PUT that omits `classVersion` + * (`SYN-0004: must not be null`), mirroring {@link UpdateRelationshipData}. */ -export type UpdateMembershipProperties = { - /** User ID reference. */ - userId: string; - - /** Channel ID reference. */ - channelId: string; - +export type UpdateMembershipData = { /** Version of the Membership relationship class. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; @@ -1175,21 +1351,25 @@ export type MembershipObject = { */ export type CreateMembershipParameters = { /** - * Membership properties to create. + * Optional membership ID. + * Server auto-generates a UUID if not provided. */ - membership: CreateMembershipProperties & { - /** - * Optional membership ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; + id?: string; + + /** User ID reference. */ + userId: string; + + /** Channel ID reference. */ + channelId: string; + + /** Mutable, versioned membership data (class version, status, and payload). */ + data: CreateMembershipData; }; /** * Get Membership request parameters. */ -export type GetMembershipParameters = { +export type FetchMembershipParameters = { /** Membership ID. */ id: string; }; @@ -1197,7 +1377,7 @@ export type GetMembershipParameters = { /** * Get All Memberships request parameters. */ -export type GetAllMembershipsParameters = PagedRequestParameters & { +export type FetchMembershipsParameters = PagedRequestParameters & { /** Filter memberships by user ID. */ userId?: string; @@ -1223,8 +1403,14 @@ export type UpdateMembershipParameters = { /** Membership ID. */ id: string; - /** Complete membership properties for replacement. */ - membership: UpdateMembershipProperties; + /** User ID reference. */ + userId: string; + + /** Channel ID reference. */ + channelId: string; + + /** Complete, mutable membership data for replacement. */ + data: UpdateMembershipData; /** * ETag for optimistic concurrency control. @@ -1261,6 +1447,24 @@ export type PatchMembershipParameters = { */ remove?: string[]; + /** + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is removed and re-added at `path`. + */ + move?: PatchMovePath[]; + + /** + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are dot-notation and + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is duplicated to `path`. + */ + copy?: PatchMovePath[]; + + /** + * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). The patch fails if the + * value at any path does not equal the expected value. Keys are used as provided (prefix with `payload.` for payload fields). + */ + test?: Record; + /** * ETag for optimistic concurrency control. */ @@ -1286,10 +1490,10 @@ export type RemoveMembershipParameters = { export type CreateMembershipResponse = DataSyncEntityResponse; /** Response for getting a single membership. */ -export type GetMembershipResponse = DataSyncEntityResponse; +export type FetchMembershipResponse = DataSyncEntityResponse; /** Response for listing memberships. */ -export type GetAllMembershipsResponse = DataSyncPagedResponse; +export type FetchMembershipsResponse = DataSyncPagedResponse; /** Response for updating a membership (PUT). */ export type UpdateMembershipResponse = DataSyncEntityResponse; diff --git a/src/transport/middleware.ts b/src/transport/middleware.ts index 648783c31..78795e143 100644 --- a/src/transport/middleware.ts +++ b/src/transport/middleware.ts @@ -15,6 +15,11 @@ import { Transport } from '../core/interfaces/transport'; import { encodeString } from '../core/utils'; import { Query } from '../core/types/api'; +/** + * HTTP status codes that represent definitive client outcomes and must not be retried. + */ +const NON_RETRIABLE_STATUS_CODES = [404, 409]; + /** * Transport middleware configuration options. * @@ -172,8 +177,10 @@ export class PubNubMiddleware implements Transport { activeCancellation = attemptCancellation; const responseHandler = (res?: TransportResponse, error?: PubNubAPIError) => { - const retriableError = error ? error.category !== StatusCategory.PNCancelledCategory : true; - const retriableStatusCode = (!res || res.status >= 400) && error?.statusCode !== 404; + const retriableError = !error || error.category !== StatusCategory.PNCancelledCategory; + const statusCode = error?.statusCode; + const retriableStatusCode = + (!res || res.status >= 400) && !NON_RETRIABLE_STATUS_CODES.includes(statusCode as number); let delay = -1; if (