From 0c83fb4b3de315f048b72c12650069987ede29e0 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Fri, 22 May 2026 13:27:49 +0530 Subject: [PATCH 01/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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/27] 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 ( From 0c506462b03bcf70a6d267590664cb336b30d2f0 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 27 Jul 2026 11:34:10 +0530 Subject: [PATCH 21/27] lint fixes --- src/core/endpoints/data_sync/entity/fetch.ts | 5 +++- src/core/pubnub-data-sync.ts | 9 ++++++-- src/core/types/api/data-sync.ts | 24 +++++++++++++------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/core/endpoints/data_sync/entity/fetch.ts b/src/core/endpoints/data_sync/entity/fetch.ts index 862937348..af75191fb 100644 --- a/src/core/endpoints/data_sync/entity/fetch.ts +++ b/src/core/endpoints/data_sync/entity/fetch.ts @@ -32,7 +32,10 @@ type RequestParameters = DataSync.FetchEntityParameters & { * * @internal */ -export class FetchEntityRequest extends AbstractRequest { +export class FetchEntityRequest extends AbstractRequest< + Response, + Response +> { constructor(private readonly parameters: RequestParameters) { super(); } diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index 47f2e943c..63dfb7f74 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -754,7 +754,10 @@ export default class PubNubDataSync { * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchUser(parameters: DataSync.FetchUserParameters, callback: ResultCallback): void; + public fetchUser( + parameters: DataSync.FetchUserParameters, + callback: ResultCallback, + ): void; /** * Fetch a specific User. @@ -1377,7 +1380,9 @@ export default class PubNubDataSync { * * @returns Asynchronous fetch membership response. */ - public async fetchMembership(parameters: DataSync.FetchMembershipParameters): Promise; + public async fetchMembership( + parameters: DataSync.FetchMembershipParameters, + ): Promise; /** * Fetch a specific Membership. diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 907969607..ceb8f84ed 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -781,7 +781,8 @@ export type PatchRelationshipParameters = { /** * 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`. + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is + * removed and re-added at `path`. */ move?: PatchMovePath[]; @@ -793,7 +794,8 @@ export type PatchRelationshipParameters = { /** * 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). + * value at any path does not equal the expected value. Keys are used as provided (prefix with + * `payload.` for payload fields). */ test?: Record; @@ -996,7 +998,8 @@ export type PatchUserParameters = { /** * 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`. + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is + * removed and re-added at `path`. */ move?: PatchMovePath[]; @@ -1008,7 +1011,8 @@ export type PatchUserParameters = { /** * 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). + * value at any path does not equal the expected value. Keys are used as provided (prefix with + * `payload.` for payload fields). */ test?: Record; @@ -1207,7 +1211,8 @@ export type PatchChannelParameters = { /** * 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`. + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is + * removed and re-added at `path`. */ move?: PatchMovePath[]; @@ -1219,7 +1224,8 @@ export type PatchChannelParameters = { /** * 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). + * value at any path does not equal the expected value. Keys are used as provided (prefix with + * `payload.` for payload fields). */ test?: Record; @@ -1449,7 +1455,8 @@ export type PatchMembershipParameters = { /** * 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`. + * used as provided (prefix with `payload.` to target payload fields); the value at `from` is + * removed and re-added at `path`. */ move?: PatchMovePath[]; @@ -1461,7 +1468,8 @@ export type PatchMembershipParameters = { /** * 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). + * value at any path does not equal the expected value. Keys are used as provided (prefix with + * `payload.` for payload fields). */ test?: Record; From 82d6083135837579a08272323b07baf636193240 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 27 Jul 2026 12:53:41 +0530 Subject: [PATCH 22/27] DATA_SYNC_MODULE environment variable based module load for dataSync feature --- rollup.config.js | 9 +++++++++ src/core/pubnub-common.ts | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rollup.config.js b/rollup.config.js index 0e0c2017b..4b44211e3 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -116,6 +116,15 @@ const replaceConfiguration = { */ 'process.env.APP_CONTEXT_MODULE': JSON.stringify(process.env.APP_CONTEXT_MODULE ?? 'enabled'), + /** + * Module contains functionality related to the DataSync entities, relationships, and their + * typed convenience resources (users, channels, memberships). + * + * Set `DATA_SYNC_MODULE` environment variable to `disabled` during build with Webpack or + * roll-up to exclude module during tree-shaking optimization process. + */ + 'process.env.DATA_SYNC_MODULE': JSON.stringify(process.env.DATA_SYNC_MODULE ?? 'enabled'), + /** * Module contains functionality related to the file sharing. * diff --git a/src/core/pubnub-common.ts b/src/core/pubnub-common.ts index d90e49c4e..ea3f2d401 100644 --- a/src/core/pubnub-common.ts +++ b/src/core/pubnub-common.ts @@ -323,6 +323,7 @@ export class PubNubCore< * * @internal */ + // @ts-expect-error Allowed to simplify interface when module can be disabled. private readonly _dataSync: PubNubDataSync; /** @@ -443,7 +444,8 @@ 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.DATA_SYNC_MODULE !== 'disabled') + this._dataSync = new PubNubDataSync(this._configuration, this.sendRequest.bind(this)); if (process.env.CHANNEL_GROUPS_MODULE !== 'disabled') this._channelGroups = new PubNubChannelGroups( this._configuration.logger(), From 7e55c5cdf09d9e41d43410da06fbea40f324b261 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 17 Aug 2026 12:15:37 +0530 Subject: [PATCH 23/27] dataSync updates: refined method naming convention consistent as per feature, support for `classLevel` grantToken update to allow users, channels resources and patterns for dataSync permissions class name support at Users and channels apis. --- lib/core/endpoints/data_sync/channel/patch.js | 84 -- lib/core/endpoints/data_sync/entity/patch.js | 84 -- .../endpoints/data_sync/membership/patch.js | 84 -- .../endpoints/data_sync/relationship/patch.js | 84 -- lib/core/endpoints/data_sync/user/patch.js | 84 -- src/core/constants/operations.ts | 80 +- .../endpoints/access_manager/grant_token.ts | 95 +-- .../endpoints/data_sync/channel/create.ts | 6 +- .../channel/{fetch-all.ts => get-all.ts} | 10 +- .../data_sync/channel/{fetch.ts => get.ts} | 10 +- .../endpoints/data_sync/channel/remove.ts | 2 +- .../data_sync/channel/{patch.ts => set.ts} | 45 +- .../endpoints/data_sync/channel/update.ts | 37 +- src/core/endpoints/data_sync/entity/create.ts | 5 +- .../entity/{fetch-all.ts => get-all.ts} | 10 +- .../data_sync/entity/{fetch.ts => get.ts} | 13 +- src/core/endpoints/data_sync/entity/remove.ts | 2 +- .../data_sync/entity/{patch.ts => set.ts} | 49 +- src/core/endpoints/data_sync/entity/update.ts | 38 +- .../endpoints/data_sync/membership/create.ts | 2 +- .../membership/{fetch-all.ts => get-all.ts} | 10 +- .../data_sync/membership/{fetch.ts => get.ts} | 10 +- .../endpoints/data_sync/membership/remove.ts | 2 +- .../data_sync/membership/{patch.ts => set.ts} | 48 +- .../endpoints/data_sync/membership/update.ts | 40 +- .../data_sync/relationship/create.ts | 2 +- .../relationship/{fetch-all.ts => get-all.ts} | 10 +- .../relationship/{fetch.ts => get.ts} | 10 +- .../data_sync/relationship/remove.ts | 2 +- .../relationship/{patch.ts => set.ts} | 49 +- .../data_sync/relationship/update.ts | 41 +- src/core/endpoints/data_sync/user/create.ts | 6 +- .../user/{fetch-all.ts => get-all.ts} | 13 +- .../data_sync/user/{fetch.ts => get.ts} | 10 +- src/core/endpoints/data_sync/user/remove.ts | 2 +- .../data_sync/user/{patch.ts => set.ts} | 45 +- src/core/endpoints/data_sync/user/update.ts | 37 +- src/core/endpoints/subscribe.ts | 105 ++- src/core/pubnub-data-sync.ts | 721 +++++++++--------- src/core/types/api/access-manager.ts | 41 +- src/core/types/api/data-sync.ts | 295 +++++-- src/core/types/api/subscription.ts | 1 + 42 files changed, 1028 insertions(+), 1296 deletions(-) delete mode 100644 lib/core/endpoints/data_sync/channel/patch.js delete mode 100644 lib/core/endpoints/data_sync/entity/patch.js delete mode 100644 lib/core/endpoints/data_sync/membership/patch.js delete mode 100644 lib/core/endpoints/data_sync/relationship/patch.js delete mode 100644 lib/core/endpoints/data_sync/user/patch.js rename src/core/endpoints/data_sync/channel/{fetch-all.ts => get-all.ts} (88%) rename src/core/endpoints/data_sync/channel/{fetch.ts => get.ts} (84%) rename src/core/endpoints/data_sync/channel/{patch.ts => set.ts} (55%) rename src/core/endpoints/data_sync/entity/{fetch-all.ts => get-all.ts} (89%) rename src/core/endpoints/data_sync/entity/{fetch.ts => get.ts} (83%) rename src/core/endpoints/data_sync/entity/{patch.ts => set.ts} (54%) rename src/core/endpoints/data_sync/membership/{fetch-all.ts => get-all.ts} (88%) rename src/core/endpoints/data_sync/membership/{fetch.ts => get.ts} (84%) rename src/core/endpoints/data_sync/membership/{patch.ts => set.ts} (54%) rename src/core/endpoints/data_sync/relationship/{fetch-all.ts => get-all.ts} (89%) rename src/core/endpoints/data_sync/relationship/{fetch.ts => get.ts} (83%) rename src/core/endpoints/data_sync/relationship/{patch.ts => set.ts} (54%) rename src/core/endpoints/data_sync/user/{fetch-all.ts => get-all.ts} (88%) rename src/core/endpoints/data_sync/user/{fetch.ts => get.ts} (84%) rename src/core/endpoints/data_sync/user/{patch.ts => set.ts} (54%) diff --git a/lib/core/endpoints/data_sync/channel/patch.js b/lib/core/endpoints/data_sync/channel/patch.js deleted file mode 100644 index 5be9797c0..000000000 --- a/lib/core/endpoints/data_sync/channel/patch.js +++ /dev/null @@ -1,84 +0,0 @@ -"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 __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.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; - } - 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'; - 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/entity/patch.js b/lib/core/endpoints/data_sync/entity/patch.js deleted file mode 100644 index fd9649405..000000000 --- a/lib/core/endpoints/data_sync/entity/patch.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -/** - * 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 - */ -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.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; - } - 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/${(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 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.PatchEntityRequest = PatchEntityRequest; diff --git a/lib/core/endpoints/data_sync/membership/patch.js b/lib/core/endpoints/data_sync/membership/patch.js deleted file mode 100644 index 4b6f22771..000000000 --- a/lib/core/endpoints/data_sync/membership/patch.js +++ /dev/null @@ -1,84 +0,0 @@ -"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 __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.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; - } - 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/${(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/relationship/patch.js b/lib/core/endpoints/data_sync/relationship/patch.js deleted file mode 100644 index 3ffab6fb7..000000000 --- a/lib/core/endpoints/data_sync/relationship/patch.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; -/** - * 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 - */ -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.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; - } - 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/${(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 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.PatchRelationshipRequest = PatchRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/user/patch.js b/lib/core/endpoints/data_sync/user/patch.js deleted file mode 100644 index 8d230ecc8..000000000 --- a/lib/core/endpoints/data_sync/user/patch.js +++ /dev/null @@ -1,84 +0,0 @@ -"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 __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.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; - } - 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'; - 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/src/core/constants/operations.ts b/src/core/constants/operations.ts index 5e83bd191..677306d4e 100644 --- a/src/core/constants/operations.ts +++ b/src/core/constants/operations.ts @@ -182,152 +182,152 @@ enum RequestOperation { /** * Create entity REST API operation. */ - PNCreateEntityOperation = 'PNCreateEntityOperation', + PNCreateDataSyncEntityOperation = 'PNCreateDataSyncEntityOperation', /** * Get entity REST API operation. */ - PNFetchEntityOperation = 'PNFetchEntityOperation', + PNGetDataSyncEntityOperation = 'PNGetDataSyncEntityOperation', /** * Get all entities REST API operation. */ - PNFetchEntitiesOperation = 'PNFetchEntitiesOperation', + PNGetDataSyncEntitiesOperation = 'PNGetDataSyncEntitiesOperation', /** - * Update entity REST API operation. + * Set entity REST API operation (full replacement via PUT). */ - PNUpdateEntityOperation = 'PNUpdateEntityOperation', + PNSetDataSyncEntityOperation = 'PNSetDataSyncEntityOperation', /** - * Patch entity REST API operation. + * Update entity REST API operation (partial update via PATCH). */ - PNPatchEntityOperation = 'PNPatchEntityOperation', + PNUpdateDataSyncEntityOperation = 'PNUpdateDataSyncEntityOperation', /** * Remove entity REST API operation. */ - PNRemoveEntityOperation = 'PNRemoveEntityOperation', + PNRemoveDataSyncEntityOperation = 'PNRemoveDataSyncEntityOperation', /** * Create relationship REST API operation. */ - PNCreateRelationshipOperation = 'PNCreateRelationshipOperation', + PNCreateDataSyncRelationshipOperation = 'PNCreateDataSyncRelationshipOperation', /** * Get relationship REST API operation. */ - PNFetchRelationshipOperation = 'PNFetchRelationshipOperation', + PNGetDataSyncRelationshipOperation = 'PNGetDataSyncRelationshipOperation', /** * Get all relationships REST API operation. */ - PNFetchRelationshipsOperation = 'PNFetchRelationshipsOperation', + PNGetDataSyncRelationshipsOperation = 'PNGetDataSyncRelationshipsOperation', /** - * Update relationship REST API operation. + * Set relationship REST API operation (full replacement via PUT). */ - PNUpdateRelationshipOperation = 'PNUpdateRelationshipOperation', + PNSetDataSyncRelationshipOperation = 'PNSetDataSyncRelationshipOperation', /** - * Patch relationship REST API operation. + * Update relationship REST API operation (partial update via PATCH). */ - PNPatchRelationshipOperation = 'PNPatchRelationshipOperation', + PNUpdateDataSyncRelationshipOperation = 'PNUpdateDataSyncRelationshipOperation', /** * Remove relationship REST API operation. */ - PNRemoveRelationshipOperation = 'PNRemoveRelationshipOperation', + PNRemoveDataSyncRelationshipOperation = 'PNRemoveDataSyncRelationshipOperation', /** * Create user REST API operation. */ - PNCreateUserOperation = 'PNCreateUserOperation', + PNCreateDataSyncUserOperation = 'PNCreateDataSyncUserOperation', /** * Get user REST API operation. */ - PNFetchUserOperation = 'PNFetchUserOperation', + PNGetDataSyncUserOperation = 'PNGetDataSyncUserOperation', /** * Get all users REST API operation. */ - PNFetchUsersOperation = 'PNFetchUsersOperation', + PNGetDataSyncUsersOperation = 'PNGetDataSyncUsersOperation', /** - * Update user REST API operation. + * Set user REST API operation (full replacement via PUT). */ - PNUpdateUserOperation = 'PNUpdateUserOperation', + PNSetDataSyncUserOperation = 'PNSetDataSyncUserOperation', /** - * Patch user REST API operation. + * Update user REST API operation (partial update via PATCH). */ - PNPatchUserOperation = 'PNPatchUserOperation', + PNUpdateDataSyncUserOperation = 'PNUpdateDataSyncUserOperation', /** * Remove user REST API operation. */ - PNRemoveUserOperation = 'PNRemoveUserOperation', + PNRemoveDataSyncUserOperation = 'PNRemoveDataSyncUserOperation', /** * Create channel REST API operation. */ - PNCreateChannelOperation = 'PNCreateChannelOperation', + PNCreateDataSyncChannelOperation = 'PNCreateDataSyncChannelOperation', /** * Get channel REST API operation. */ - PNFetchChannelOperation = 'PNFetchChannelOperation', + PNGetDataSyncChannelOperation = 'PNGetDataSyncChannelOperation', /** * Get all channels REST API operation. */ - PNFetchChannelsOperation = 'PNFetchChannelsOperation', + PNGetDataSyncChannelsOperation = 'PNGetDataSyncChannelsOperation', /** - * Update channel REST API operation. + * Set channel REST API operation (full replacement via PUT). */ - PNUpdateChannelOperation = 'PNUpdateChannelOperation', + PNSetDataSyncChannelOperation = 'PNSetDataSyncChannelOperation', /** - * Patch channel REST API operation. + * Update channel REST API operation (partial update via PATCH). */ - PNPatchChannelOperation = 'PNPatchChannelOperation', + PNUpdateDataSyncChannelOperation = 'PNUpdateDataSyncChannelOperation', /** * Remove channel REST API operation. */ - PNRemoveChannelOperation = 'PNRemoveChannelOperation', + PNRemoveDataSyncChannelOperation = 'PNRemoveDataSyncChannelOperation', /** * Create membership REST API operation. */ - PNCreateMembershipOperation = 'PNCreateMembershipOperation', + PNCreateDataSyncMembershipOperation = 'PNCreateDataSyncMembershipOperation', /** * Get membership REST API operation. */ - PNFetchMembershipOperation = 'PNFetchMembershipOperation', + PNGetDataSyncMembershipOperation = 'PNGetDataSyncMembershipOperation', /** * Get all memberships REST API operation. */ - PNFetchMembershipsOperation = 'PNFetchMembershipsOperation', + PNGetDataSyncMembershipsOperation = 'PNGetDataSyncMembershipsOperation', /** - * Update membership REST API operation. + * Set membership REST API operation (full replacement via PUT). */ - PNUpdateMembershipOperation = 'PNUpdateMembershipOperation', + PNSetDataSyncMembershipOperation = 'PNSetDataSyncMembershipOperation', /** - * Patch membership REST API operation. + * Update membership REST API operation (partial update via PATCH). */ - PNPatchMembershipOperation = 'PNPatchMembershipOperation', + PNUpdateDataSyncMembershipOperation = 'PNUpdateDataSyncMembershipOperation', /** * Remove membership REST API operation. */ - PNRemoveMembershipOperation = 'PNRemoveMembershipOperation', + PNRemoveDataSyncMembershipOperation = 'PNRemoveDataSyncMembershipOperation', // -------------------------------------------------------- // -------------------- File Upload API ------------------- diff --git a/src/core/endpoints/access_manager/grant_token.ts b/src/core/endpoints/access_manager/grant_token.ts index 1d88270f1..671fd672d 100644 --- a/src/core/endpoints/access_manager/grant_token.ts +++ b/src/core/endpoints/access_manager/grant_token.ts @@ -37,6 +37,11 @@ type PermissionPayload = { */ uuids?: Record; + /** + * Object containing `user` permissions. + */ + users?: Record; + /** * Object containing `channel` permissions. */ @@ -147,19 +152,21 @@ export class GrantTokenRequest extends AbstractRequest + scope in (this.parameters.resources ?? {}) || scope in (this.parameters.patterns ?? {}); + + if (hasScope('users') && hasScope('uuids')) + return 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`'; + if (hasScope('spaces') && hasScope('channels')) + return 'Cannot mix `spaces` with `channels` — `spaces` is deprecated terminology; use `channels`'; + if ('authorizedUserId' in this.parameters && 'authorized_uuid' in this.parameters) + return 'Cannot mix `authorizedUserId` with `authorized_uuid` — use `authorizedUserId`'; let permissionsEmpty = true; [this.parameters.resources, this.parameters.patterns].forEach((refPerm) => { @@ -189,9 +196,11 @@ export class GrantTokenRequest extends AbstractRequest = { ...(ttl || ttl === 0 ? { ttl } : {}) }; - const uuid = this.isVspPermissions(this.parameters) - ? this.parameters.authorizedUserId - : this.parameters.authorized_uuid; + // `authorizedUserId` is the preferred User-terminology principal; `authorized_uuid` is the + // legacy App Context name. Either binds the token to a single principal. + const uuid = + ('authorizedUserId' in this.parameters ? this.parameters.authorizedUserId : undefined) ?? + ('authorized_uuid' in this.parameters ? this.parameters.authorized_uuid : undefined); const permissions: Record> = {}; const resourcePermissions: PermissionPayload = {}; @@ -212,25 +221,36 @@ export class GrantTokenRequest extends AbstractRequest = {}; let channelGroupsPermissions: Record = {}; let uuidsPermissions: Record = {}; + let usersPermissions: Record = {}; if (!target.channels) target.channels = {}; if (!target.groups) target.groups = {}; if (!target.uuids) target.uuids = {}; - // @ts-expect-error Not used, needed for api backward compatibility if (!target.users) target.users = {}; // @ts-expect-error Not used, needed for api backward compatibility if (!target.spaces) target.spaces = {}; if (refPerm) { - // Check whether working with legacy Objects permissions. - if ('spaces' in refPerm || 'users' in refPerm) { - channelsPermissions = refPerm.spaces ?? {}; - uuidsPermissions = refPerm.users ?? {}; - } else if ('channels' in refPerm || 'uuids' in refPerm || 'groups' in refPerm) { - channelsPermissions = refPerm.channels ?? {}; - channelGroupsPermissions = refPerm.groups ?? {}; - uuidsPermissions = refPerm.uuids ?? {}; - } + // `spaces` (deprecated) still collapses onto the channel wire scope. `users` and `uuids` + // are distinct wire keys: `users` maps to `users`, `uuids` maps to `uuids`. Validation + // already rejects providing both members of a synonym pair. `spaces` is read intentionally + // as the legacy fallback for channels. + const legacyRefPerm = refPerm as { + channels?: Record; + groups?: Record; + uuids?: Record; + users?: Record; + spaces?: Record; + }; + channelsPermissions = + 'channels' in legacyRefPerm + ? (legacyRefPerm.channels ?? {}) + : 'spaces' in legacyRefPerm + ? (legacyRefPerm.spaces ?? {}) + : {}; + channelGroupsPermissions = 'groups' in legacyRefPerm ? (legacyRefPerm.groups ?? {}) : {}; + uuidsPermissions = 'uuids' in legacyRefPerm ? (legacyRefPerm.uuids ?? {}) : {}; + usersPermissions = 'users' in legacyRefPerm ? (legacyRefPerm.users ?? {}) : {}; } Object.keys(channelsPermissions).forEach((channel) => @@ -245,6 +265,10 @@ export class GrantTokenRequest extends AbstractRequest + mapPermissions(users, this.extractPermissions(usersPermissions[users]), 'users', target), + ); + if (refPerm && 'dataSync' in refPerm) this.mapDataSyncPermissions(refPerm.dataSync, target, mapPermissions); }); @@ -360,23 +384,4 @@ export class GrantTokenRequest extends AbstractRequest { @@ -75,12 +75,14 @@ export class CreateChannelRequest extends AbstractRequest< +export class GetChannelsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class FetchChannelsRequest { diff --git a/src/core/endpoints/data_sync/channel/fetch.ts b/src/core/endpoints/data_sync/channel/get.ts similarity index 84% rename from src/core/endpoints/data_sync/channel/fetch.ts rename to src/core/endpoints/data_sync/channel/get.ts index 808f35207..20227ad6a 100644 --- a/src/core/endpoints/data_sync/channel/fetch.ts +++ b/src/core/endpoints/data_sync/channel/get.ts @@ -1,5 +1,5 @@ /** - * Fetch Channel REST API module. + * Get Channel REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchChannelParameters & { +type RequestParameters = DataSync.GetChannelParameters & { /** * PubNub REST API access key set. */ @@ -28,11 +28,11 @@ type RequestParameters = DataSync.FetchChannelParameters & { // endregion /** - * Fetch Channel request. + * Get Channel request. * * @internal */ -export class FetchChannelRequest extends AbstractRequest< +export class GetChannelRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class FetchChannelRequest } operation(): RequestOperation { - return RequestOperation.PNFetchChannelOperation; + return RequestOperation.PNGetDataSyncChannelOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/channel/remove.ts b/src/core/endpoints/data_sync/channel/remove.ts index f6cdd378b..ba4a44ad1 100644 --- a/src/core/endpoints/data_sync/channel/remove.ts +++ b/src/core/endpoints/data_sync/channel/remove.ts @@ -42,7 +42,7 @@ export class RemoveChannelRequest extends AbstractRequest< +export class SetChannelRequest extends AbstractRequest< Response, Response > { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PATCH }); + super({ method: TransportMethod.PUT }); } operation(): RequestOperation { - return RequestOperation.PNPatchChannelOperation; + return RequestOperation.PNSetDataSyncChannelOperation; } async parse(response: TransportResponse): Promise { @@ -60,16 +56,9 @@ export class PatchChannelRequest validate(): string | undefined { if (!this.parameters.id) return 'Channel id cannot be empty'; - - 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'; + if (!this.parameters.data) return 'Channel data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) + return 'Entity class version cannot be empty'; } protected get headers(): Record | undefined { @@ -79,7 +68,7 @@ export class PatchChannelRequest return { ...headers, - 'Content-Type': 'application/json-patch+json', + 'Content-Type': 'application/vnd.pubnub.objects.channel+json;version=1', }; } @@ -93,10 +82,14 @@ export class PatchChannelRequest } protected get body(): ArrayBuffer | string | undefined { - const { add, replace, remove, move, copy, test } = this.parameters; + const { data } = this.parameters; - // 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); + 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/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts index af5d9fee0..4fef6af38 100644 --- a/src/core/endpoints/data_sync/channel/update.ts +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -1,7 +1,10 @@ /** * Update Channel REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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. * * @internal */ @@ -11,6 +14,7 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -40,11 +44,11 @@ export class UpdateChannelRequest { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PUT }); + super({ method: TransportMethod.PATCH }); } operation(): RequestOperation { - return RequestOperation.PNUpdateChannelOperation; + return RequestOperation.PNUpdateDataSyncChannelOperation; } async parse(response: TransportResponse): Promise { @@ -56,9 +60,16 @@ export class UpdateChannelRequest 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 { @@ -68,7 +79,7 @@ export class UpdateChannelRequest 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/create.ts b/src/core/endpoints/data_sync/entity/create.ts index d98846203..42592ee7f 100644 --- a/src/core/endpoints/data_sync/entity/create.ts +++ b/src/core/endpoints/data_sync/entity/create.ts @@ -41,7 +41,7 @@ export class CreateEntityRequest } operation(): RequestOperation { - return RequestOperation.PNCreateEntityOperation; + return RequestOperation.PNCreateDataSyncEntityOperation; } async parse(response: TransportResponse): Promise { @@ -76,13 +76,14 @@ export class CreateEntityRequest } protected get body(): ArrayBuffer | string | undefined { - const { id, class: entityClass, data } = this.parameters; + const { id, class: entityClass, classLevel, data } = this.parameters; return JSON.stringify({ data: { ...(id !== undefined ? { id } : {}), entityClass, entityClassVersion: data.classVersion, + ...(classLevel !== undefined ? { entityClassLevel: classLevel } : {}), ...(data.status !== undefined ? { status: data.status } : {}), ...(data.payload !== undefined ? { payload: data.payload } : {}), }, diff --git a/src/core/endpoints/data_sync/entity/fetch-all.ts b/src/core/endpoints/data_sync/entity/get-all.ts similarity index 89% rename from src/core/endpoints/data_sync/entity/fetch-all.ts rename to src/core/endpoints/data_sync/entity/get-all.ts index fe738a30d..ed7a867e6 100644 --- a/src/core/endpoints/data_sync/entity/fetch-all.ts +++ b/src/core/endpoints/data_sync/entity/get-all.ts @@ -1,5 +1,5 @@ /** - * Fetch Entities REST API module. + * Get Entities REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchEntitiesParameters & { +type RequestParameters = DataSync.GetEntitiesParameters & { /** * PubNub REST API access key set. */ @@ -38,11 +38,11 @@ type RequestParameters = DataSync.FetchEntitiesParameters & { // endregion /** - * Fetch Entities request. + * Get Entities request. * * @internal */ -export class FetchEntitiesRequest extends AbstractRequest< +export class GetEntitiesRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class FetchEntitiesRequest { diff --git a/src/core/endpoints/data_sync/entity/fetch.ts b/src/core/endpoints/data_sync/entity/get.ts similarity index 83% rename from src/core/endpoints/data_sync/entity/fetch.ts rename to src/core/endpoints/data_sync/entity/get.ts index af75191fb..8a6409326 100644 --- a/src/core/endpoints/data_sync/entity/fetch.ts +++ b/src/core/endpoints/data_sync/entity/get.ts @@ -1,5 +1,5 @@ /** - * Fetch Entity REST API module. + * Get Entity REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchEntityParameters & { +type RequestParameters = DataSync.GetEntityParameters & { /** * PubNub REST API access key set. */ @@ -28,20 +28,17 @@ type RequestParameters = DataSync.FetchEntityParameters & { // endregion /** - * Fetch Entity request. + * Get Entity request. * * @internal */ -export class FetchEntityRequest extends AbstractRequest< - Response, - Response -> { +export class GetEntityRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } operation(): RequestOperation { - return RequestOperation.PNFetchEntityOperation; + return RequestOperation.PNGetDataSyncEntityOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/entity/remove.ts b/src/core/endpoints/data_sync/entity/remove.ts index a2b770107..1b8e13136 100644 --- a/src/core/endpoints/data_sync/entity/remove.ts +++ b/src/core/endpoints/data_sync/entity/remove.ts @@ -42,7 +42,7 @@ export class RemoveEntityRequest } operation(): RequestOperation { - return RequestOperation.PNRemoveEntityOperation; + return RequestOperation.PNRemoveDataSyncEntityOperation; } validate(): string | undefined { diff --git a/src/core/endpoints/data_sync/entity/patch.ts b/src/core/endpoints/data_sync/entity/set.ts similarity index 54% rename from src/core/endpoints/data_sync/entity/patch.ts rename to src/core/endpoints/data_sync/entity/set.ts index 2ea639467..5e58c07ae 100644 --- a/src/core/endpoints/data_sync/entity/patch.ts +++ b/src/core/endpoints/data_sync/entity/set.ts @@ -1,10 +1,8 @@ /** - * Patch Entity REST API module. + * Set Entity REST API module. * - * Partial update via JSON Patch (RFC 6902). - * 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. + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. * * @internal */ @@ -14,7 +12,6 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -26,7 +23,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.PatchEntityParameters & { +type RequestParameters = DataSync.SetEntityParameters & { /** * PubNub REST API access key set. */ @@ -35,20 +32,17 @@ type RequestParameters = DataSync.PatchEntityParameters & { // endregion /** - * Patch Entity request. + * Set Entity request. * * @internal */ -export class PatchEntityRequest extends AbstractRequest< - Response, - Response -> { +export class SetEntityRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PATCH }); + super({ method: TransportMethod.PUT }); } operation(): RequestOperation { - return RequestOperation.PNPatchEntityOperation; + return RequestOperation.PNSetDataSyncEntityOperation; } async parse(response: TransportResponse): Promise { @@ -60,16 +54,9 @@ export class PatchEntityRequest e validate(): string | undefined { if (!this.parameters.id) return 'Entity id cannot be empty'; - - 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'; + 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'; } protected get headers(): Record | undefined { @@ -79,7 +66,7 @@ export class PatchEntityRequest e return { ...headers, - 'Content-Type': 'application/json-patch+json', + 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1', }; } @@ -93,10 +80,14 @@ export class PatchEntityRequest e } protected get body(): ArrayBuffer | string | undefined { - const { add, replace, remove, move, copy, test } = this.parameters; + const { data } = this.parameters; - // 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); + 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/entity/update.ts b/src/core/endpoints/data_sync/entity/update.ts index 60084eb14..279e75d98 100644 --- a/src/core/endpoints/data_sync/entity/update.ts +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -1,8 +1,10 @@ /** * Update Entity REST API module. * - * Full resource replacement via PUT. - * Note: `entityClass` is immutable and cannot be changed via update. + * Partial update via JSON Patch (RFC 6902). + * 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. * * @internal */ @@ -12,6 +14,7 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -41,11 +44,11 @@ export class UpdateEntityRequest Response > { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PUT }); + super({ method: TransportMethod.PATCH }); } operation(): RequestOperation { - return RequestOperation.PNUpdateEntityOperation; + return RequestOperation.PNUpdateDataSyncEntityOperation; } async parse(response: TransportResponse): Promise { @@ -57,9 +60,16 @@ export class UpdateEntityRequest validate(): string | undefined { if (!this.parameters.id) return 'Entity id 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'; + + 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 { @@ -69,7 +79,7 @@ export class UpdateEntityRequest return { ...headers, - 'Content-Type': 'application/vnd.pubnub.objects.entity+json;version=1', + 'Content-Type': 'application/json-patch+json', }; } @@ -83,14 +93,10 @@ export class UpdateEntityRequest } protected get body(): ArrayBuffer | string | undefined { - const { data } = this.parameters; + const { add, replace, remove, move, copy, test } = this.parameters; - return JSON.stringify({ - data: { - entityClassVersion: data.classVersion, - ...(data.status !== undefined ? { status: data.status } : {}), - ...(data.payload !== undefined ? { payload: data.payload } : {}), - }, - }); + // 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/create.ts b/src/core/endpoints/data_sync/membership/create.ts index 82fef21e0..58805f69e 100644 --- a/src/core/endpoints/data_sync/membership/create.ts +++ b/src/core/endpoints/data_sync/membership/create.ts @@ -41,7 +41,7 @@ export class CreateMembershipRequest { diff --git a/src/core/endpoints/data_sync/membership/fetch-all.ts b/src/core/endpoints/data_sync/membership/get-all.ts similarity index 88% rename from src/core/endpoints/data_sync/membership/fetch-all.ts rename to src/core/endpoints/data_sync/membership/get-all.ts index dc6ac872a..538148d10 100644 --- a/src/core/endpoints/data_sync/membership/fetch-all.ts +++ b/src/core/endpoints/data_sync/membership/get-all.ts @@ -1,5 +1,5 @@ /** - * Fetch Memberships REST API module. + * Get Memberships REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchMembershipsParameters & { +type RequestParameters = DataSync.GetMembershipsParameters & { /** * PubNub REST API access key set. */ @@ -38,11 +38,11 @@ type RequestParameters = DataSync.FetchMembershipsParameters & { // endregion /** - * Fetch Memberships request. + * Get Memberships request. * * @internal */ -export class FetchMembershipsRequest extends AbstractRequest< +export class GetMembershipsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class FetchMembershipsRequest { diff --git a/src/core/endpoints/data_sync/membership/fetch.ts b/src/core/endpoints/data_sync/membership/get.ts similarity index 84% rename from src/core/endpoints/data_sync/membership/fetch.ts rename to src/core/endpoints/data_sync/membership/get.ts index 49f50bfb8..96ffd1d16 100644 --- a/src/core/endpoints/data_sync/membership/fetch.ts +++ b/src/core/endpoints/data_sync/membership/get.ts @@ -1,5 +1,5 @@ /** - * Fetch Membership REST API module. + * Get Membership REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchMembershipParameters & { +type RequestParameters = DataSync.GetMembershipParameters & { /** * PubNub REST API access key set. */ @@ -28,11 +28,11 @@ type RequestParameters = DataSync.FetchMembershipParameters & { // endregion /** - * Fetch Membership request. + * Get Membership request. * * @internal */ -export class FetchMembershipRequest extends AbstractRequest< +export class GetMembershipRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class FetchMembershipRequest { diff --git a/src/core/endpoints/data_sync/membership/remove.ts b/src/core/endpoints/data_sync/membership/remove.ts index 4924d2c4e..cb5842952 100644 --- a/src/core/endpoints/data_sync/membership/remove.ts +++ b/src/core/endpoints/data_sync/membership/remove.ts @@ -42,7 +42,7 @@ export class RemoveMembershipRequest extends AbstractRequest< +export class SetMembershipRequest extends AbstractRequest< Response, Response > { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PATCH }); + super({ method: TransportMethod.PUT }); } operation(): RequestOperation { - return RequestOperation.PNPatchMembershipOperation; + return RequestOperation.PNSetDataSyncMembershipOperation; } async parse(response: TransportResponse): Promise { @@ -60,16 +56,10 @@ export class PatchMembershipRequest 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'; + if (!this.parameters.userId) return 'User id cannot be empty'; + if (!this.parameters.channelId) return 'Channel id cannot be empty'; + if (!this.parameters.data) return 'Membership data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } protected get headers(): Record | undefined { @@ -79,7 +69,7 @@ export class PatchMembershipRequest JSON Pointer). The SDK - const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); - return JSON.stringify(jsonPatchOps); + return JSON.stringify({ + data: { + userId, + channelId, + relationshipClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/endpoints/data_sync/membership/update.ts b/src/core/endpoints/data_sync/membership/update.ts index 547dccc00..18c7ae86e 100644 --- a/src/core/endpoints/data_sync/membership/update.ts +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -1,7 +1,10 @@ /** * Update Membership REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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. * * @internal */ @@ -11,6 +14,7 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -40,11 +44,11 @@ export class UpdateMembershipRequest { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PUT }); + super({ method: TransportMethod.PATCH }); } operation(): RequestOperation { - return RequestOperation.PNUpdateMembershipOperation; + return RequestOperation.PNUpdateDataSyncMembershipOperation; } async parse(response: TransportResponse): Promise { @@ -56,10 +60,16 @@ export class UpdateMembershipRequest 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 { @@ -69,7 +79,7 @@ export class UpdateMembershipRequest 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/create.ts b/src/core/endpoints/data_sync/relationship/create.ts index 817eb3c10..647edac69 100644 --- a/src/core/endpoints/data_sync/relationship/create.ts +++ b/src/core/endpoints/data_sync/relationship/create.ts @@ -41,7 +41,7 @@ export class CreateRelationshipRequest { diff --git a/src/core/endpoints/data_sync/relationship/fetch-all.ts b/src/core/endpoints/data_sync/relationship/get-all.ts similarity index 89% rename from src/core/endpoints/data_sync/relationship/fetch-all.ts rename to src/core/endpoints/data_sync/relationship/get-all.ts index 9ad9d49a8..73e00fc0c 100644 --- a/src/core/endpoints/data_sync/relationship/fetch-all.ts +++ b/src/core/endpoints/data_sync/relationship/get-all.ts @@ -1,5 +1,5 @@ /** - * Fetch Relationships REST API module. + * Get Relationships REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchRelationshipsParameters & { +type RequestParameters = DataSync.GetRelationshipsParameters & { /** * PubNub REST API access key set. */ @@ -38,11 +38,11 @@ type RequestParameters = DataSync.FetchRelationshipsParameters & { // endregion /** - * Fetch Relationships request. + * Get Relationships request. * * @internal */ -export class FetchRelationshipsRequest extends AbstractRequest< +export class GetRelationshipsRequest extends AbstractRequest< Response, Response > { @@ -54,7 +54,7 @@ export class FetchRelationshipsRequest { diff --git a/src/core/endpoints/data_sync/relationship/fetch.ts b/src/core/endpoints/data_sync/relationship/get.ts similarity index 83% rename from src/core/endpoints/data_sync/relationship/fetch.ts rename to src/core/endpoints/data_sync/relationship/get.ts index 371be546d..3e544d194 100644 --- a/src/core/endpoints/data_sync/relationship/fetch.ts +++ b/src/core/endpoints/data_sync/relationship/get.ts @@ -1,5 +1,5 @@ /** - * Fetch Relationship REST API module. + * Get Relationship REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchRelationshipParameters & { +type RequestParameters = DataSync.GetRelationshipParameters & { /** * PubNub REST API access key set. */ @@ -28,11 +28,11 @@ type RequestParameters = DataSync.FetchRelationshipParameters & { // endregion /** - * Fetch Relationship request. + * Get Relationship request. * * @internal */ -export class FetchRelationshipRequest extends AbstractRequest< +export class GetRelationshipRequest extends AbstractRequest< Response, Response > { @@ -41,7 +41,7 @@ export class FetchRelationshipRequest { diff --git a/src/core/endpoints/data_sync/relationship/remove.ts b/src/core/endpoints/data_sync/relationship/remove.ts index 82c555f46..2d5f4e996 100644 --- a/src/core/endpoints/data_sync/relationship/remove.ts +++ b/src/core/endpoints/data_sync/relationship/remove.ts @@ -42,7 +42,7 @@ export class RemoveRelationshipRequest extends AbstractRequest< +export class SetRelationshipRequest extends AbstractRequest< Response, Response > { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PATCH }); + super({ method: TransportMethod.PUT }); } operation(): RequestOperation { - return RequestOperation.PNPatchRelationshipOperation; + return RequestOperation.PNSetDataSyncRelationshipOperation; } async parse(response: TransportResponse): Promise { @@ -61,16 +56,10 @@ export class PatchRelationshipRequest 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'; + if (!this.parameters.entityAId) return 'Entity A id cannot be empty'; + if (!this.parameters.entityBId) return 'Entity B id cannot be empty'; + if (!this.parameters.data) return 'Relationship data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } protected get headers(): Record | undefined { @@ -80,7 +69,7 @@ export class PatchRelationshipRequest JSON Pointer). The SDK - const jsonPatchOps = toJsonPatchOperations({ add, replace, remove, move, copy, test }); - return JSON.stringify(jsonPatchOps); + return JSON.stringify({ + data: { + entityAId, + entityBId, + relationshipClassVersion: data.classVersion, + ...(data.status !== undefined ? { status: data.status } : {}), + ...(data.payload !== undefined ? { payload: data.payload } : {}), + }, + }); } } diff --git a/src/core/endpoints/data_sync/relationship/update.ts b/src/core/endpoints/data_sync/relationship/update.ts index a0cf13585..4b4a9dc38 100644 --- a/src/core/endpoints/data_sync/relationship/update.ts +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -1,7 +1,11 @@ /** * Update Relationship REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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. * * @internal */ @@ -11,6 +15,7 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -40,11 +45,11 @@ export class UpdateRelationshipRequest { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PUT }); + super({ method: TransportMethod.PATCH }); } operation(): RequestOperation { - return RequestOperation.PNUpdateRelationshipOperation; + return RequestOperation.PNUpdateDataSyncRelationshipOperation; } async parse(response: TransportResponse): Promise { @@ -56,10 +61,16 @@ export class UpdateRelationshipRequest 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 { @@ -69,7 +80,7 @@ export class UpdateRelationshipRequest 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/create.ts b/src/core/endpoints/data_sync/user/create.ts index 65bbfc5b4..be2986c5a 100644 --- a/src/core/endpoints/data_sync/user/create.ts +++ b/src/core/endpoints/data_sync/user/create.ts @@ -41,7 +41,7 @@ export class CreateUserRequest ext } operation(): RequestOperation { - return RequestOperation.PNCreateUserOperation; + return RequestOperation.PNCreateDataSyncUserOperation; } async parse(response: TransportResponse): Promise { @@ -75,12 +75,14 @@ export class CreateUserRequest ext } protected get body(): ArrayBuffer | string | undefined { - const { id, data } = this.parameters; + const { id, class: entityClass, classLevel, data } = this.parameters; return JSON.stringify({ data: { ...(id !== undefined ? { id } : {}), + ...(entityClass !== undefined ? { entityClass } : {}), entityClassVersion: data.classVersion, + ...(classLevel !== undefined ? { entityClassLevel: classLevel } : {}), ...(data.status !== undefined ? { status: data.status } : {}), ...(data.payload !== undefined ? { payload: data.payload } : {}), }, diff --git a/src/core/endpoints/data_sync/user/fetch-all.ts b/src/core/endpoints/data_sync/user/get-all.ts similarity index 88% rename from src/core/endpoints/data_sync/user/fetch-all.ts rename to src/core/endpoints/data_sync/user/get-all.ts index 133a46f46..24ff6047c 100644 --- a/src/core/endpoints/data_sync/user/fetch-all.ts +++ b/src/core/endpoints/data_sync/user/get-all.ts @@ -1,5 +1,5 @@ /** - * Fetch Users REST API module. + * Get Users REST API module. * * @internal */ @@ -29,7 +29,7 @@ const DEFAULT_LIMIT = 20; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchUsersParameters & { +type RequestParameters = DataSync.GetUsersParameters & { /** * PubNub REST API access key set. */ @@ -38,14 +38,11 @@ type RequestParameters = DataSync.FetchUsersParameters & { // endregion /** - * Fetch Users request. + * Get Users request. * * @internal */ -export class FetchUsersRequest extends AbstractRequest< - Response, - Response -> { +export class GetUsersRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); @@ -54,7 +51,7 @@ export class FetchUsersRequest ext } operation(): RequestOperation { - return RequestOperation.PNFetchUsersOperation; + return RequestOperation.PNGetDataSyncUsersOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/user/fetch.ts b/src/core/endpoints/data_sync/user/get.ts similarity index 84% rename from src/core/endpoints/data_sync/user/fetch.ts rename to src/core/endpoints/data_sync/user/get.ts index f6df1654c..02ce5da17 100644 --- a/src/core/endpoints/data_sync/user/fetch.ts +++ b/src/core/endpoints/data_sync/user/get.ts @@ -1,5 +1,5 @@ /** - * Fetch User REST API module. + * Get User REST API module. * * @internal */ @@ -19,7 +19,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.FetchUserParameters & { +type RequestParameters = DataSync.GetUserParameters & { /** * PubNub REST API access key set. */ @@ -28,17 +28,17 @@ type RequestParameters = DataSync.FetchUserParameters & { // endregion /** - * Fetch User request. + * Get User request. * * @internal */ -export class FetchUserRequest extends AbstractRequest { +export class GetUserRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { super(); } operation(): RequestOperation { - return RequestOperation.PNFetchUserOperation; + return RequestOperation.PNGetDataSyncUserOperation; } async parse(response: TransportResponse): Promise { diff --git a/src/core/endpoints/data_sync/user/remove.ts b/src/core/endpoints/data_sync/user/remove.ts index de8c33b69..33b7d9206 100644 --- a/src/core/endpoints/data_sync/user/remove.ts +++ b/src/core/endpoints/data_sync/user/remove.ts @@ -42,7 +42,7 @@ export class RemoveUserRequest ext } operation(): RequestOperation { - return RequestOperation.PNRemoveUserOperation; + return RequestOperation.PNRemoveDataSyncUserOperation; } validate(): string | undefined { diff --git a/src/core/endpoints/data_sync/user/patch.ts b/src/core/endpoints/data_sync/user/set.ts similarity index 54% rename from src/core/endpoints/data_sync/user/patch.ts rename to src/core/endpoints/data_sync/user/set.ts index 73b2754a9..f3bad632d 100644 --- a/src/core/endpoints/data_sync/user/patch.ts +++ b/src/core/endpoints/data_sync/user/set.ts @@ -1,10 +1,7 @@ /** - * Patch User REST API module. + * Set User REST API module. * - * Partial update via JSON Patch (RFC 6902). - * 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. + * Full resource replacement via PUT. * * @internal */ @@ -14,7 +11,6 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -26,7 +22,7 @@ import { encodeString } from '../../../utils'; /** * Request configuration parameters. */ -type RequestParameters = DataSync.PatchUserParameters & { +type RequestParameters = DataSync.SetUserParameters & { /** * PubNub REST API access key set. */ @@ -35,17 +31,17 @@ type RequestParameters = DataSync.PatchUserParameters & { // endregion /** - * Patch User request. + * Set User request. * * @internal */ -export class PatchUserRequest extends AbstractRequest { +export class SetUserRequest extends AbstractRequest { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PATCH }); + super({ method: TransportMethod.PUT }); } operation(): RequestOperation { - return RequestOperation.PNPatchUserOperation; + return RequestOperation.PNSetDataSyncUserOperation; } async parse(response: TransportResponse): Promise { @@ -57,16 +53,9 @@ export class PatchUserRequest exten validate(): string | undefined { if (!this.parameters.id) return 'User id cannot be empty'; - - 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'; + 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'; } protected get headers(): Record | undefined { @@ -76,7 +65,7 @@ export class PatchUserRequest exten return { ...headers, - 'Content-Type': 'application/json-patch+json', + 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1', }; } @@ -90,10 +79,14 @@ export class PatchUserRequest exten } protected get body(): ArrayBuffer | string | undefined { - const { add, replace, remove, move, copy, test } = this.parameters; + const { data } = this.parameters; - // 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); + 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/user/update.ts b/src/core/endpoints/data_sync/user/update.ts index 7f0c2e103..90cac7e57 100644 --- a/src/core/endpoints/data_sync/user/update.ts +++ b/src/core/endpoints/data_sync/user/update.ts @@ -1,7 +1,10 @@ /** * Update User REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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. * * @internal */ @@ -11,6 +14,7 @@ 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 { toJsonPatchOperations } from '../../../types/api/data-sync'; import { KeySet } from '../../../types/api'; import { encodeString } from '../../../utils'; @@ -40,11 +44,11 @@ export class UpdateUserRequest ext Response > { constructor(private readonly parameters: RequestParameters) { - super({ method: TransportMethod.PUT }); + super({ method: TransportMethod.PATCH }); } operation(): RequestOperation { - return RequestOperation.PNUpdateUserOperation; + return RequestOperation.PNUpdateDataSyncUserOperation; } async parse(response: TransportResponse): Promise { @@ -56,9 +60,16 @@ export class UpdateUserRequest ext validate(): string | undefined { if (!this.parameters.id) return 'User id cannot be empty'; - 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'; + + 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 { @@ -68,7 +79,7 @@ export class UpdateUserRequest ext return { ...headers, - 'Content-Type': 'application/vnd.pubnub.objects.user+json;version=1', + 'Content-Type': 'application/json-patch+json', }; } @@ -82,14 +93,10 @@ export class UpdateUserRequest ext } protected get body(): ArrayBuffer | string | undefined { - const { data } = this.parameters; + const { add, replace, remove, move, copy, test } = this.parameters; - return JSON.stringify({ - data: { - entityClassVersion: data.classVersion, - ...(data.status !== undefined ? { status: data.status } : {}), - ...(data.payload !== undefined ? { payload: data.payload } : {}), - }, - }); + // 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/subscribe.ts b/src/core/endpoints/subscribe.ts index 214607284..d2f6222fc 100644 --- a/src/core/endpoints/subscribe.ts +++ b/src/core/endpoints/subscribe.ts @@ -436,21 +436,29 @@ type DataSyncEventName = 'create' | 'update' | 'delete'; type DataSyncObjectType = 'entity' | 'relationship'; /** - * Normalized DataSync object kind derived from the wire `className`. + * Scope of the class definition a DataSync object belongs to. + * + * `Global` identifies the built-in classes provided by the service (`User`, `Channel`, + * `Membership`); `SubKey` identifies classes defined by the developer on their own key set. + */ +export type DataSyncClassLevel = 'Global' | 'SubKey'; + +/** + * Normalized DataSync object kind. * * 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. + * class-name strings. Falls back to the raw wire {@link DataSyncObjectType} for developer-defined + * classes. */ export type DataSyncNormalizedType = 'user' | 'channel' | 'membership' | 'entity' | 'relationship'; /** - * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * Reserved DataSync system class names (lower-cased) → 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`). + * Only consulted for classes the service marks as `Global` (see {@link DataSyncClassLevel}), so a + * developer-defined class which happens to share one of these names is not mistaken for a typed + * resource. Keys are compared case-insensitively. * * @internal */ @@ -458,13 +466,14 @@ 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). + * + * Mirrors the object as sent by the service. Class identity is not repeated here: it is reported once + * on the event itself as {@link DataSyncData.className} / {@link DataSyncData.classLevel} / + * {@link DataSyncData.classVersion}. */ export type DataSyncEntityData = { /** @@ -501,41 +510,28 @@ export type DataSyncEntityData = { * 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). + * + * Class identity is not repeated here: it is reported once on the event itself as + * {@link DataSyncData.className} / {@link DataSyncData.classLevel} / {@link DataSyncData.classVersion}. */ -export type DataSyncRelationshipData = Omit & { +export type DataSyncRelationshipData = DataSyncEntityData & { /** * First entity id in the relationship. + * + * For a membership this is the channel id. */ entityAId?: string; /** * Second entity id in the relationship. + * + * For a membership this is the user id. */ 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; }; /** @@ -580,18 +576,23 @@ export type DataSyncData = { /** * 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. + * The built-in `User` / `Channel` / `Membership` classes map to `'user'` / `'channel'` / + * `'membership'`; developer-defined classes fall 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`). + * Object class name. */ className?: string; + /** + * Scope of the class definition: `Global` for the built-in classes (`User` / `Channel` / + * `Membership`), `SubKey` for classes defined by the developer on their own key set. + */ + classLevel?: DataSyncClassLevel; + /** * Version of the object class schema (parsed from the wire `classVersion`). */ @@ -617,6 +618,7 @@ type DataSyncServiceData = { source?: string; type?: DataSyncObjectType; className?: string; + classLevel?: string; classVersion?: string | number; }; data?: Record; @@ -1061,33 +1063,29 @@ 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. + // Wire `className` is a bare class name (`User`, `Membership`, `Customer`); the `:`-splitting below + // is only there to keep tolerating the retired positional composite (`User::` / `::Customer`). 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 classLevel = metadata.classLevel as DataSyncClassLevel | undefined; + + // `classLevel` authoritatively separates the built-in classes from developer-defined ones, so a + // developer class named `User` / `Channel` / `Membership` is not mistaken for a typed resource. + // When it is absent (service predating the field) fall back to the legacy positional heuristic, + // where the system class was the first segment. + const systemClass = classLevel === undefined ? classSegments[0] : classLevel === 'Global' ? className : 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; + // `data` mirrors the object as sent by the service; class identity is reported once, on the event. 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; - } + if (metadata.event === 'delete') data = { id: raw.id as string, deletedAt: raw.deletedAt as string | undefined }; + else if (metadata.type === 'relationship') data = { ...raw } as DataSyncRelationshipData; + else data = { ...raw } as DataSyncEntityData; return { channel, @@ -1100,6 +1098,7 @@ export class BaseSubscribeRequest extends AbstractRequest, + public getEntity( + parameters: DataSync.GetEntityParameters, + callback: ResultCallback, ): void; /** - * Fetch a specific Entity. + * Get a specific Entity. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch entity response. + * @returns Asynchronous get entity response. */ - public async fetchEntity(parameters: DataSync.FetchEntityParameters): Promise; + public async getEntity(parameters: DataSync.GetEntityParameters): Promise; /** - * Fetch a specific Entity. + * Get a specific Entity. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch entity response or `void` in case if `callback` provided. + * @returns Asynchronous get entity response or `void` in case if `callback` provided. */ - async fetchEntity( - parameters: DataSync.FetchEntityParameters, - callback?: ResultCallback, - ): Promise { + async getEntity( + parameters: DataSync.GetEntityParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Entity with parameters:', + details: 'Get Entity with parameters:', })); - const request = new FetchEntityRequest({ ...parameters, keySet: this.keySet }); + const request = new GetEntityRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Fetch Entities + // region Get Entities /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get a paginated list of Entities for a given Entity Class. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchEntities( - parameters: DataSync.FetchEntitiesParameters, - callback: ResultCallback, + public getEntities( + parameters: DataSync.GetEntitiesParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get a paginated list of Entities for a given Entity Class. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch entities response. + * @returns Asynchronous get entities response. */ - public async fetchEntities(parameters: DataSync.FetchEntitiesParameters): Promise; + public async getEntities(parameters: DataSync.GetEntitiesParameters): Promise; /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get a paginated list of Entities for a given Entity Class. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch entities response or `void` in case if `callback` provided. + * @returns Asynchronous get entities response or `void` in case if `callback` provided. */ - async fetchEntities( - parameters: DataSync.FetchEntitiesParameters, - callback?: ResultCallback, - ): Promise { + async getEntities( + parameters: DataSync.GetEntitiesParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Entities with parameters:', + details: 'Get Entities with parameters:', })); - const request = new FetchEntitiesRequest({ ...parameters, keySet: this.keySet }); + const request = new GetEntitiesRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Update Entity + // region Set Entity /** - * Update an Entity (full replacement via PUT). + * Set an Entity (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public updateEntity( - parameters: DataSync.UpdateEntityParameters, - callback: ResultCallback, + public setEntity( + parameters: DataSync.SetEntityParameters, + callback: ResultCallback, ): void; /** - * Update an Entity (full replacement via PUT). + * Set an Entity (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update entity response. + * @returns Asynchronous set entity response. */ - public async updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; + public async setEntity(parameters: DataSync.SetEntityParameters): Promise; /** - * Update an Entity (full replacement via PUT). + * Set 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. + * @returns Asynchronous set entity response or `void` in case if `callback` provided. */ - async updateEntity( - parameters: DataSync.UpdateEntityParameters, - callback?: ResultCallback, - ): Promise { + async setEntity( + parameters: DataSync.SetEntityParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Update Entity with parameters:', + details: 'Set Entity with parameters:', })); - const request = new UpdateEntityRequest({ ...parameters, keySet: this.keySet }); + const request = new SetEntityRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Patch Entity + // region Update Entity /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Update 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, + public updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback: ResultCallback, ): void; /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update entity response. */ - public async patchEntity(parameters: DataSync.PatchEntityParameters): Promise; + public async updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update entity response or `void` in case if `callback` provided. */ - async patchEntity( - parameters: DataSync.PatchEntityParameters, - callback?: ResultCallback, - ): Promise { + async updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Patch Entity with parameters:', + details: 'Update Entity with parameters:', })); - const request = new PatchEntityRequest({ ...parameters, keySet: this.keySet }); + const request = new UpdateEntityRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -441,202 +441,202 @@ export default class PubNubDataSync { } // endregion - // region Fetch Relationship + // region Get Relationship /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchRelationship( - parameters: DataSync.FetchRelationshipParameters, - callback: ResultCallback, + public getRelationship( + parameters: DataSync.GetRelationshipParameters, + callback: ResultCallback, ): void; /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch relationship response. + * @returns Asynchronous get relationship response. */ - public async fetchRelationship( - parameters: DataSync.FetchRelationshipParameters, - ): Promise; + public async getRelationship( + parameters: DataSync.GetRelationshipParameters, + ): Promise; /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch relationship response or `void` in case if `callback` provided. + * @returns Asynchronous get relationship response or `void` in case if `callback` provided. */ - async fetchRelationship( - parameters: DataSync.FetchRelationshipParameters, - callback?: ResultCallback, - ): Promise { + async getRelationship( + parameters: DataSync.GetRelationshipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Relationship with parameters:', + details: 'Get Relationship with parameters:', })); - const request = new FetchRelationshipRequest({ ...parameters, keySet: this.keySet }); + const request = new GetRelationshipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Fetch Relationships + // region Get Relationships /** - * Fetch a paginated list of Relationships. + * Get a paginated list of Relationships. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchRelationships( - parameters: DataSync.FetchRelationshipsParameters, - callback: ResultCallback, + public getRelationships( + parameters: DataSync.GetRelationshipsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Relationships. + * Get a paginated list of Relationships. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch relationships response. + * @returns Asynchronous get relationships response. */ - public async fetchRelationships( - parameters: DataSync.FetchRelationshipsParameters, - ): Promise; + public async getRelationships( + parameters: DataSync.GetRelationshipsParameters, + ): Promise; /** - * Fetch a paginated list of Relationships. + * Get a paginated list of Relationships. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch relationships response or `void` in case if `callback` provided. + * @returns Asynchronous get relationships response or `void` in case if `callback` provided. */ - async fetchRelationships( - parameters: DataSync.FetchRelationshipsParameters, - callback?: ResultCallback, - ): Promise { + async getRelationships( + parameters: DataSync.GetRelationshipsParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Relationships with parameters:', + details: 'Get Relationships with parameters:', })); - const request = new FetchRelationshipsRequest({ ...parameters, keySet: this.keySet }); + const request = new GetRelationshipsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Update Relationship + // region Set Relationship /** - * Update a Relationship (full replacement via PUT). + * Set a Relationship (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public updateRelationship( - parameters: DataSync.UpdateRelationshipParameters, - callback: ResultCallback, + public setRelationship( + parameters: DataSync.SetRelationshipParameters, + callback: ResultCallback, ): void; /** - * Update a Relationship (full replacement via PUT). + * Set a Relationship (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update relationship response. + * @returns Asynchronous set relationship response. */ - public async updateRelationship( - parameters: DataSync.UpdateRelationshipParameters, - ): Promise; + public async setRelationship( + parameters: DataSync.SetRelationshipParameters, + ): Promise; /** - * Update a Relationship (full replacement via PUT). + * Set 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. + * @returns Asynchronous set relationship response or `void` in case if `callback` provided. */ - async updateRelationship( - parameters: DataSync.UpdateRelationshipParameters, - callback?: ResultCallback, - ): Promise { + async setRelationship( + parameters: DataSync.SetRelationshipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Update Relationship with parameters:', + details: 'Set Relationship with parameters:', })); - const request = new UpdateRelationshipRequest({ ...parameters, keySet: this.keySet }); + const request = new SetRelationshipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Patch Relationship + // region Update Relationship /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Update 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, + public updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback: ResultCallback, ): void; /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update relationship response. */ - public async patchRelationship( - parameters: DataSync.PatchRelationshipParameters, - ): Promise; + public async updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + ): Promise; /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. */ - async patchRelationship( - parameters: DataSync.PatchRelationshipParameters, - callback?: ResultCallback, - ): Promise { + async updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Patch Relationship with parameters:', + details: 'Update Relationship with parameters:', })); - const request = new PatchRelationshipRequest({ ...parameters, keySet: this.keySet }); + const request = new UpdateRelationshipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -746,205 +746,196 @@ export default class PubNubDataSync { } // endregion - // region Fetch User + // region Get User /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchUser( - parameters: DataSync.FetchUserParameters, - callback: ResultCallback, - ): void; + public getUser(parameters: DataSync.GetUserParameters, callback: ResultCallback): void; /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch user response. + * @returns Asynchronous get user response. */ - public async fetchUser(parameters: DataSync.FetchUserParameters): Promise; + public async getUser(parameters: DataSync.GetUserParameters): Promise; /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch user response or `void` in case if `callback` provided. + * @returns Asynchronous get user response or `void` in case if `callback` provided. */ - async fetchUser( - parameters: DataSync.FetchUserParameters, - callback?: ResultCallback, - ): Promise { + async getUser( + parameters: DataSync.GetUserParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch User with parameters:', + details: 'Get User with parameters:', })); - const request = new FetchUserRequest({ ...parameters, keySet: this.keySet }); + const request = new GetUserRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Fetch Users + // region Get Users /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param callback - Request completion handler callback. */ - public fetchUsers(callback: ResultCallback): void; + public getUsers(callback: ResultCallback): void; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchUsers( - parameters: DataSync.FetchUsersParameters, - callback: ResultCallback, - ): void; + public getUsers(parameters: DataSync.GetUsersParameters, callback: ResultCallback): void; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous fetch users response. + * @returns Asynchronous get users response. */ - public async fetchUsers(parameters?: DataSync.FetchUsersParameters): Promise; + public async getUsers(parameters?: DataSync.GetUsersParameters): Promise; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param [parametersOrCallback] - Request configuration parameters or callback from overload. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch users response or `void` in case if `callback` provided. + * @returns Asynchronous get users response or `void` in case if `callback` provided. */ - async fetchUsers( - parametersOrCallback?: DataSync.FetchUsersParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.FetchUsersParameters = + async getUsers( + parametersOrCallback?: DataSync.GetUsersParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetUsersParameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Users with parameters:', + details: 'Get Users with parameters:', })); - const request = new FetchUsersRequest({ ...parameters, keySet: this.keySet }); + const request = new GetUsersRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Update User + // region Set User /** - * Update a User (full replacement via PUT). + * Set 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; + public setUser(parameters: DataSync.SetUserParameters, callback: ResultCallback): void; /** - * Update a User (full replacement via PUT). + * Set a User (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update user response. + * @returns Asynchronous set user response. */ - public async updateUser(parameters: DataSync.UpdateUserParameters): Promise; + public async setUser(parameters: DataSync.SetUserParameters): Promise; /** - * Update a User (full replacement via PUT). + * Set 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. + * @returns Asynchronous set user response or `void` in case if `callback` provided. */ - async updateUser( - parameters: DataSync.UpdateUserParameters, - callback?: ResultCallback, - ): Promise { + async setUser( + parameters: DataSync.SetUserParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Update User with parameters:', + details: 'Set User with parameters:', })); - const request = new UpdateUserRequest({ ...parameters, keySet: this.keySet }); + const request = new SetUserRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Patch User + // region Update User /** - * Patch a User (partial update via JSON Patch RFC 6902). + * Update 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, + public updateUser( + parameters: DataSync.UpdateUserParameters, + callback: ResultCallback, ): void; /** - * Patch a User (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update user response. */ - public async patchUser(parameters: DataSync.PatchUserParameters): Promise; + public async updateUser(parameters: DataSync.UpdateUserParameters): Promise; /** - * Patch a User (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update user response or `void` in case if `callback` provided. */ - async patchUser( - parameters: DataSync.PatchUserParameters, - callback?: ResultCallback, - ): Promise { + async updateUser( + parameters: DataSync.UpdateUserParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Patch User with parameters:', + details: 'Update User with parameters:', })); - const request = new PatchUserRequest({ ...parameters, keySet: this.keySet }); + const request = new UpdateUserRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -1052,205 +1043,205 @@ export default class PubNubDataSync { } // endregion - // region Fetch Channel + // region Get Channel /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchChannel( - parameters: DataSync.FetchChannelParameters, - callback: ResultCallback, + public getChannel( + parameters: DataSync.GetChannelParameters, + callback: ResultCallback, ): void; /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch channel response. + * @returns Asynchronous get channel response. */ - public async fetchChannel(parameters: DataSync.FetchChannelParameters): Promise; + public async getChannel(parameters: DataSync.GetChannelParameters): Promise; /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch channel response or `void` in case if `callback` provided. + * @returns Asynchronous get channel response or `void` in case if `callback` provided. */ - async fetchChannel( - parameters: DataSync.FetchChannelParameters, - callback?: ResultCallback, - ): Promise { + async getChannel( + parameters: DataSync.GetChannelParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Channel with parameters:', + details: 'Get Channel with parameters:', })); - const request = new FetchChannelRequest({ ...parameters, keySet: this.keySet }); + const request = new GetChannelRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Fetch Channels + // region Get Channels /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param callback - Request completion handler callback. */ - public fetchChannels(callback: ResultCallback): void; + public getChannels(callback: ResultCallback): void; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchChannels( - parameters: DataSync.FetchChannelsParameters, - callback: ResultCallback, + public getChannels( + parameters: DataSync.GetChannelsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous fetch channels response. + * @returns Asynchronous get channels response. */ - public async fetchChannels(parameters?: DataSync.FetchChannelsParameters): Promise; + public async getChannels(parameters?: DataSync.GetChannelsParameters): Promise; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param [parametersOrCallback] - Request configuration parameters or callback from overload. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch channels response or `void` in case if `callback` provided. + * @returns Asynchronous get channels response or `void` in case if `callback` provided. */ - async fetchChannels( - parametersOrCallback?: DataSync.FetchChannelsParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.FetchChannelsParameters = + async getChannels( + parametersOrCallback?: DataSync.GetChannelsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetChannelsParameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Channels with parameters:', + details: 'Get Channels with parameters:', })); - const request = new FetchChannelsRequest({ ...parameters, keySet: this.keySet }); + const request = new GetChannelsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Update Channel + // region Set Channel /** - * Update a Channel (full replacement via PUT). + * Set a Channel (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public updateChannel( - parameters: DataSync.UpdateChannelParameters, - callback: ResultCallback, + public setChannel( + parameters: DataSync.SetChannelParameters, + callback: ResultCallback, ): void; /** - * Update a Channel (full replacement via PUT). + * Set a Channel (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update channel response. + * @returns Asynchronous set channel response. */ - public async updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; + public async setChannel(parameters: DataSync.SetChannelParameters): Promise; /** - * Update a Channel (full replacement via PUT). + * Set 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. + * @returns Asynchronous set channel response or `void` in case if `callback` provided. */ - async updateChannel( - parameters: DataSync.UpdateChannelParameters, - callback?: ResultCallback, - ): Promise { + async setChannel( + parameters: DataSync.SetChannelParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Update Channel with parameters:', + details: 'Set Channel with parameters:', })); - const request = new UpdateChannelRequest({ ...parameters, keySet: this.keySet }); + const request = new SetChannelRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Patch Channel + // region Update Channel /** - * Patch a Channel (partial update via JSON Patch RFC 6902). + * Update 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, + public updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback: ResultCallback, ): void; /** - * Patch a Channel (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update channel response. */ - public async patchChannel(parameters: DataSync.PatchChannelParameters): Promise; + public async updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; /** - * Patch a Channel (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update channel response or `void` in case if `callback` provided. */ - async patchChannel( - parameters: DataSync.PatchChannelParameters, - callback?: ResultCallback, - ): Promise { + async updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Patch Channel with parameters:', + details: 'Update Channel with parameters:', })); - const request = new PatchChannelRequest({ ...parameters, keySet: this.keySet }); + const request = new UpdateChannelRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -1360,213 +1351,207 @@ export default class PubNubDataSync { } // endregion - // region Fetch Membership + // region Get Membership /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchMembership( - parameters: DataSync.FetchMembershipParameters, - callback: ResultCallback, + public getMembership( + parameters: DataSync.GetMembershipParameters, + callback: ResultCallback, ): void; /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous fetch membership response. + * @returns Asynchronous get membership response. */ - public async fetchMembership( - parameters: DataSync.FetchMembershipParameters, - ): Promise; + public async getMembership(parameters: DataSync.GetMembershipParameters): Promise; /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch membership response or `void` in case if `callback` provided. + * @returns Asynchronous get membership response or `void` in case if `callback` provided. */ - async fetchMembership( - parameters: DataSync.FetchMembershipParameters, - callback?: ResultCallback, - ): Promise { + async getMembership( + parameters: DataSync.GetMembershipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Membership with parameters:', + details: 'Get Membership with parameters:', })); - const request = new FetchMembershipRequest({ ...parameters, keySet: this.keySet }); + const request = new GetMembershipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Fetch Memberships + // region Get Memberships /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param callback - Request completion handler callback. */ - public fetchMemberships(callback: ResultCallback): void; + public getMemberships(callback: ResultCallback): void; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public fetchMemberships( - parameters: DataSync.FetchMembershipsParameters, - callback: ResultCallback, + public getMemberships( + parameters: DataSync.GetMembershipsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous fetch memberships response. + * @returns Asynchronous get memberships response. */ - public async fetchMemberships( - parameters?: DataSync.FetchMembershipsParameters, - ): Promise; + public async getMemberships(parameters?: DataSync.GetMembershipsParameters): Promise; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param [parametersOrCallback] - Request configuration parameters or callback from overload. * @param [callback] - Request completion handler callback. * - * @returns Asynchronous fetch memberships response or `void` in case if `callback` provided. + * @returns Asynchronous get memberships response or `void` in case if `callback` provided. */ - async fetchMemberships( - parametersOrCallback?: DataSync.FetchMembershipsParameters | ResultCallback, - callback?: ResultCallback, - ): Promise { - const parameters: DataSync.FetchMembershipsParameters = + async getMemberships( + parametersOrCallback?: DataSync.GetMembershipsParameters | ResultCallback, + callback?: ResultCallback, + ): Promise { + const parameters: DataSync.GetMembershipsParameters = parametersOrCallback && typeof parametersOrCallback !== 'function' ? parametersOrCallback : {}; callback ??= typeof parametersOrCallback === 'function' ? parametersOrCallback : undefined; this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Fetch Memberships with parameters:', + details: 'Get Memberships with parameters:', })); - const request = new FetchMembershipsRequest({ ...parameters, keySet: this.keySet }); + const request = new GetMembershipsRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Update Membership + // region Set Membership /** - * Update a Membership (full replacement via PUT). + * Set a Membership (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - public updateMembership( - parameters: DataSync.UpdateMembershipParameters, - callback: ResultCallback, + public setMembership( + parameters: DataSync.SetMembershipParameters, + callback: ResultCallback, ): void; /** - * Update a Membership (full replacement via PUT). + * Set a Membership (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update membership response. + * @returns Asynchronous set membership response. */ - public async updateMembership( - parameters: DataSync.UpdateMembershipParameters, - ): Promise; + public async setMembership(parameters: DataSync.SetMembershipParameters): Promise; /** - * Update a Membership (full replacement via PUT). + * Set 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. + * @returns Asynchronous set membership response or `void` in case if `callback` provided. */ - async updateMembership( - parameters: DataSync.UpdateMembershipParameters, - callback?: ResultCallback, - ): Promise { + async setMembership( + parameters: DataSync.SetMembershipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Update Membership with parameters:', + details: 'Set Membership with parameters:', })); - const request = new UpdateMembershipRequest({ ...parameters, keySet: this.keySet }); + const request = new SetMembershipRequest({ ...parameters, keySet: this.keySet }); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); } // endregion - // region Patch Membership + // region Update Membership /** - * Patch a Membership (partial update via JSON Patch RFC 6902). + * Update 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, + public updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback: ResultCallback, ): void; /** - * Patch a Membership (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update membership response. */ - public async patchMembership( - parameters: DataSync.PatchMembershipParameters, - ): Promise; + public async updateMembership( + parameters: DataSync.UpdateMembershipParameters, + ): Promise; /** - * Patch a Membership (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update membership response or `void` in case if `callback` provided. */ - async patchMembership( - parameters: DataSync.PatchMembershipParameters, - callback?: ResultCallback, - ): Promise { + async updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback?: ResultCallback, + ): Promise { this.logger.debug('PubNub', () => ({ messageType: 'object', message: { ...parameters }, - details: 'Patch Membership with parameters:', + details: 'Update Membership with parameters:', })); - const request = new PatchMembershipRequest({ ...parameters, keySet: this.keySet }); + const request = new UpdateMembershipRequest({ ...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 d931e47da..a201163db 100644 --- a/src/core/types/api/access-manager.ts +++ b/src/core/types/api/access-manager.ts @@ -20,6 +20,14 @@ export type ChannelTokenPermissions = { */ write?: boolean; + /** + * Whether `create` operations are permitted for corresponding level or not. + * + * Used by DataSync `Channel` grants (a DataSync Channel is an entity, granted through the reused + * `channels` scope). Ignored for classic messaging channels. + */ + create?: boolean; + /** * Whether `get` operations are permitted for corresponding level or not. */ @@ -70,6 +78,14 @@ export type ChannelGroupTokenPermissions = { * Uuid-specific token permissions. */ export type UuidTokenPermissions = { + /** + * Whether `create` operations are permitted for corresponding level or not. + * + * Used by DataSync `User` grants (a DataSync User is an entity, granted through the reused + * `users` / `uuids` scope). Ignored for App Context UUID-metadata grants. + */ + create?: boolean; + /** * Whether `get` operations are permitted for corresponding level or not. */ @@ -89,7 +105,7 @@ export type UuidTokenPermissions = { /** * User-specific token permissions. */ -type UserTokenPermissions = UuidTokenPermissions; +export type UserTokenPermissions = UuidTokenPermissions; /** * DataSync entity-level token permissions. @@ -268,8 +284,20 @@ export type GrantTokenParameters = { * Object containing resource permissions. */ resources?: { + /** + * Object containing `user` permissions. + * + * Preferred DataSync terminology for granting permissions on `User` resources (create / get / + * update / delete). Serialized to the same wire scope as {@link uuids}; may be combined with + * `channels`, `groups`, `uuids`, and `dataSync` in a single grant. + */ + users?: Record; + /** * Object containing `uuid` metadata permissions. + * + * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. + * `uuids` remains for App Context UUID-metadata permissions. */ uuids?: Record; @@ -293,9 +321,20 @@ export type GrantTokenParameters = { * Object containing permissions to multiple resources specified by a RegEx pattern. */ patterns?: { + /** + * Object containing `user` permissions to apply to all `users` matching the RegEx pattern. + * + * Preferred DataSync terminology for granting permissions on `User` resources. Serialized to the + * same wire scope as {@link uuids}; may be combined with `channels`, `groups`, `uuids`, and + * `dataSync`. + */ + users?: Record; + /** * Object containing `uuid` metadata permissions to apply to all `uuids` matching the RegEx * pattern. + * + * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. */ uuids?: Record; diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index ceb8f84ed..0f6f054ac 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -107,6 +107,14 @@ type PagedRequestParameters = { */ export type DataSyncSort = string | Record; +/** + * Class hierarchy level used to disambiguate classes that share a name at different levels. + * + * `Global` targets a class provided by the service; `SubKey` targets one defined on the key set. + * Mirrors the event-side `DataSyncClassLevel` reported on subscribe messages. + */ +export type ClassLevel = 'Global' | 'SubKey'; + /** * Serialize a {@link DataSyncSort} into the query value the service expects. * @@ -162,7 +170,7 @@ type DataSyncPagedResponse = { /** * JSON Patch operation as defined by RFC 6902. * - * Internal wire format. Developers use `add`/`replace`/`remove`/`move`/`copy`/`test` with dot + * Internal request 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`. * @@ -187,7 +195,7 @@ export type PatchMovePath = { }; /** - * User-friendly JSON Patch input (dot notation), converted to RFC 6902 operations on the wire. + * User-friendly JSON Patch input (dot notation), converted to RFC 6902 operations before sending. * * @internal */ @@ -224,7 +232,7 @@ export function toJsonPointer(dotPath: string): string { } /** - * Convert user-friendly dot-notation patch input to JSON Patch operations (wire format). + * Convert user-friendly dot-notation patch input to JSON Patch operations (request format). * * - Each key in `add` becomes an "add" operation. * - Each key in `replace` becomes a "replace" operation. @@ -290,7 +298,12 @@ export function toJsonPatchOperations(input: JsonPatchInput): JsonPatchOperation * lifetime is grouped here under `data`. */ export type CreateEntityData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * Stored on the entity as `entityClassVersion` — use that name to address it in + * {@link UpdateEntityParameters} patch paths. + */ classVersion: number; /** Optional lifecycle status. */ @@ -304,10 +317,10 @@ export type CreateEntityData = { * Entity data properties for update (PUT) requests. * * The mutable, versioned payload of an entity. `id` lives at the top level of - * {@link UpdateEntityParameters}. `entityClass` is immutable after creation and therefore + * {@link SetEntityParameters}. `entityClass` is immutable after creation and therefore * has no place in updates. */ -export type UpdateEntityData = { +export type SetEntityData = { /** Version of the entity class schema. */ classVersion: number; @@ -362,9 +375,24 @@ export type CreateEntityParameters = { */ id?: string; - /** Entity class this entity belongs to. Set at creation time and immutable afterward. */ + /** + * Entity class this entity belongs to. Set at creation time and immutable afterward. + * + * Stored on the entity as `entityClass` — the name it carries in responses, in real-time event + * payloads, and in {@link UpdateEntityParameters} patch paths (immutable, so never a patch + * target). + */ class: string; + /** + * Class hierarchy level of `class`. Set at creation time and immutable afterward. + * + * Omit to let the service apply its default. + * + * Stored on the entity as `entityClassLevel`. + */ + classLevel?: ClassLevel; + /** * Mutable, versioned entity data (class version, status, and payload). * @@ -378,7 +406,7 @@ export type CreateEntityParameters = { /** * Get Entity request parameters. */ -export type FetchEntityParameters = { +export type GetEntityParameters = { /** Entity ID. */ id: string; }; @@ -388,7 +416,7 @@ export type FetchEntityParameters = { * * `entityClass` is required — entities are always listed within the context of their class. */ -export type FetchEntitiesParameters = PagedRequestParameters & { +export type GetEntitiesParameters = PagedRequestParameters & { /** Entity class name to filter by (required). */ entityClass: string; @@ -407,17 +435,17 @@ export type FetchEntitiesParameters = PagedRequestParameters & { }; /** - * Update Entity request parameters (full replacement via PUT). + * Set Entity request parameters (full replacement via PUT). * * `entityClass` is immutable after creation — only `classVersion`, `status`, * and `payload` can be updated. */ -export type UpdateEntityParameters = { +export type SetEntityParameters = { /** Entity ID. */ id: string; /** Complete, mutable entity data for replacement (excludes immutable `entityClass`). */ - data: UpdateEntityData; + data: SetEntityData; /** * ETag for optimistic concurrency control. @@ -427,14 +455,20 @@ export type UpdateEntityParameters = { }; /** - * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * Update Entity request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to + * JSON Patch operations. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * Patch paths address the entity's **stored property names** — the same keys that come back in + * responses and real-time events — not the grouped parameter names used by + * {@link CreateEntityParameters}. So the class version is `entityClassVersion` (not + * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ -export type PatchEntityParameters = { +export type UpdateEntityParameters = { /** Entity ID. */ id: string; @@ -548,16 +582,16 @@ export type RemoveEntityParameters = { export type CreateEntityResponse = DataSyncEntityResponse; /** Response for getting a single entity. */ -export type FetchEntityResponse = DataSyncEntityResponse; +export type GetEntityResponse = DataSyncEntityResponse; /** Response for listing entities. */ -export type FetchEntitiesResponse = DataSyncPagedResponse; +export type GetEntitiesResponse = DataSyncPagedResponse; /** Response for updating an entity (PUT). */ -export type UpdateEntityResponse = DataSyncEntityResponse; +export type SetEntityResponse = DataSyncEntityResponse; /** Response for patching an entity (PATCH). */ -export type PatchEntityResponse = DataSyncEntityResponse; +export type UpdateEntityResponse = DataSyncEntityResponse; /** Response for removing an entity. */ export type RemoveEntityResponse = { @@ -577,7 +611,12 @@ export type RemoveEntityResponse = { * everything that can change over the relationship's lifetime is grouped here under `data`. */ export type CreateRelationshipData = { - /** Version of the relationship class schema. */ + /** + * Version of the relationship class schema. + * + * Stored on the relationship as `relationshipClassVersion` — use that name to address it in + * {@link UpdateRelationshipParameters} patch paths. + */ classVersion: number; /** Optional lifecycle status. */ @@ -591,10 +630,10 @@ export type CreateRelationshipData = { * Relationship data properties for update (PUT) requests. * * The mutable, versioned payload of a relationship. `id`, `entityAId`, and `entityBId` live at the - * top level of {@link UpdateRelationshipParameters}. `relationshipClass` is immutable after creation + * top level of {@link SetRelationshipParameters}. `relationshipClass` is immutable after creation * and therefore has no place in updates. The server rejects a PUT that omits `classVersion`. */ -export type UpdateRelationshipData = { +export type SetRelationshipData = { /** Version of the relationship class schema. */ classVersion: number; @@ -655,7 +694,13 @@ export type CreateRelationshipParameters = { */ id?: string; - /** Relationship class this relationship belongs to. Set at creation time and immutable afterward. */ + /** + * Relationship class this relationship belongs to. Set at creation time and immutable afterward. + * + * Stored on the relationship as `relationshipClass` — the name it carries in responses, in + * real-time event payloads, and in {@link UpdateRelationshipParameters} patch paths (immutable, + * so never a patch target). + */ class: string; /** First entity ID in the relationship. */ @@ -671,7 +716,7 @@ export type CreateRelationshipParameters = { /** * Get Relationship request parameters. */ -export type FetchRelationshipParameters = { +export type GetRelationshipParameters = { /** Relationship ID. */ id: string; }; @@ -679,7 +724,7 @@ export type FetchRelationshipParameters = { /** * Get All Relationships request parameters. */ -export type FetchRelationshipsParameters = PagedRequestParameters & { +export type GetRelationshipsParameters = PagedRequestParameters & { /** Relationship class name (required by the server). */ relationshipClass: string; @@ -702,9 +747,9 @@ export type FetchRelationshipsParameters = PagedRequestParameters & { }; /** - * Update Relationship request parameters (full replacement via PUT). + * Set Relationship request parameters (full replacement via PUT). */ -export type UpdateRelationshipParameters = { +export type SetRelationshipParameters = { /** Relationship ID. */ id: string; @@ -715,7 +760,7 @@ export type UpdateRelationshipParameters = { entityBId: string; /** Complete, mutable relationship data for replacement (excludes immutable `relationshipClass`). */ - data: UpdateRelationshipData; + data: SetRelationshipData; /** * ETag for optimistic concurrency control. @@ -725,14 +770,20 @@ export type UpdateRelationshipParameters = { }; /** - * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * Update Relationship request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to + * JSON Patch operations. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. - * The SDK converts these to JSON Patch operations on the wire. + * Patch paths address the relationship's **stored property names** — the same keys that come back in + * responses and real-time events — not the grouped parameter names used by + * {@link CreateRelationshipParameters}. So the class version is `relationshipClassVersion` (not + * `data.classVersion`), and payload fields keep their `payload.` prefix. `relationshipClass`, + * `entityAId`, and `entityBId` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ -export type PatchRelationshipParameters = { +export type UpdateRelationshipParameters = { /** Relationship ID. */ id: string; @@ -826,16 +877,16 @@ export type RemoveRelationshipParameters = { export type CreateRelationshipResponse = DataSyncEntityResponse; /** Response for getting a single relationship. */ -export type FetchRelationshipResponse = DataSyncEntityResponse; +export type GetRelationshipResponse = DataSyncEntityResponse; /** Response for listing relationships. */ -export type FetchRelationshipsResponse = DataSyncPagedResponse; +export type GetRelationshipsResponse = DataSyncPagedResponse; /** Response for updating a relationship (PUT). */ -export type UpdateRelationshipResponse = DataSyncEntityResponse; +export type SetRelationshipResponse = DataSyncEntityResponse; /** Response for patching a relationship (PATCH). */ -export type PatchRelationshipResponse = DataSyncEntityResponse; +export type UpdateRelationshipResponse = DataSyncEntityResponse; /** Response for removing a relationship. */ export type RemoveRelationshipResponse = { @@ -854,7 +905,12 @@ export type RemoveRelationshipResponse = { * {@link CreateUserParameters}; everything that can change over the user's lifetime is here. */ export type CreateUserData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * Stored on the user as `entityClassVersion` — use that name to address it in + * {@link UpdateUserParameters} patch paths. + */ classVersion: number; /** Optional lifecycle status. */ @@ -905,6 +961,25 @@ export type CreateUserParameters = { */ id?: string; + /** + * Entity class this user belongs to. Set at creation time and immutable afterward. + * + * Must be `User` or one of its subclasses. Omit to let the service apply the default (`User`). + * + * Stored on the user as `entityClass` — the name it carries in responses, in real-time event + * payloads, and in {@link UpdateUserParameters} patch paths (immutable, so never a patch target). + */ + class?: string; + + /** + * Class hierarchy level of the user's entity class. Set at creation time and immutable afterward. + * + * Omit to let the service apply its default. + * + * Stored on the user as `entityClassLevel`. + */ + classLevel?: ClassLevel; + /** Mutable, versioned user data (class version, status, and payload). */ data: CreateUserData; }; @@ -913,9 +988,9 @@ export type CreateUserParameters = { * User data properties for update (PUT) requests. * * The mutable, versioned payload of a user. `id` lives at the top level of - * {@link UpdateUserParameters}. + * {@link SetUserParameters}. */ -export type UpdateUserData = { +export type SetUserData = { /** Version of the entity class schema. */ classVersion: number; @@ -929,7 +1004,7 @@ export type UpdateUserData = { /** * Get User request parameters. */ -export type FetchUserParameters = { +export type GetUserParameters = { /** User ID. */ id: string; }; @@ -937,7 +1012,7 @@ export type FetchUserParameters = { /** * Get All Users request parameters. */ -export type FetchUsersParameters = PagedRequestParameters & { +export type GetUsersParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns users for the latest version. */ @@ -950,14 +1025,14 @@ export type FetchUsersParameters = PagedRequestParameters & { }; /** - * Update User request parameters (full replacement via PUT). + * Set User request parameters (full replacement via PUT). */ -export type UpdateUserParameters = { +export type SetUserParameters = { /** User ID. */ id: string; /** Complete, mutable user data for replacement. */ - data: UpdateUserData; + data: SetUserData; /** * ETag for optimistic concurrency control. @@ -967,14 +1042,20 @@ export type UpdateUserParameters = { }; /** - * Patch User request parameters (partial update via JSON Patch RFC 6902). + * Update 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. + * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to + * JSON Patch operations. + * + * Patch paths address the user's **stored property names** — the same keys that come back in + * responses and real-time events — not the grouped parameter names used by + * {@link CreateUserParameters}. So the class version is `entityClassVersion` (not + * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ -export type PatchUserParameters = { +export type UpdateUserParameters = { /** User ID. */ id: string; @@ -1041,16 +1122,16 @@ export type RemoveUserParameters = { export type CreateUserResponse = DataSyncEntityResponse; /** Response for getting a single user. */ -export type FetchUserResponse = DataSyncEntityResponse; +export type GetUserResponse = DataSyncEntityResponse; /** Response for listing users. */ -export type FetchUsersResponse = DataSyncPagedResponse; +export type GetUsersResponse = DataSyncPagedResponse; /** Response for updating a user (PUT). */ -export type UpdateUserResponse = DataSyncEntityResponse; +export type SetUserResponse = DataSyncEntityResponse; /** Response for patching a user (PATCH). */ -export type PatchUserResponse = DataSyncEntityResponse; +export type UpdateUserResponse = DataSyncEntityResponse; /** Response for removing a user. */ export type RemoveUserResponse = { @@ -1069,7 +1150,12 @@ export type RemoveUserResponse = { * {@link CreateChannelParameters}; everything that can change over the channel's lifetime is here. */ export type CreateChannelData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * Stored on the channel as `entityClassVersion` — use that name to address it in + * {@link UpdateChannelParameters} patch paths. + */ classVersion: number; /** Optional lifecycle status. */ @@ -1083,9 +1169,9 @@ export type CreateChannelData = { * Channel data properties for update (PUT) requests. * * The mutable, versioned payload of a channel. `id` lives at the top level of - * {@link UpdateChannelParameters}. + * {@link SetChannelParameters}. */ -export type UpdateChannelData = { +export type SetChannelData = { /** Version of the entity class schema. */ classVersion: number; @@ -1137,6 +1223,28 @@ export type CreateChannelParameters = { */ id?: string; + /** + * Entity class this channel belongs to. Set at creation time and immutable afterward. + * + * Must be `Channel` or one of its subclasses. Omit to let the service apply the default + * (`Channel`). + * + * Stored on the channel as `entityClass` — the name it carries in responses, in real-time event + * payloads, and in {@link UpdateChannelParameters} patch paths (immutable, so never a patch + * target). + */ + class?: string; + + /** + * Class hierarchy level of the channel's entity class. Set at creation time and immutable + * afterward. + * + * Omit to let the service apply its default. + * + * Stored on the channel as `entityClassLevel`. + */ + classLevel?: ClassLevel; + /** Mutable, versioned channel data (class version, status, and payload). */ data: CreateChannelData; }; @@ -1144,7 +1252,7 @@ export type CreateChannelParameters = { /** * Get Channel request parameters. */ -export type FetchChannelParameters = { +export type GetChannelParameters = { /** Channel ID. */ id: string; }; @@ -1152,7 +1260,7 @@ export type FetchChannelParameters = { /** * Get All Channels request parameters. */ -export type FetchChannelsParameters = PagedRequestParameters & { +export type GetChannelsParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns channels for the latest version. */ @@ -1165,14 +1273,14 @@ export type FetchChannelsParameters = PagedRequestParameters & { }; /** - * Update Channel request parameters (full replacement via PUT). + * Set Channel request parameters (full replacement via PUT). */ -export type UpdateChannelParameters = { +export type SetChannelParameters = { /** Channel ID. */ id: string; /** Complete, mutable channel data for replacement. */ - data: UpdateChannelData; + data: SetChannelData; /** * ETag for optimistic concurrency control. @@ -1181,13 +1289,20 @@ export type UpdateChannelParameters = { }; /** - * Patch Channel request parameters (partial update via JSON Patch RFC 6902). + * Update Channel request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to + * JSON Patch operations. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Patch paths address the channel's **stored property names** — the same keys that come back in + * responses and real-time events — not the grouped parameter names used by + * {@link CreateChannelParameters}. So the class version is `entityClassVersion` (not + * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ -export type PatchChannelParameters = { +export type UpdateChannelParameters = { /** Channel ID. */ id: string; @@ -1254,16 +1369,16 @@ export type RemoveChannelParameters = { export type CreateChannelResponse = DataSyncEntityResponse; /** Response for getting a single channel. */ -export type FetchChannelResponse = DataSyncEntityResponse; +export type GetChannelResponse = DataSyncEntityResponse; /** Response for listing channels. */ -export type FetchChannelsResponse = DataSyncPagedResponse; +export type GetChannelsResponse = DataSyncPagedResponse; /** Response for updating a channel (PUT). */ -export type UpdateChannelResponse = DataSyncEntityResponse; +export type SetChannelResponse = DataSyncEntityResponse; /** Response for patching a channel (PATCH). */ -export type PatchChannelResponse = DataSyncEntityResponse; +export type UpdateChannelResponse = DataSyncEntityResponse; /** Response for removing a channel. */ export type RemoveChannelResponse = { @@ -1283,7 +1398,12 @@ export type RemoveChannelResponse = { * that can change over the membership's lifetime is grouped here under `data`. */ export type CreateMembershipData = { - /** Version of the Membership relationship class. */ + /** + * Version of the Membership relationship class. + * + * Stored on the membership as `relationshipClassVersion` — use that name to address it in + * {@link UpdateMembershipParameters} patch paths. + */ classVersion: number; /** Optional lifecycle status. */ @@ -1297,10 +1417,10 @@ export type CreateMembershipData = { * Membership data properties for update (PUT) requests. * * 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}. + * level of {@link SetMembershipParameters}. The server rejects a PUT that omits `classVersion` + * (`SYN-0004: must not be null`), mirroring {@link SetRelationshipData}. */ -export type UpdateMembershipData = { +export type SetMembershipData = { /** Version of the Membership relationship class. */ classVersion: number; @@ -1375,7 +1495,7 @@ export type CreateMembershipParameters = { /** * Get Membership request parameters. */ -export type FetchMembershipParameters = { +export type GetMembershipParameters = { /** Membership ID. */ id: string; }; @@ -1383,7 +1503,7 @@ export type FetchMembershipParameters = { /** * Get All Memberships request parameters. */ -export type FetchMembershipsParameters = PagedRequestParameters & { +export type GetMembershipsParameters = PagedRequestParameters & { /** Filter memberships by user ID. */ userId?: string; @@ -1403,9 +1523,9 @@ export type FetchMembershipsParameters = PagedRequestParameters & { }; /** - * Update Membership request parameters (full replacement via PUT). + * Set Membership request parameters (full replacement via PUT). */ -export type UpdateMembershipParameters = { +export type SetMembershipParameters = { /** Membership ID. */ id: string; @@ -1416,7 +1536,7 @@ export type UpdateMembershipParameters = { channelId: string; /** Complete, mutable membership data for replacement. */ - data: UpdateMembershipData; + data: SetMembershipData; /** * ETag for optimistic concurrency control. @@ -1425,13 +1545,20 @@ export type UpdateMembershipParameters = { }; /** - * Patch Membership request parameters (partial update via JSON Patch RFC 6902). + * Update Membership request parameters (partial update via JSON Patch RFC 6902). + * + * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to + * JSON Patch operations. * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Patch paths address the membership's **stored property names** — the same keys that come back in + * responses and real-time events — not the grouped parameter names used by + * {@link CreateMembershipParameters}. So the class version is `relationshipClassVersion` (not + * `data.classVersion`), and payload fields keep their `payload.` prefix. `channelId` and `userId` + * are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ -export type PatchMembershipParameters = { +export type UpdateMembershipParameters = { /** Membership ID. */ id: string; @@ -1498,16 +1625,16 @@ export type RemoveMembershipParameters = { export type CreateMembershipResponse = DataSyncEntityResponse; /** Response for getting a single membership. */ -export type FetchMembershipResponse = DataSyncEntityResponse; +export type GetMembershipResponse = DataSyncEntityResponse; /** Response for listing memberships. */ -export type FetchMembershipsResponse = DataSyncPagedResponse; +export type GetMembershipsResponse = DataSyncPagedResponse; /** Response for updating a membership (PUT). */ -export type UpdateMembershipResponse = DataSyncEntityResponse; +export type SetMembershipResponse = DataSyncEntityResponse; /** Response for patching a membership (PATCH). */ -export type PatchMembershipResponse = DataSyncEntityResponse; +export type UpdateMembershipResponse = DataSyncEntityResponse; /** Response for removing a membership. */ export type RemoveMembershipResponse = { diff --git a/src/core/types/api/subscription.ts b/src/core/types/api/subscription.ts index 5afafba38..f234ad9a7 100644 --- a/src/core/types/api/subscription.ts +++ b/src/core/types/api/subscription.ts @@ -14,6 +14,7 @@ import { export type { DataSyncData, DataSyncNormalizedType, + DataSyncClassLevel, DataSyncEntityData, DataSyncRelationshipData, DataSyncDeleteData, From a35c647a5cbc2a71341d1e8a346e988d87590d99 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 17 Aug 2026 12:17:04 +0530 Subject: [PATCH 24/27] dist and lib files updates --- dist/web/pubnub.js | 915 +++++++++-------- dist/web/pubnub.min.js | 4 +- lib/core/components/token_manager.js | 51 + lib/core/constants/operations.js | 80 +- .../endpoints/access_manager/grant_token.js | 72 +- .../endpoints/data_sync/channel/create.js | 13 +- .../endpoints/data_sync/channel/get-all.js | 49 +- lib/core/endpoints/data_sync/channel/get.js | 2 +- .../endpoints/data_sync/channel/remove.js | 2 +- lib/core/endpoints/data_sync/channel/set.js | 75 ++ .../endpoints/data_sync/channel/update.js | 30 +- lib/core/endpoints/data_sync/entity/create.js | 15 +- .../endpoints/data_sync/entity/get-all.js | 49 +- lib/core/endpoints/data_sync/entity/get.js | 2 +- lib/core/endpoints/data_sync/entity/remove.js | 2 +- lib/core/endpoints/data_sync/entity/set.js | 76 ++ lib/core/endpoints/data_sync/entity/update.js | 31 +- .../endpoints/data_sync/membership/create.js | 18 +- .../endpoints/data_sync/membership/get-all.js | 49 +- .../endpoints/data_sync/membership/get.js | 2 +- .../endpoints/data_sync/membership/remove.js | 2 +- .../endpoints/data_sync/membership/set.js | 80 ++ .../endpoints/data_sync/membership/update.js | 34 +- .../data_sync/relationship/create.js | 21 +- .../data_sync/relationship/get-all.js | 49 +- .../endpoints/data_sync/relationship/get.js | 2 +- .../data_sync/relationship/remove.js | 2 +- .../endpoints/data_sync/relationship/set.js | 80 ++ .../data_sync/relationship/update.js | 35 +- lib/core/endpoints/data_sync/user/create.js | 13 +- lib/core/endpoints/data_sync/user/get-all.js | 49 +- lib/core/endpoints/data_sync/user/get.js | 2 +- lib/core/endpoints/data_sync/user/remove.js | 2 +- lib/core/endpoints/data_sync/user/set.js | 75 ++ lib/core/endpoints/data_sync/user/update.js | 30 +- lib/core/endpoints/subscribe.js | 41 +- lib/core/pubnub-common.js | 3 +- lib/core/pubnub-data-sync.js | 180 ++-- lib/core/types/api/data-sync.js | 38 +- lib/transport/middleware.js | 9 +- lib/types/index.d.ts | 956 +++++++++++------- 41 files changed, 2163 insertions(+), 1077 deletions(-) create mode 100644 lib/core/endpoints/data_sync/channel/set.js create mode 100644 lib/core/endpoints/data_sync/entity/set.js create mode 100644 lib/core/endpoints/data_sync/membership/set.js create mode 100644 lib/core/endpoints/data_sync/relationship/set.js create mode 100644 lib/core/endpoints/data_sync/user/set.js diff --git a/dist/web/pubnub.js b/dist/web/pubnub.js index 84d317f63..9e964cb98 100644 --- a/dist/web/pubnub.js +++ b/dist/web/pubnub.js @@ -3696,123 +3696,123 @@ /** * Create entity REST API operation. */ - RequestOperation["PNCreateEntityOperation"] = "PNCreateEntityOperation"; + RequestOperation["PNCreateDataSyncEntityOperation"] = "PNCreateDataSyncEntityOperation"; /** * Get entity REST API operation. */ - RequestOperation["PNGetEntityOperation"] = "PNGetEntityOperation"; + RequestOperation["PNGetDataSyncEntityOperation"] = "PNGetDataSyncEntityOperation"; /** * Get all entities REST API operation. */ - RequestOperation["PNGetAllEntitiesOperation"] = "PNGetAllEntitiesOperation"; + RequestOperation["PNGetDataSyncEntitiesOperation"] = "PNGetDataSyncEntitiesOperation"; /** - * Update entity REST API operation. + * Set entity REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateEntityOperation"] = "PNUpdateEntityOperation"; + RequestOperation["PNSetDataSyncEntityOperation"] = "PNSetDataSyncEntityOperation"; /** - * Patch entity REST API operation. + * Update entity REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchEntityOperation"] = "PNPatchEntityOperation"; + RequestOperation["PNUpdateDataSyncEntityOperation"] = "PNUpdateDataSyncEntityOperation"; /** * Remove entity REST API operation. */ - RequestOperation["PNRemoveEntityOperation"] = "PNRemoveEntityOperation"; + RequestOperation["PNRemoveDataSyncEntityOperation"] = "PNRemoveDataSyncEntityOperation"; /** * Create relationship REST API operation. */ - RequestOperation["PNCreateRelationshipOperation"] = "PNCreateRelationshipOperation"; + RequestOperation["PNCreateDataSyncRelationshipOperation"] = "PNCreateDataSyncRelationshipOperation"; /** * Get relationship REST API operation. */ - RequestOperation["PNGetRelationshipOperation"] = "PNGetRelationshipOperation"; + RequestOperation["PNGetDataSyncRelationshipOperation"] = "PNGetDataSyncRelationshipOperation"; /** * Get all relationships REST API operation. */ - RequestOperation["PNGetAllRelationshipsOperation"] = "PNGetAllRelationshipsOperation"; + RequestOperation["PNGetDataSyncRelationshipsOperation"] = "PNGetDataSyncRelationshipsOperation"; /** - * Update relationship REST API operation. + * Set relationship REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateRelationshipOperation"] = "PNUpdateRelationshipOperation"; + RequestOperation["PNSetDataSyncRelationshipOperation"] = "PNSetDataSyncRelationshipOperation"; /** - * Patch relationship REST API operation. + * Update relationship REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchRelationshipOperation"] = "PNPatchRelationshipOperation"; + RequestOperation["PNUpdateDataSyncRelationshipOperation"] = "PNUpdateDataSyncRelationshipOperation"; /** * Remove relationship REST API operation. */ - RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + RequestOperation["PNRemoveDataSyncRelationshipOperation"] = "PNRemoveDataSyncRelationshipOperation"; /** * Create user REST API operation. */ - RequestOperation["PNCreateUserOperation"] = "PNCreateUserOperation"; + RequestOperation["PNCreateDataSyncUserOperation"] = "PNCreateDataSyncUserOperation"; /** * Get user REST API operation. */ - RequestOperation["PNGetUserOperation"] = "PNGetUserOperation"; + RequestOperation["PNGetDataSyncUserOperation"] = "PNGetDataSyncUserOperation"; /** * Get all users REST API operation. */ - RequestOperation["PNGetAllUsersOperation"] = "PNGetAllUsersOperation"; + RequestOperation["PNGetDataSyncUsersOperation"] = "PNGetDataSyncUsersOperation"; /** - * Update user REST API operation. + * Set user REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateUserOperation"] = "PNUpdateUserOperation"; + RequestOperation["PNSetDataSyncUserOperation"] = "PNSetDataSyncUserOperation"; /** - * Patch user REST API operation. + * Update user REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchUserOperation"] = "PNPatchUserOperation"; + RequestOperation["PNUpdateDataSyncUserOperation"] = "PNUpdateDataSyncUserOperation"; /** * Remove user REST API operation. */ - RequestOperation["PNRemoveUserOperation"] = "PNRemoveUserOperation"; + RequestOperation["PNRemoveDataSyncUserOperation"] = "PNRemoveDataSyncUserOperation"; /** * Create channel REST API operation. */ - RequestOperation["PNCreateChannelOperation"] = "PNCreateChannelOperation"; + RequestOperation["PNCreateDataSyncChannelOperation"] = "PNCreateDataSyncChannelOperation"; /** * Get channel REST API operation. */ - RequestOperation["PNGetChannelOperation"] = "PNGetChannelOperation"; + RequestOperation["PNGetDataSyncChannelOperation"] = "PNGetDataSyncChannelOperation"; /** * Get all channels REST API operation. */ - RequestOperation["PNGetAllChannelsOperation"] = "PNGetAllChannelsOperation"; + RequestOperation["PNGetDataSyncChannelsOperation"] = "PNGetDataSyncChannelsOperation"; /** - * Update channel REST API operation. + * Set channel REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateChannelOperation"] = "PNUpdateChannelOperation"; + RequestOperation["PNSetDataSyncChannelOperation"] = "PNSetDataSyncChannelOperation"; /** - * Patch channel REST API operation. + * Update channel REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchChannelOperation"] = "PNPatchChannelOperation"; + RequestOperation["PNUpdateDataSyncChannelOperation"] = "PNUpdateDataSyncChannelOperation"; /** * Remove channel REST API operation. */ - RequestOperation["PNRemoveChannelOperation"] = "PNRemoveChannelOperation"; + RequestOperation["PNRemoveDataSyncChannelOperation"] = "PNRemoveDataSyncChannelOperation"; /** * Create membership REST API operation. */ - RequestOperation["PNCreateMembershipOperation"] = "PNCreateMembershipOperation"; + RequestOperation["PNCreateDataSyncMembershipOperation"] = "PNCreateDataSyncMembershipOperation"; /** * Get membership REST API operation. */ - RequestOperation["PNGetMembershipOperation"] = "PNGetMembershipOperation"; + RequestOperation["PNGetDataSyncMembershipOperation"] = "PNGetDataSyncMembershipOperation"; /** * Get all memberships REST API operation. */ - RequestOperation["PNGetAllMembershipsOperation"] = "PNGetAllMembershipsOperation"; + RequestOperation["PNGetDataSyncMembershipsOperation"] = "PNGetDataSyncMembershipsOperation"; /** - * Update membership REST API operation. + * Set membership REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateMembershipOperation"] = "PNUpdateMembershipOperation"; + RequestOperation["PNSetDataSyncMembershipOperation"] = "PNSetDataSyncMembershipOperation"; /** - * Patch membership REST API operation. + * Update membership REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchMembershipOperation"] = "PNPatchMembershipOperation"; + RequestOperation["PNUpdateDataSyncMembershipOperation"] = "PNUpdateDataSyncMembershipOperation"; /** * Remove membership REST API operation. */ - RequestOperation["PNRemoveMembershipOperation"] = "PNRemoveMembershipOperation"; + RequestOperation["PNRemoveDataSyncMembershipOperation"] = "PNRemoveDataSyncMembershipOperation"; // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- @@ -5755,6 +5755,7 @@ * @returns Information about resources and permissions which has been granted for them. */ parseToken(tokenString) { + var _a, _b; const parsed = this.cbor.decodeToken(tokenString); if (parsed !== undefined) { const uuidResourcePermissions = parsed.res.uuid ? Object.keys(parsed.res.uuid) : []; @@ -5788,6 +5789,9 @@ groupResourcePermissions.forEach((id) => (groups[id] = this.extractPermissions(parsed.res.grp[id]))); } } + const resourceDataSync = this.extractDataSyncScopes(parsed.res); + if (resourceDataSync) + ((_a = result.resources) !== null && _a !== void 0 ? _a : (result.resources = {})).dataSync = resourceDataSync; const uuidPatterns = uuidPatternPermissions.length > 0; const channelPatterns = channelPatternPermissions.length > 0; const groupPatterns = groupPatternPermissions.length > 0; @@ -5806,6 +5810,9 @@ groupPatternPermissions.forEach((id) => (groups[id] = this.extractPermissions(parsed.pat.grp[id]))); } } + const patternDataSync = this.extractDataSyncScopes(parsed.pat); + if (patternDataSync) + ((_b = result.patterns) !== null && _b !== void 0 ? _b : (result.patterns = {})).dataSync = patternDataSync; if (parsed.meta && Object.keys(parsed.meta).length > 0) result.meta = parsed.meta; return result; @@ -5845,6 +5852,50 @@ permissionsResult.read = true; 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. + */ + extractDataSyncScopes(section) { + const dataSyncScopes = [ + ['entities', 'datasync:entities'], + ['relationships', 'datasync:relationships'], + ['memberships', 'datasync:memberships'], + ]; + let result; + dataSyncScopes.forEach(([scope, wireKey]) => { + const permissions = section[wireKey]; + if (!permissions) + return; + const ids = Object.keys(permissions); + if (ids.length === 0) + return; + const scopeResult = ((result !== null && result !== void 0 ? result : (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. + */ + extractDataSyncPermissions(permissions) { + return { + create: (permissions & 16) === 16, + get: (permissions & 32) === 32, + update: (permissions & 64) === 64, + delete: (permissions & 8) === 8, + }; + } } /** @@ -5887,6 +5938,10 @@ * * @internal */ + /** + * HTTP status codes that represent definitive client outcomes and must not be retried. + */ + const NON_RETRIABLE_STATUS_CODES = [404, 409]; /** * Request signature generator. * @@ -5999,8 +6054,9 @@ const [attemptPromise, attemptCancellation] = transport.makeSendable(this.request(req)); activeCancellation = attemptCancellation; const responseHandler = (res, error) => { - const retriableError = error ? error.category !== StatusCategory$1.PNCancelledCategory : true; - const retriableStatusCode = (!res || res.status >= 400) && (error === null || error === void 0 ? void 0 : error.statusCode) !== 404; + const retriableError = !error || error.category !== StatusCategory$1.PNCancelledCategory; + const statusCode = error === null || error === void 0 ? void 0 : error.statusCode; + const retriableStatusCode = (!res || res.status >= 400) && !NON_RETRIABLE_STATUS_CODES.includes(statusCode); let delay = -1; if (retriableError && retriableStatusCode && @@ -6708,12 +6764,11 @@ PubNubEventType[PubNubEventType["DataSync"] = 5] = "DataSync"; })(PubNubEventType || (PubNubEventType = {})); /** - * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * Reserved DataSync system class names (lower-cased) → 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`). + * Only consulted for classes the service marks as `Global` (see {@link DataSyncClassLevel}), so a + * developer-defined class which happens to share one of these names is not mistaken for a typed + * resource. Keys are compared case-insensitively. * * @internal */ @@ -6721,9 +6776,6 @@ user: 'user', channel: 'channel', membership: 'membership', - pn_user: 'user', - pn_channel: 'channel', - pn_membership: 'membership', }; // endregion /** @@ -6952,29 +7004,29 @@ // 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. + // Wire `className` is a bare class name (`User`, `Membership`, `Customer`); the `:`-splitting below + // is only there to keep tolerating the retired positional composite (`User::` / `::Customer`). 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 classLevel = metadata.classLevel; + // `classLevel` authoritatively separates the built-in classes from developer-defined ones, so a + // developer class named `User` / `Channel` / `Membership` is not mistaken for a typed resource. + // When it is absent (service predating the field) fall back to the legacy positional heuristic, + // where the system class was the first segment. + const systemClass = classLevel === undefined ? classSegments[0] : classLevel === 'Global' ? className : 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 : {}); + // `data` mirrors the object as sent by the service; class identity is reported once, on the event. let data; - if (metadata.event === 'delete') { + 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 }); - } + else if (metadata.type === 'relationship') + data = Object.assign({}, raw); + else + data = Object.assign({}, raw); return { channel, subscription, @@ -6986,6 +7038,7 @@ type: metadata.type, objectType, className, + classLevel, classVersion, data, }, @@ -15627,7 +15680,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateUserOperation; + return RequestOperation$1.PNCreateDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15638,9 +15691,9 @@ }); } validate() { - 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'; } get headers() { @@ -15653,12 +15706,93 @@ return `/v1/datasync/subkeys/${subscribeKey}/users`; } get body() { - return JSON.stringify({ data: this.parameters.user }); + const { id, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } /** - * Get All Users REST API module. + * PubNub DataSync API type definitions. + * + * Types for Entity Class CRUD operations. + */ + /** + * 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 + */ + function serializeDataSyncSort(sort) { + if (typeof sort === 'string') + return sort; + return Object.entries(sort !== null && sort !== void 0 ? sort : {}).map(([option, order]) => (order !== null ? `${option}:${order}` : option)); + } + /** + * 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 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 + */ + function toJsonPatchOperations(input) { + const { add, replace, remove, move, copy, test } = input; + const ops = []; + 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) }); + } + } + 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; + } + + /** + * Get Users REST API module. * * @internal */ @@ -15672,11 +15806,11 @@ const DEFAULT_LIMIT$4 = 20; // endregion /** - * Get All Users request. + * Get Users request. * * @internal */ - class GetAllUsersRequest extends AbstractRequest { + class GetUsersRequest extends AbstractRequest { constructor(parameters) { var _a; super(); @@ -15685,7 +15819,7 @@ (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$4); } operation() { - return RequestOperation$1.PNGetAllUsersOperation; + return RequestOperation$1.PNGetDataSyncUsersOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15700,12 +15834,13 @@ } 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 } : {})); + const sorting = serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update User REST API module. + * Set User REST API module. * * Full resource replacement via PUT. * @@ -15713,17 +15848,17 @@ */ // endregion /** - * Update User request. + * Set User request. * * @internal */ - class UpdateUserRequest extends AbstractRequest { + class SetUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateUserOperation; + return RequestOperation$1.PNSetDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15736,9 +15871,9 @@ 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) + 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'; } get headers() { @@ -15753,7 +15888,10 @@ return `/v1/datasync/subkeys/${subscribeKey}/users/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.user }); + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } @@ -15774,7 +15912,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveUserOperation; + return RequestOperation$1.PNRemoveDataSyncUserOperation; } validate() { if (!this.parameters.id) @@ -15799,72 +15937,28 @@ } /** - * PubNub DataSync API type definitions. - * - * Types for Entity Class CRUD operations. - */ - /** - * 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 `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 - */ - function toJsonPatchOperations(add, replace, remove) { - const ops = []; - 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; - } - - /** - * Patch User REST API module. + * Update 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 */ // endregion /** - * Patch User request. + * Update User request. * * @internal */ - class PatchUserRequest extends AbstractRequest { + class UpdateUserRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchUserOperation; + return RequestOperation$1.PNUpdateDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15877,11 +15971,15 @@ 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'; + 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'; } get headers() { var _a; @@ -15895,14 +15993,9 @@ return `/v1/datasync/subkeys/${subscribeKey}/users/${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); + const { add, replace, remove, move, copy, test } = this.parameters; + // 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); } } @@ -15924,7 +16017,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetUserOperation; + return RequestOperation$1.PNGetDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15961,7 +16054,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateChannelOperation; + return RequestOperation$1.PNCreateDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -15972,9 +16065,9 @@ }); } validate() { - if (!this.parameters.channel) - return 'Channel cannot be empty'; - if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + if (!this.parameters.data) + return 'Channel data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } get headers() { @@ -15987,12 +16080,15 @@ return `/v1/datasync/subkeys/${subscribeKey}/channels`; } get body() { - return JSON.stringify({ data: this.parameters.channel }); + const { id, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } /** - * Get All Channels REST API module. + * Get Channels REST API module. * * @internal */ @@ -16006,11 +16102,11 @@ const DEFAULT_LIMIT$3 = 20; // endregion /** - * Get All Channels request. + * Get Channels request. * * @internal */ - class GetAllChannelsRequest extends AbstractRequest { + class GetChannelsRequest extends AbstractRequest { constructor(parameters) { var _a; super(); @@ -16019,7 +16115,7 @@ (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$3); } operation() { - return RequestOperation$1.PNGetAllChannelsOperation; + return RequestOperation$1.PNGetDataSyncChannelsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16034,12 +16130,13 @@ } 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 } : {})); + const sorting = serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Channel REST API module. + * Set Channel REST API module. * * Full resource replacement via PUT. * @@ -16047,17 +16144,17 @@ */ // endregion /** - * Update Channel request. + * Set Channel request. * * @internal */ - class UpdateChannelRequest extends AbstractRequest { + class SetChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateChannelOperation; + return RequestOperation$1.PNSetDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16070,9 +16167,9 @@ 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) + if (!this.parameters.data) + return 'Channel data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } get headers() { @@ -16087,7 +16184,10 @@ return `/v1/datasync/subkeys/${subscribeKey}/channels/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.channel }); + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } @@ -16108,7 +16208,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveChannelOperation; + return RequestOperation$1.PNRemoveDataSyncChannelOperation; } validate() { if (!this.parameters.id) @@ -16133,27 +16233,28 @@ } /** - * Patch Channel REST API module. + * Update 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 */ // endregion /** - * Patch Channel request. + * Update Channel request. * * @internal */ - class PatchChannelRequest extends AbstractRequest { + class UpdateChannelRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchChannelOperation; + return RequestOperation$1.PNUpdateDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16166,11 +16267,15 @@ 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'; + 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'; } get headers() { var _a; @@ -16184,14 +16289,9 @@ return `/v1/datasync/subkeys/${subscribeKey}/channels/${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); + const { add, replace, remove, move, copy, test } = this.parameters; + // 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); } } @@ -16213,7 +16313,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetChannelOperation; + return RequestOperation$1.PNGetDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16250,7 +16350,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateMembershipOperation; + return RequestOperation$1.PNCreateDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16261,13 +16361,13 @@ }); } validate() { - if (!this.parameters.membership) - return 'Membership cannot be empty'; - if (!this.parameters.membership.userId) + if (!this.parameters.userId) return 'User id cannot be empty'; - if (!this.parameters.membership.channelId) + if (!this.parameters.channelId) return 'Channel id cannot be empty'; - if (!this.parameters.membership.relationshipClassVersion) + if (!this.parameters.data) + return 'Membership data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -16280,12 +16380,16 @@ return `/v1/datasync/subkeys/${subscribeKey}/memberships`; } get body() { - return JSON.stringify({ data: this.parameters.membership }); + const { id, userId, channelId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { userId, + channelId, relationshipClassVersion: data.classVersion }), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } /** - * Get All Memberships REST API module. + * Get Memberships REST API module. * * @internal */ @@ -16299,11 +16403,11 @@ const DEFAULT_LIMIT$2 = 20; // endregion /** - * Get All Memberships request. + * Get Memberships request. * * @internal */ - class GetAllMembershipsRequest extends AbstractRequest { + class GetMembershipsRequest extends AbstractRequest { constructor(parameters) { var _a; super(); @@ -16312,7 +16416,7 @@ (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$2); } operation() { - return RequestOperation$1.PNGetAllMembershipsOperation; + return RequestOperation$1.PNGetDataSyncMembershipsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16327,12 +16431,13 @@ } 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 } : {})); + const sorting = serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Membership REST API module. + * Set Membership REST API module. * * Full resource replacement via PUT. * @@ -16340,17 +16445,17 @@ */ // endregion /** - * Update Membership request. + * Set Membership request. * * @internal */ - class UpdateMembershipRequest extends AbstractRequest { + class SetMembershipRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateMembershipOperation; + return RequestOperation$1.PNSetDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16363,13 +16468,13 @@ 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) + if (!this.parameters.userId) return 'User id cannot be empty'; - if (!this.parameters.membership.channelId) + if (!this.parameters.channelId) return 'Channel id cannot be empty'; - if (!this.parameters.membership.relationshipClassVersion) + if (!this.parameters.data) + return 'Membership data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -16384,7 +16489,11 @@ return `/v1/datasync/subkeys/${subscribeKey}/memberships/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.membership }); + const { userId, channelId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ userId, + channelId, relationshipClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } @@ -16405,7 +16514,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveMembershipOperation; + return RequestOperation$1.PNRemoveDataSyncMembershipOperation; } validate() { if (!this.parameters.id) @@ -16430,27 +16539,28 @@ } /** - * Patch Membership REST API module. + * Update 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 */ // endregion /** - * Patch Membership request. + * Update Membership request. * * @internal */ - class PatchMembershipRequest extends AbstractRequest { + class UpdateMembershipRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchMembershipOperation; + return RequestOperation$1.PNUpdateDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16463,11 +16573,15 @@ 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'; + 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'; } get headers() { var _a; @@ -16481,14 +16595,9 @@ 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); + const { add, replace, remove, move, copy, test } = this.parameters; + // 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); } } @@ -16510,7 +16619,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetMembershipOperation; + return RequestOperation$1.PNGetDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16547,7 +16656,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateRelationshipOperation; + return RequestOperation$1.PNCreateDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16558,15 +16667,15 @@ }); } validate() { - if (!this.parameters.relationship) - return 'Relationship cannot be empty'; - if (!this.parameters.relationship.entityAId) + if (!this.parameters.entityAId) return 'Entity A id cannot be empty'; - if (!this.parameters.relationship.entityBId) + if (!this.parameters.entityBId) return 'Entity B id cannot be empty'; - if (!this.parameters.relationship.relationshipClass) + if (!this.parameters.class) return 'Relationship class cannot be empty'; - if (!this.parameters.relationship.relationshipClassVersion) + if (!this.parameters.data) + return 'Relationship data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -16579,12 +16688,17 @@ return `/v1/datasync/subkeys/${subscribeKey}/relationships`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + const { id, class: relationshipClass, entityAId, entityBId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityAId, + entityBId, + relationshipClass, relationshipClassVersion: data.classVersion }), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } /** - * Get All Relationships REST API module. + * Get Relationships REST API module. * * @internal */ @@ -16598,11 +16712,11 @@ const DEFAULT_LIMIT$1 = 20; // endregion /** - * Get All Relationships request. + * Get Relationships request. * * @internal */ - class GetAllRelationshipsRequest extends AbstractRequest { + class GetRelationshipsRequest extends AbstractRequest { constructor(parameters) { var _a; super(); @@ -16611,7 +16725,7 @@ (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT$1); } operation() { - return RequestOperation$1.PNGetAllRelationshipsOperation; + return RequestOperation$1.PNGetDataSyncRelationshipsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16630,12 +16744,13 @@ } 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 } : {})); + const sorting = serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Relationship REST API module. + * Set Relationship REST API module. * * Full resource replacement via PUT. * @@ -16643,17 +16758,17 @@ */ // endregion /** - * Update Relationship request. + * Set Relationship request. * * @internal */ - class UpdateRelationshipRequest extends AbstractRequest { + class SetRelationshipRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateRelationshipOperation; + return RequestOperation$1.PNSetDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16666,13 +16781,13 @@ 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) + if (!this.parameters.entityAId) return 'Entity A id cannot be empty'; - if (!this.parameters.relationship.entityBId) + if (!this.parameters.entityBId) return 'Entity B id cannot be empty'; - if (!this.parameters.relationship.relationshipClassVersion) + if (!this.parameters.data) + return 'Relationship data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -16687,7 +16802,11 @@ return `/v1/datasync/subkeys/${subscribeKey}/relationships/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + const { entityAId, entityBId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityAId, + entityBId, relationshipClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } @@ -16708,7 +16827,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveRelationshipOperation; + return RequestOperation$1.PNRemoveDataSyncRelationshipOperation; } validate() { if (!this.parameters.id) @@ -16733,27 +16852,29 @@ } /** - * Patch Relationship REST API module. + * Update 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 */ // endregion /** - * Patch Relationship request. + * Update Relationship request. * * @internal */ - class PatchRelationshipRequest extends AbstractRequest { + class UpdateRelationshipRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchRelationshipOperation; + return RequestOperation$1.PNUpdateDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16766,11 +16887,15 @@ 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'; + 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'; } get headers() { var _a; @@ -16784,14 +16909,9 @@ 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); + const { add, replace, remove, move, copy, test } = this.parameters; + // 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); } } @@ -16813,7 +16933,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetRelationshipOperation; + return RequestOperation$1.PNGetDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16850,7 +16970,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNCreateEntityOperation; + return RequestOperation$1.PNCreateDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16861,11 +16981,11 @@ }); } validate() { - if (!this.parameters.entity) - return 'Entity cannot be empty'; - if (!this.parameters.entity.entityClass) + if (!this.parameters.class) return 'Entity class 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'; } get headers() { @@ -16878,12 +16998,15 @@ return `/v1/datasync/subkeys/${subscribeKey}/entities`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + const { id, class: entityClass, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClass, entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } /** - * Get All Entities REST API module. + * Get Entities REST API module. * * @internal */ @@ -16897,11 +17020,11 @@ const DEFAULT_LIMIT = 20; // endregion /** - * Get All Entities request. + * Get Entities request. * * @internal */ - class GetAllEntitiesRequest extends AbstractRequest { + class GetEntitiesRequest extends AbstractRequest { constructor(parameters) { var _a; super(); @@ -16910,7 +17033,7 @@ (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return RequestOperation$1.PNGetAllEntitiesOperation; + return RequestOperation$1.PNGetDataSyncEntitiesOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16929,12 +17052,13 @@ } 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 sorting = serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } /** - * Update Entity REST API module. + * Set Entity REST API module. * * Full resource replacement via PUT. * Note: `entityClass` is immutable and cannot be changed via update. @@ -16943,17 +17067,17 @@ */ // endregion /** - * Update Entity request. + * Set Entity request. * * @internal */ - class UpdateEntityRequest extends AbstractRequest { + class SetEntityRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PUT }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNUpdateEntityOperation; + return RequestOperation$1.PNSetDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -16966,9 +17090,9 @@ 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) + 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'; } get headers() { @@ -16983,7 +17107,10 @@ return `/v1/datasync/subkeys/${subscribeKey}/entities/${encodeString(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } @@ -17004,7 +17131,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNRemoveEntityOperation; + return RequestOperation$1.PNRemoveDataSyncEntityOperation; } validate() { if (!this.parameters.id) @@ -17029,27 +17156,28 @@ } /** - * Patch Entity REST API module. + * Update 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 */ // endregion /** - * Patch Entity request. + * Update Entity request. * * @internal */ - class PatchEntityRequest extends AbstractRequest { + class UpdateEntityRequest extends AbstractRequest { constructor(parameters) { super({ method: TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return RequestOperation$1.PNPatchEntityOperation; + return RequestOperation$1.PNUpdateDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -17062,11 +17190,15 @@ 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'; + 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'; } get headers() { var _a; @@ -17080,14 +17212,9 @@ 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); + const { add, replace, remove, move, copy, test } = this.parameters; + // 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); } } @@ -17109,7 +17236,7 @@ this.parameters = parameters; } operation() { - return RequestOperation$1.PNGetEntityOperation; + return RequestOperation$1.PNGetDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -17183,7 +17310,7 @@ }); } /** - * Fetch a specific Entity. + * Get a specific Entity. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -17204,65 +17331,65 @@ }); } /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get 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. + * @returns Asynchronous get entities response or `void` in case if `callback` provided. */ - getAllEntities(parameters, callback) { + getEntities(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: 'Get Entities with parameters:', })); - const request = new GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetEntitiesRequest(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). + * Set 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. + * @returns Asynchronous set entity response or `void` in case if `callback` provided. */ - updateEntity(parameters, callback) { + setEntity(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: 'Set Entity with parameters:', })); - const request = new UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new SetEntityRequest(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). + * Update 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. + * @returns Asynchronous update entity response or `void` in case if `callback` provided. */ - patchEntity(parameters, callback) { + updateEntity(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: 'Update Entity with parameters:', })); - const request = new PatchEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); @@ -17311,7 +17438,7 @@ }); } /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -17332,65 +17459,65 @@ }); } /** - * Fetch a paginated list of Relationships. + * Get 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. + * @returns Asynchronous get relationships response or `void` in case if `callback` provided. */ - getAllRelationships(parameters, callback) { + getRelationships(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get all Relationships with parameters:', + details: 'Get Relationships with parameters:', })); - const request = new GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetRelationshipsRequest(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). + * Set 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. + * @returns Asynchronous set relationship response or `void` in case if `callback` provided. */ - updateRelationship(parameters, callback) { + setRelationship(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: 'Set Relationship with parameters:', })); - const request = new UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new SetRelationshipRequest(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). + * Update 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. + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. */ - patchRelationship(parameters, callback) { + updateRelationship(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: 'Update Relationship with parameters:', })); - const request = new PatchRelationshipRequest(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); @@ -17439,7 +17566,7 @@ }); } /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -17460,67 +17587,67 @@ }); } /** - * Fetch a paginated list of Users. + * Get 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. + * @returns Asynchronous get users response or `void` in case if `callback` provided. */ - getAllUsers(parametersOrCallback, callback) { + getUsers(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:', + details: 'Get Users with parameters:', })); - const request = new GetAllUsersRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetUsersRequest(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). + * Set 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. + * @returns Asynchronous set user response or `void` in case if `callback` provided. */ - updateUser(parameters, callback) { + setUser(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:', + details: 'Set User with parameters:', })); - const request = new UpdateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new SetUserRequest(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). + * Update 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. + * @returns Asynchronous update user response or `void` in case if `callback` provided. */ - patchUser(parameters, callback) { + updateUser(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:', + details: 'Update User with parameters:', })); - const request = new PatchUserRequest(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); @@ -17569,7 +17696,7 @@ }); } /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -17590,67 +17717,67 @@ }); } /** - * Fetch a paginated list of Channels. + * Get 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. + * @returns Asynchronous get channels response or `void` in case if `callback` provided. */ - getAllChannels(parametersOrCallback, callback) { + getChannels(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:', + details: 'Get Channels with parameters:', })); - const request = new GetAllChannelsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetChannelsRequest(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). + * Set 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. + * @returns Asynchronous set channel response or `void` in case if `callback` provided. */ - updateChannel(parameters, callback) { + setChannel(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:', + details: 'Set Channel with parameters:', })); - const request = new UpdateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new SetChannelRequest(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). + * Update 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. + * @returns Asynchronous update channel response or `void` in case if `callback` provided. */ - patchChannel(parameters, callback) { + updateChannel(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:', + details: 'Update Channel with parameters:', })); - const request = new PatchChannelRequest(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); @@ -17699,7 +17826,7 @@ }); } /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -17720,67 +17847,67 @@ }); } /** - * Fetch a paginated list of Memberships. + * Get 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. + * @returns Asynchronous get memberships response or `void` in case if `callback` provided. */ - getAllMemberships(parametersOrCallback, callback) { + getMemberships(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:', + details: 'Get Memberships with parameters:', })); - const request = new GetAllMembershipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new GetMembershipsRequest(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). + * Set 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. + * @returns Asynchronous set membership response or `void` in case if `callback` provided. */ - updateMembership(parameters, callback) { + setMembership(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:', + details: 'Set Membership with parameters:', })); - const request = new UpdateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new SetMembershipRequest(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). + * Update 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. + * @returns Asynchronous update membership response or `void` in case if `callback` provided. */ - patchMembership(parameters, callback) { + updateMembership(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:', + details: 'Update Membership with parameters:', })); - const request = new PatchMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new UpdateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); if (callback) return this.sendRequest(request, callback); return this.sendRequest(request); diff --git a/dist/web/pubnub.min.js b/dist/web/pubnub.min.js index 38aef7417..7337fa999 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=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.3"},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.bind(globalThis);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.bind(globalThis)}}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})); \ No newline at end of file +!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 j=new Uint8Array(O),k=0;for(i=0;i=0;)y(w,d);else y(w,d);return String.fromCharCode.apply(null,w);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],j=e[r+14],k=e[r+15],w=t(w=a[0],N=a[1],P=a[2],C=a[3],c,7,u[0]),C=t(C,w,N,P,o,12,u[1]),P=t(P,C,w,N,l,17,u[2]),N=t(N,P,C,w,h,22,u[3]);w=t(w,N,P,C,d,7,u[4]),C=t(C,w,N,P,p,12,u[5]),P=t(P,C,w,N,g,17,u[6]),N=t(N,P,C,w,b,22,u[7]),w=t(w,N,P,C,y,7,u[8]),C=t(C,w,N,P,m,12,u[9]),P=t(P,C,w,N,f,17,u[10]),N=t(N,P,C,w,v,22,u[11]),w=t(w,N,P,C,S,7,u[12]),C=t(C,w,N,P,O,12,u[13]),P=t(P,C,w,N,j,17,u[14]),w=s(w,N=t(N,P,C,w,k,22,u[15]),P,C,o,5,u[16]),C=s(C,w,N,P,g,9,u[17]),P=s(P,C,w,N,v,14,u[18]),N=s(N,P,C,w,c,20,u[19]),w=s(w,N,P,C,p,5,u[20]),C=s(C,w,N,P,f,9,u[21]),P=s(P,C,w,N,k,14,u[22]),N=s(N,P,C,w,d,20,u[23]),w=s(w,N,P,C,m,5,u[24]),C=s(C,w,N,P,j,9,u[25]),P=s(P,C,w,N,h,14,u[26]),N=s(N,P,C,w,y,20,u[27]),w=s(w,N,P,C,O,5,u[28]),C=s(C,w,N,P,l,9,u[29]),P=s(P,C,w,N,b,14,u[30]),w=n(w,N=s(N,P,C,w,S,20,u[31]),P,C,p,4,u[32]),C=n(C,w,N,P,y,11,u[33]),P=n(P,C,w,N,v,16,u[34]),N=n(N,P,C,w,j,23,u[35]),w=n(w,N,P,C,o,4,u[36]),C=n(C,w,N,P,d,11,u[37]),P=n(P,C,w,N,b,16,u[38]),N=n(N,P,C,w,f,23,u[39]),w=n(w,N,P,C,O,4,u[40]),C=n(C,w,N,P,c,11,u[41]),P=n(P,C,w,N,h,16,u[42]),N=n(N,P,C,w,g,23,u[43]),w=n(w,N,P,C,m,4,u[44]),C=n(C,w,N,P,S,11,u[45]),P=n(P,C,w,N,k,16,u[46]),w=i(w,N=n(N,P,C,w,l,23,u[47]),P,C,c,6,u[48]),C=i(C,w,N,P,b,10,u[49]),P=i(P,C,w,N,j,15,u[50]),N=i(N,P,C,w,p,21,u[51]),w=i(w,N,P,C,S,6,u[52]),C=i(C,w,N,P,h,10,u[53]),P=i(P,C,w,N,f,15,u[54]),N=i(N,P,C,w,o,21,u[55]),w=i(w,N,P,C,y,6,u[56]),C=i(C,w,N,P,k,10,u[57]),P=i(P,C,w,N,g,15,u[58]),N=i(N,P,C,w,O,21,u[59]),w=i(w,N,P,C,d,6,u[60]),C=i(C,w,N,P,v,10,u[61]),P=i(P,C,w,N,l,15,u[62]),N=i(N,P,C,w,m,21,u[63]);a[0]=a[0]+w|0,a[1]=a[1]+N|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],j=257*p[m]^16843008*m;r[b]=j<<24|j>>>8,a[b]=j<<16|j>>>16,o[b]=j<<8|j>>>24,c[b]=j,j=16843009*O^65537*v^257*f^16843008*b,u[m]=j<<24|j>>>8,l[m]=j<<16|j>>>16,h[m]=j<<8|j>>>24,d[m]=j,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=t(S);class j{constructor({cipherKey:e}){this.cipherKey=e,this.CryptoJS=O,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 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 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 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(j.BLOCK_SIZE))}getKey(){return r(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),C=e=>encodeURIComponent(e).replace(/[!~*'()]/g,(e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)),P=(e,t)=>{const s=e.map((e=>C(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}=${C(e)}`)).join("&"):`${t}=${C(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),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}`},R=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")};function D(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 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},null!=s?s:{}),details:"Encrypt with parameters:",ignoredKeys:w}))),s=this.parseOptions(s);const i=this.getMode(s),r=this.getPaddedKey(n,s);if(this.configuration.useRandomIVs){const t=this.getRandomIV(),s=O.AES.encrypt(e,r,{iv:t,mode:i}).ciphertext;return t.clone().concat(s.clone()).toString(O.enc.Base64)}const a=this.getIV(s);return O.AES.encrypt(e,r,{iv:a,mode:i}).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},null!=s?s:{}),details:"Decrypt with parameters:",ignoredKeys:w}))),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=D(t.slice(0,16)),n=D(t.slice(16));try{const e=O.AES.decrypt({ciphertext:n},r,{iv:s,mode:i}).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},r,{iv:t,mode:i}).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,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?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 A{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=A.encoder.encode(t).buffer,i=yield crypto.subtle.encrypt({name:"AES-CBC",iv:s},e,n),r=this.concatArrayBuffer(s.buffer,i);return A.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(A.IV_LENGTH).byteLength<=0)throw new Error("decryption error: empty content");return yield crypto.subtle.decrypt({name:"AES-CBC",iv:s},e,t.slice(A.IV_LENGTH))}))}decryptString(e,t){return r(this,void 0,void 0,(function*(){const s=A.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 A.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",A.encoder.encode(e)),s=Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join(""),n=A.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}}A.IV_LENGTH=16,A.encoder=new TextEncoder,A.decoder=new TextDecoder;class ${constructor(e){this.config=e,this.cryptor=new U(Object.assign({},e)),this.fileCryptor=new A}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 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`LegacyCryptor { ${Object.entries(this.config).reduce(((e,[t,s])=>("logger"===t||w(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 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 $(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 r(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),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=x.tryParse(s),i=this.getCryptor(n);if((null==i?void 0:i.identifier)===x.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 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 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")}))}}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,i=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(i=t[4],i>x.MAX_VERSION)throw new Error("Decryption error: Unknown cryptor error");let r=5+x.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 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=h.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=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 G(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 G(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,G.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)))}}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.PNCreateDataSyncEntityOperation="PNCreateDataSyncEntityOperation",e.PNGetDataSyncEntityOperation="PNGetDataSyncEntityOperation",e.PNGetDataSyncEntitiesOperation="PNGetDataSyncEntitiesOperation",e.PNSetDataSyncEntityOperation="PNSetDataSyncEntityOperation",e.PNUpdateDataSyncEntityOperation="PNUpdateDataSyncEntityOperation",e.PNRemoveDataSyncEntityOperation="PNRemoveDataSyncEntityOperation",e.PNCreateDataSyncRelationshipOperation="PNCreateDataSyncRelationshipOperation",e.PNGetDataSyncRelationshipOperation="PNGetDataSyncRelationshipOperation",e.PNGetDataSyncRelationshipsOperation="PNGetDataSyncRelationshipsOperation",e.PNSetDataSyncRelationshipOperation="PNSetDataSyncRelationshipOperation",e.PNUpdateDataSyncRelationshipOperation="PNUpdateDataSyncRelationshipOperation",e.PNRemoveDataSyncRelationshipOperation="PNRemoveDataSyncRelationshipOperation",e.PNCreateDataSyncUserOperation="PNCreateDataSyncUserOperation",e.PNGetDataSyncUserOperation="PNGetDataSyncUserOperation",e.PNGetDataSyncUsersOperation="PNGetDataSyncUsersOperation",e.PNSetDataSyncUserOperation="PNSetDataSyncUserOperation",e.PNUpdateDataSyncUserOperation="PNUpdateDataSyncUserOperation",e.PNRemoveDataSyncUserOperation="PNRemoveDataSyncUserOperation",e.PNCreateDataSyncChannelOperation="PNCreateDataSyncChannelOperation",e.PNGetDataSyncChannelOperation="PNGetDataSyncChannelOperation",e.PNGetDataSyncChannelsOperation="PNGetDataSyncChannelsOperation",e.PNSetDataSyncChannelOperation="PNSetDataSyncChannelOperation",e.PNUpdateDataSyncChannelOperation="PNUpdateDataSyncChannelOperation",e.PNRemoveDataSyncChannelOperation="PNRemoveDataSyncChannelOperation",e.PNCreateDataSyncMembershipOperation="PNCreateDataSyncMembershipOperation",e.PNGetDataSyncMembershipOperation="PNGetDataSyncMembershipOperation",e.PNGetDataSyncMembershipsOperation="PNGetDataSyncMembershipsOperation",e.PNSetDataSyncMembershipOperation="PNSetDataSyncMembershipOperation",e.PNUpdateDataSyncMembershipOperation="PNUpdateDataSyncMembershipOperation",e.PNRemoveDataSyncMembershipOperation="PNRemoveDataSyncMembershipOperation",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: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 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 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),[i,r,a]=e.split(".").map(Number);return i>t||r>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 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)?B(c,t+1):c})),i}const W=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,j=!1,k=100,w=!0;return void 0!==m.dedupeOnSubscribe&&"boolean"==typeof m.dedupeOnSubscribe&&(j=m.dedupeOnSubscribe),void 0!==m.maximumCacheSize&&"number"==typeof m.maximumCacheSize&&(k=m.maximumCacheSize),void 0!==m.useRequestId&&"boolean"==typeof m.useRequestId&&(w=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:j,maximumCacheSize:k,useRequestId:w,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 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,i=n.queryParameters&&Object.keys(n.queryParameters).length>0?T(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===V.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}${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,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} }`:` ${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,i,r)=>(!s||s!==h.PNCancelledCategory&&s!==h.PNBadRequestCategory&&s!==h.PNAccessDeniedCategory)&&(!Y(e,r)&&(!(n>i)&&(!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[i](r)))}}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 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)}(te,te.exports);var se=t(te.exports),ne={createUUID:()=>se.uuid?se.uuid():se()};const ie=(e,t)=>{var s,n,i,r;!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!==(i=e.useRandomIVs)&&void 0!==i||(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=re(null!==(r=e.ssl)&&void 0!==r&&r,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.3"},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},re=(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){var t,s;const n=this.cbor.decodeToken(e);if(void 0!==n){const e=n.res.uuid?Object.keys(n.res.uuid):[],i=Object.keys(n.res.chan),r=Object.keys(n.res.grp),a=n.pat.uuid?Object.keys(n.pat.uuid):[],o=Object.keys(n.pat.chan),c=Object.keys(n.pat.grp),u={version:n.v,timestamp:n.t,ttl:n.ttl,authorized_uuid:n.uuid,signature:n.sig},l=e.length>0,h=i.length>0,d=r.length>0;if(l||h||d){if(u.resources={},l){const t=u.resources.uuids={};e.forEach((e=>t[e]=this.extractPermissions(n.res.uuid[e])))}if(h){const e=u.resources.channels={};i.forEach((t=>e[t]=this.extractPermissions(n.res.chan[t])))}if(d){const e=u.resources.groups={};r.forEach((t=>e[t]=this.extractPermissions(n.res.grp[t])))}}const p=this.extractDataSyncScopes(n.res);p&&((null!==(t=u.resources)&&void 0!==t?t:u.resources={}).dataSync=p);const g=a.length>0,b=o.length>0,y=c.length>0;if(g||b||y){if(u.patterns={},g){const e=u.patterns.uuids={};a.forEach((t=>e[t]=this.extractPermissions(n.pat.uuid[t])))}if(b){const e=u.patterns.channels={};o.forEach((t=>e[t]=this.extractPermissions(n.pat.chan[t])))}if(y){const e=u.patterns.groups={};c.forEach((t=>e[t]=this.extractPermissions(n.pat.grp[t])))}}const m=this.extractDataSyncScopes(n.pat);return m&&((null!==(s=u.patterns)&&void 0!==s?s:u.patterns={}).dataSync=m),n.meta&&Object.keys(n.meta).length>0&&(u.meta=n.meta),u}}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}extractDataSyncScopes(e){let t;return[["entities","datasync:entities"],["relationships","datasync:relationships"],["memberships","datasync:memberships"]].forEach((([s,n])=>{const i=e[n];if(!i)return;const r=Object.keys(i);if(0===r.length)return;const a=(null!=t?t:t={})[s]={};r.forEach((e=>a[e]=this.extractDataSyncPermissions(i[e])))})),t}extractDataSyncPermissions(e){return{create:!(16&~e),get:!(32&~e),update:!(64&~e),delete:!(8&~e)}}}var ce;!function(e){e.GET="GET",e.POST="POST",e.PATCH="PATCH",e.PUT="PUT",e.DELETE="DELETE",e.LOCAL="LOCAL"}(ce||(ce={}));const ue=[404,409];class le{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=le.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}=${C(e)}`)).join("&"):`${t}=${C(s)}`})).join("&")}}le.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 le(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=null==i?void 0:i.statusCode,d=(!s||s.status>=400)&&!ue.includes(l);let p=-1;r&&d&&t.shouldRetry(e,s,null==i?void 0:i.category,a+1)&&(p=t.getDelay(a,s)),p>0?(a++,this.logger.warn("PubNubMiddleware",`HTTP request retry #${a} in ${p}ms.`),n=setTimeout((()=>u()),p)):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 de{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&&(de.originalFetch=de.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 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 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([de.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(G.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?de.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}?${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.bind(globalThis);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.bind(globalThis)}}de.encoder=new TextEncoder,de.decoder=new TextDecoder;class pe{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 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: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!==(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===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=pe.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}}pe.decoder=new TextDecoder;var ge;!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"}(ge||(ge={}));const be={user:"user",channel:"channel",membership:"membership"};class ye extends pe{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 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 r(this,void 0,void 0,(function*(){let t,s;try{s=pe.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")?ge.Presence:ge.Message);const s=R(e.d);if(t!=ge.Signal&&"string"==typeof e.d)return t==ge.Message?{type:ge.Message,data:this.messageFromEnvelope(e),pn_mfp:s}:{type:ge.Files,data:this.fileFromEnvelope(e),pn_mfp:s};if(t==ge.Message)return{type:ge.Message,data:this.messageFromEnvelope(e),pn_mfp:s};if(t===ge.Presence)return{type:ge.Presence,data:this.presenceEventFromEnvelope(e),pn_mfp:s};if(t==ge.Signal)return{type:ge.Signal,data:this.signalFromEnvelope(e),pn_mfp:s};if(t===ge.AppContext)return{type:ge.AppContext,data:this.appContextFromEnvelope(e),pn_mfp:s};if(t===ge.MessageAction)return{type:ge.MessageAction,data:this.messageActionFromEnvelope(e),pn_mfp:s};if(t===ge.DataSync){const t=this.dataSyncFromEnvelope(e);return t?{type:ge.DataSync,data:t,pn_mfp:s}:{type:ge.Message,data:this.messageFromEnvelope(e),pn_mfp:s}}return{type:ge.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}}dataSyncFromEnvelope(e){var t;const[s,n]=this.subscriptionChannelFromEnvelope(e),i=e.d,r=null==i?void 0:i.metadata;if(!r||"data-sync"!==r.source||!r.event||!r.type)return;const a=r.className?r.className.split(":"):[],o=a.filter((e=>e.length>0)),c=o.length>0?o[o.length-1]:void 0,u=r.classLevel,l=void 0===u?a[0]:"Global"===u?c:void 0,h=l&&be[l.toLowerCase()]||r.type,d=void 0!==r.classVersion?Number.parseInt(`${r.classVersion}`,10):NaN,p=Number.isNaN(d)?void 0:d,g=null!==(t=i.data)&&void 0!==t?t:{};let b;return b="delete"===r.event?{id:g.id,deletedAt:g.deletedAt}:(r.type,Object.assign({},g)),{channel:s,subscription:n,timetoken:e.p.t,message:{version:i.version,event:r.event,source:r.source,type:r.type,objectType:h,className:c,classLevel:u,classVersion:p,data:b}}}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(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 ye{get path(){var e;const{keySet:{subscribeKey:t},channels:s}=this.parameters;return`/v2/subscribe/${t}/${P(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 fe{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===ge.Message)this.announce("message",e.data);else if(e.type===ge.Signal)this.announce("signal",e.data);else if(e.type===ge.Presence)this.announce("presence",e.data);else if(e.type===ge.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===ge.MessageAction?this.announce("messageAction",e.data):e.type===ge.Files?this.announce("file",e.data):e.type===ge.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 ve{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 Se{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=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: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 je{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 ke extends je{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 we extends je{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 Ce{constructor(e,t){this._payload={apns:{},fcm:{}},this._title=e,this._body=t,this.apns=new ke(this._payload.apns,e,t),this.fcm=new we(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 Ne{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 Ee 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 Ne(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 Te{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 _e(e,t){const s=function(...s){return{type:e,payload:null==t?void 0:t(...s)}};return s.type=e,s}function Ie(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 De 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 De}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),Fe=Me("HEARTBEAT",((e,t)=>({channels:e,groups:t}))),xe=Ie("LEAVE",((e,t)=>({channels:e,groups:t}))),qe=Ie("EMIT_STATUS",(e=>e)),Ge=Me("WAIT",(()=>({}))),Le=_e("RECONNECT",(()=>({}))),Ke=_e("DISCONNECT",((e=!1)=>({isOffline:e}))),He=_e("JOINED",((e,t)=>({channels:e,groups:t}))),Be=_e("LEFT",((e,t)=>({channels:e,groups:t}))),We=_e("LEFT_ALL",((e=!1)=>({isOffline:e}))),Ve=_e("HEARTBEAT_SUCCESS",(e=>({statusCode:e}))),ze=_e("HEARTBEAT_FAILURE",(e=>e)),Je=_e("TIMES_UP",(()=>({})));class Xe extends Te{constructor(e,t){super(t,t.config.logger()),this.on(Fe.type,$e(((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(Ve(200))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;e.transition(ze(t))}}}))))),this.on(xe.type,$e(((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(Ge.type,$e(((t,s,n)=>r(this,[t,s,n],void 0,(function*(t,s,{heartbeatDelay:n}){return s.throwIfAborted(),yield n(),s.throwIfAborted(),e.transition(Je())}))))),this.on(qe.type,$e(((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:K.PNHeartbeatOperation})):n.announceSuccessfulHeartbeats&&200===e.statusCode&&s(Object.assign(Object.assign({},e),{error:!1,operation:K.PNHeartbeatOperation,category:h.PNAcknowledgmentCategory}))})))))}}const Qe=new Ne("HEARTBEAT_STOPPED");Qe.on(He.type,((e,t)=>Qe.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(Be.type,((e,t)=>Qe.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))}))),Qe.on(Le.type,((e,t)=>et.with({channels:e.channels,groups:e.groups}))),Qe.on(We.type,((e,t)=>tt.with(void 0)));const Ye=new Ne("HEARTBEAT_COOLDOWN");Ye.onEnter((()=>Ge())),Ye.onExit((()=>Ge.cancel)),Ye.on(Je.type,((e,t)=>et.with({channels:e.channels,groups:e.groups}))),Ye.on(He.type,((e,t)=>et.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(Be.type,((e,t)=>et.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[xe(t.payload.channels,t.payload.groups)]))),Ye.on(Ke.type,((e,t)=>Qe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]]))),Ye.on(We.type,((e,t)=>tt.with(void 0,[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]])));const Ze=new Ne("HEARTBEAT_FAILED");Ze.on(He.type,((e,t)=>et.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(Be.type,((e,t)=>et.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[xe(t.payload.channels,t.payload.groups)]))),Ze.on(Le.type,((e,t)=>et.with({channels:e.channels,groups:e.groups}))),Ze.on(Ke.type,((e,t)=>Qe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]]))),Ze.on(We.type,((e,t)=>tt.with(void 0,[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]])));const et=new Ne("HEARTBEATING");et.onEnter((e=>Fe(e.channels,e.groups))),et.onExit((()=>Fe.cancel)),et.on(Ve.type,((e,t)=>Ye.with({channels:e.channels,groups:e.groups},[qe(Object.assign({},t.payload))]))),et.on(He.type,((e,t)=>et.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)))]}))),et.on(Be.type,((e,t)=>et.with({channels:e.channels.filter((e=>!t.payload.channels.includes(e))),groups:e.groups.filter((e=>!t.payload.groups.includes(e)))},[xe(t.payload.channels,t.payload.groups)]))),et.on(ze.type,((e,t)=>Ze.with(Object.assign({},e),[...t.payload.status?[qe(Object.assign({},t.payload.status))]:[]]))),et.on(Ke.type,((e,t)=>Qe.with({channels:e.channels,groups:e.groups},[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]]))),et.on(We.type,((e,t)=>tt.with(void 0,[...t.payload.isOffline?[]:[xe(e.channels,e.groups)]])));const tt=new Ne("HEARTBEAT_INACTIVE");tt.on(He.type,((e,t)=>et.with({channels:t.payload.channels,groups:t.payload.groups})));class st{get _engine(){return this.engine}constructor(e){this.dependencies=e,this.channels=[],this.groups=[],this.engine=new Ee(e.config.logger()),this.dispatcher=new Xe(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(tt,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(He(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(Be(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(We(e))}reconnect(){this.engine.transition(Le())}disconnect(e=!1){this.engine.transition(Ke(e))}dispose(){this.disconnect(!0),this._unsubscribeEngine(),this.dispatcher.dispose()}}const nt=Me("HANDSHAKE",((e,t,s)=>({channels:e,groups:t,onDemand:s}))),it=Me("RECEIVE_MESSAGES",((e,t,s,n)=>({channels:e,groups:t,cursor:s,onDemand:n}))),rt=Ie("EMIT_MESSAGES",((e,t)=>({cursor:e,events:t}))),at=Ie("EMIT_STATUS",(e=>e)),ot=_e("SUBSCRIPTION_CHANGED",((e,t,s=!1)=>({channels:e,groups:t,isOffline:s}))),ct=_e("SUBSCRIPTION_RESTORED",((e,t,s,n)=>({channels:e,groups:t,cursor:{timetoken:s,region:null!=n?n:0}}))),ut=_e("HANDSHAKE_SUCCESS",(e=>e)),lt=_e("HANDSHAKE_FAILURE",(e=>e)),ht=_e("RECEIVE_SUCCESS",((e,t)=>({cursor:e,events:t}))),dt=_e("RECEIVE_FAILURE",(e=>e)),pt=_e("DISCONNECT",((e=!1)=>({isOffline:e}))),gt=_e("RECONNECT",((e,t)=>({cursor:{timetoken:null!=e?e:"",region:null!=t?t:0}}))),bt=_e("UNSUBSCRIBE_ALL",(()=>({}))),yt=new Ne("UNSUBSCRIBED");yt.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,onDemand:!0}))),yt.on(ct.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region},onDemand:!0})));const mt=new Ne("HANDSHAKE_STOPPED");mt.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):mt.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),mt.on(gt.type,((e,{payload:t})=>vt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),mt.on(ct.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?yt.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(bt.type,(e=>yt.with()));const ft=new Ne("HANDSHAKE_FAILED");ft.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),ft.on(gt.type,((e,{payload:t})=>vt.with(Object.assign(Object.assign({},e),{cursor:t.cursor||e.cursor,onDemand:!0})))),ft.on(ct.type,((e,{payload:t})=>{var s,n;return 0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.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})})),ft.on(bt.type,(e=>yt.with()));const vt=new Ne("HANDSHAKING");vt.onEnter((e=>{var t;return nt(e.channels,e.groups,null!==(t=e.onDemand)&&void 0!==t&&t)})),vt.onExit((()=>nt.cancel)),vt.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),vt.on(ut.type,((e,{payload:t})=>{var s,n,i,r,a;return jt.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===(i=e.cursor)||void 0===i?void 0:i.timetoken)},[at({category:h.PNConnectedCategory,affectedChannels:e.channels.slice(0),affectedChannelGroups:e.groups.slice(0),operation:K.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})])})),vt.on(lt.type,((e,t)=>{var s;return ft.with(Object.assign(Object.assign({},e),{reason:t.payload}),[at({category:h.PNConnectionErrorCategory,error:null===(s=t.payload.status)||void 0===s?void 0:s.category})])})),vt.on(pt.type,((e,t)=>{var s;if(t.payload.isOffline){const t=G.create(new Error("Network connection error")).toPubNubError(K.PNSubscribeOperation);return ft.with(Object.assign(Object.assign({},e),{reason:t}),[at({category:h.PNConnectionErrorCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return mt.with(Object.assign({},e))})),vt.on(ct.type,((e,{payload:t})=>{var s;return 0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.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})})),vt.on(bt.type,(e=>yt.with()));const St=new Ne("RECEIVE_STOPPED");St.on(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):St.with({channels:t.channels,groups:t.groups,cursor:e.cursor}))),St.on(ct.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):St.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region}}))),St.on(gt.type,((e,{payload:t})=>{var s;return vt.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})})),St.on(bt.type,(()=>yt.with(void 0)));const Ot=new Ne("RECEIVE_FAILED");Ot.on(gt.type,((e,{payload:t})=>{var s;return vt.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(ot.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,onDemand:!0}))),Ot.on(ct.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0):vt.with({channels:t.channels,groups:t.groups,cursor:{timetoken:`${t.cursor.timetoken}`,region:t.cursor.region||e.cursor.region},onDemand:!0}))),Ot.on(bt.type,(e=>yt.with(void 0)));const jt=new Ne("RECEIVING");jt.onEnter((e=>{var t;return it(e.channels,e.groups,e.cursor,null!==(t=e.onDemand)&&void 0!==t&&t)})),jt.onExit((()=>it.cancel)),jt.on(ht.type,((e,{payload:t})=>jt.with({channels:e.channels,groups:e.groups,cursor:t.cursor,referenceTimetoken:I(t.cursor.timetoken)},[rt(e.cursor,t.events)]))),jt.on(ot.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),yt.with(void 0,[at(Object.assign({category:t.isOffline?h.PNDisconnectedUnexpectedlyCategory:h.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation},e?{error:e}:{}))])}return jt.with({channels:t.channels,groups:t.groups,cursor:e.cursor,referenceTimetoken:e.referenceTimetoken,onDemand:!0},[at({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:e.cursor.timetoken})])})),jt.on(ct.type,((e,{payload:t})=>0===t.channels.length&&0===t.groups.length?yt.with(void 0,[at({category:h.PNDisconnectedCategory})]):jt.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},[at({category:h.PNSubscriptionChangedCategory,affectedChannels:t.channels.slice(0),affectedChannelGroups:t.groups.slice(0),currentTimetoken:t.cursor.timetoken})]))),jt.on(dt.type,((e,{payload:t})=>{var s;return Ot.with(Object.assign(Object.assign({},e),{reason:t}),[at({category:h.PNDisconnectedUnexpectedlyCategory,error:null===(s=t.status)||void 0===s?void 0:s.category})])})),jt.on(pt.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}),[at({category:h.PNDisconnectedUnexpectedlyCategory,operation:K.PNSubscribeOperation,error:null===(s=t.status)||void 0===s?void 0:s.category})])}return St.with(Object.assign({},e),[at({category:h.PNDisconnectedCategory,operation:K.PNSubscribeOperation})])})),jt.on(bt.type,(e=>yt.with(void 0,[at({category:h.PNDisconnectedCategory,operation:K.PNUnsubscribeOperation})])));class kt extends Te{constructor(e,t){super(t,t.config.logger()),this.on(nt.type,$e(((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(ut(a))}catch(t){if(t instanceof d){if(t.status&&t.status.category==h.PNCancelledCategory)return;return e.transition(lt(t))}}}))))),this.on(it.type,$e(((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(ht(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(dt(t))}}}))))),this.on(rt.type,$e(((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(at.type,$e(((e,t,s)=>r(this,[e,t,s],void 0,(function*(e,t,{emitStatus:s}){return s(e)})))))}}class wt{get _engine(){return this.engine}constructor(e){this.channels=[],this.groups=[],this.dependencies=e,this.engine=new Ee(e.config.logger()),this.dispatcher=new kt(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(yt,void 0)}get subscriptionTimetoken(){const e=this.engine.currentState;if(!e)return;let t,s="0";if(e.label===jt.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 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(ct(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(ot(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)===jt.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=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 i=E(this.channels,e),r=E(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(ot(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(ot(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(gt(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(pt(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 Ct extends pe{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 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/${C(t)}/0${this.parameters.sendByPost?"":`/${C(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 Pt extends pe{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 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/${C(s)}/0/${C(i)}`}get queryParameters(){const{customMessageType:e}=this.parameters,t={};return e&&(t.custom_message_type=e),t}}class Nt extends ye{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}/${P(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 Et extends ye{operation(){return K.PNHandshakeOperation}get path(){const{keySet:{subscribeKey:e},channels:t=[]}=this.parameters;return`/v2/subscribe/${e}/${P(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 Tt;!function(e){e[e.Channel=0]="Channel",e[e.ChannelGroup=1]="ChannelGroup"}(Tt||(Tt={}));class _t{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 _t({channels:[...this._channels,...e._channels],channelGroups:[...this._channelGroups,...e._channelGroups]})}without(e){return new _t({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 It{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 fe,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 It{constructor(e){const t=new _t({});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 Dt 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 Dt({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 It{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 _t({[e.entity.subscriptionType==Tt.Channel?"channels":"channelGroups"]:n});super(e.client,i,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=R(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 _t({}):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 Dt({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 pe{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 K.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/${P(null!=s?s:[],",")}/uuid/${C(null!=t?t:"")}`}get queryParameters(){const{channelGroups:e}=this.parameters;return e&&0!==e.length?{"channel-group":e.join(",")}:{}}}class Ft extends pe{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 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/${P(null!=s?s:[],",")}/uuid/${C(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 xt extends pe{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 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/${P(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 qt extends pe{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 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/${P(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 Gt extends pe{constructor(e){super(),this.parameters=e}operation(){return K.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/${C(t)}`}}class Lt extends pe{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?K.PNGlobalHereNowOperation:K.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/${P(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()===K.PNHereNowOperation?{limit:n}:{}),this.operation()===K.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 Kt extends pe{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 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/${C(t)}`}get queryParameters(){const{start:e,end:t}=this.parameters;return Object.assign(Object.assign({},e?{start:e}:{}),t?{end:t}:{})}}class Ht extends pe{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 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/${P(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 Bt extends pe{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 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/${C(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(Bt.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 Wt;!function(e){e[e.Message=-1]="Message",e[e.Files=4]="Files"}(Wt||(Wt={}));class Vt extends pe{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 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 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=Wt.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/${P(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(Vt.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==Wt.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 zt extends pe{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 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/${C(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 Jt extends pe{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 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/${C(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 Xt extends pe{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 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/${C(t)}/message/${n}/action/${s}`}}class Qt extends pe{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 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/${C(t)}/0/${C(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 Yt extends pe{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 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/${C(e)}/files/${C(t)}/${C(s)}`}}class Zt extends pe{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/${C(s)}/files/${C(t)}/${C(n)}`}}class es extends pe{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/${C(t)}/files`}get queryParameters(){const{limit:e,next:t}=this.parameters;return Object.assign({limit:e},t?{next:t}:{})}}class ts extends pe{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 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/${C(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 ss extends pe{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 r(this,void 0,void 0,(function*(){return{status:e.status,message:e.body?ss.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 ns{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: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 r(this,void 0,void 0,(function*(){const e=new ts(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 ss({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 is{constructor(e,t){this.subscriptionStateIds=[],this.client=t,this._nameOrId=e}get entityType(){return"Channel"}get subscriptionType(){return Tt.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 is{get entityType(){return"ChannelMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class as extends is{get entityType(){return"ChannelGroups"}get name(){return this._nameOrId}get subscriptionType(){return Tt.ChannelGroup}}class os extends is{get entityType(){return"UserMetadata"}get id(){return this._nameOrId}subscriptionNames(e){return[this.id]}}class cs extends is{get entityType(){return"Channel"}get name(){return this._nameOrId}}class us extends pe{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 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/${C(t)}`}get queryParameters(){return{remove:this.parameters.channels.join(",")}}}class ls extends pe{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 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/${C(t)}`}get queryParameters(){return{add:this.parameters.channels.join(",")}}}class hs extends pe{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 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/${C(t)}`}}class ds extends pe{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 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/${C(t)}/remove`}}class ps extends pe{constructor(e){super(),this.parameters=e}operation(){return K.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 gs{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 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 r(this,void 0,void 0,(function*(){this.logger.debug("PubNub","List all channel groups.");const t=new ps({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 ls(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 us(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 ds(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 bs extends pe{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 ys extends bs{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 r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class ms extends bs{constructor(e){super(Object.assign(Object.assign({},e),{action:"list"}))}operation(){return K.PNPushNotificationEnabledChannelsOperation}parse(e){return r(this,void 0,void 0,(function*(){return{channels:this.deserializeResponse(e)}}))}}class fs extends bs{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 r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class vs extends bs{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 r(this,void 0,void 0,(function*(){return t.parse.call(this,e).then((e=>({})))}))}}class Ss{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 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 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 fs(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 ys(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 vs(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 pe{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 K.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 js extends pe{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/${C(t)}`}}class ks extends pe{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 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/${C(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 ws extends pe{constructor(e){var t,s,n,i,r,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!==(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 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/${C(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 Cs extends pe{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 K.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 Ps extends pe{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/${C(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}}class Ns extends pe{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/${C(t)}`}get queryParameters(){return{include:["status","type",...this.parameters.include.customFields?["custom"]:[]].join(",")}}get body(){return JSON.stringify(this.parameters.data)}}class Es extends pe{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/${C(t)}`}}class Ts extends pe{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 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/${C(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 _s extends pe{constructor(e){var t,s,n,i,r,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!==(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 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/${C(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 Is extends pe{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/${C(t)}`}get queryParameters(){const{include:e}=this.parameters;return{include:["status","type",...e.customFields?["custom"]:[]].join(",")}}}class Ms extends pe{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/${C(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 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 Cs(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 Is(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 Ms(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 Es(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 Os(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 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 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 Ns(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 js(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 Ts(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 _s(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 _s(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 ks(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 ws(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 ws(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 Ds extends pe{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateDataSyncUserOperation}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"User data 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(){const{id:e,classLevel:t,data:s}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{id:e}:{}),{entityClassVersion:s.classVersion}),void 0!==t?{entityClassLevel:t}:{}),void 0!==s.status?{status:s.status}:{}),void 0!==s.payload?{payload:s.payload}:{})})}}function Us(e){return"string"==typeof e?e:Object.entries(null!=e?e:{}).map((([e,t])=>null!==t?`${e}:${t}`:e))}function As(e){return"/"+e.split(".").join("/")}function $s(e){const{add:t,replace:s,remove:n,move:i,copy:r,test:a}=e,o=[];if(t)for(const[e,s]of Object.entries(t))o.push({op:"add",path:As(e),value:s});if(s)for(const[e,t]of Object.entries(s))o.push({op:"replace",path:As(e),value:t});if(n)for(const e of n)o.push({op:"remove",path:As(e)});if(i)for(const{from:e,path:t}of i)o.push({op:"move",from:As(e),path:As(t)});if(r)for(const{from:e,path:t}of r)o.push({op:"copy",from:As(e),path:As(t)});if(a)for(const[e,t]of Object.entries(a))o.push({op:"test",path:As(e),value:t});return o}class Fs extends pe{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetDataSyncUsersOperation}parse(e){return r(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:i,filterAdvanced:r}=this.parameters,a=Us(i);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}:{}),a.length?{sort:a}:{}),r?{filter_advanced:r}:{})}}class xs extends pe{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNSetDataSyncUserOperation}parse(e){return r(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.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"User data 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/${C(t)}`}get body(){const{data:e}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign({entityClassVersion:e.classVersion},void 0!==e.status?{status:e.status}:{}),void 0!==e.payload?{payload:e.payload}:{})})}}class qs extends pe{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveDataSyncUserOperation}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 r(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/${C(t)}`}}class Gs extends pe{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNUpdateDataSyncUserOperation}parse(e){return r(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{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=e&&Object.keys(e).length>0,o=t&&Object.keys(t).length>0,c=s&&s.length>0,u=n&&n.length>0,l=i&&i.length>0,h=r&&Object.keys(r).length>0;return a||o||c||u||l||h?void 0:"At least one of add, replace, remove, move, copy, or test 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/${C(t)}`}get body(){const{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=$s({add:e,replace:t,remove:s,move:n,copy:i,test:r});return JSON.stringify(a)}}class Ls extends pe{constructor(e){super(),this.parameters=e}operation(){return K.PNGetDataSyncUserOperation}parse(e){return r(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/${C(t)}`}}class Ks extends pe{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateDataSyncChannelOperation}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"Channel data 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(){const{id:e,classLevel:t,data:s}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{id:e}:{}),{entityClassVersion:s.classVersion}),void 0!==t?{entityClassLevel:t}:{}),void 0!==s.status?{status:s.status}:{}),void 0!==s.payload?{payload:s.payload}:{})})}}class Hs extends pe{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetDataSyncChannelsOperation}parse(e){return r(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:i,filterAdvanced:r}=this.parameters,a=Us(i);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}:{}),a.length?{sort:a}:{}),r?{filter_advanced:r}:{})}}class Bs extends pe{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNSetDataSyncChannelOperation}parse(e){return r(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.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"Channel data 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/${C(t)}`}get body(){const{data:e}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign({entityClassVersion:e.classVersion},void 0!==e.status?{status:e.status}:{}),void 0!==e.payload?{payload:e.payload}:{})})}}class Ws extends pe{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveDataSyncChannelOperation}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 r(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/${C(t)}`}}class Vs extends pe{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNUpdateDataSyncChannelOperation}parse(e){return r(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{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=e&&Object.keys(e).length>0,o=t&&Object.keys(t).length>0,c=s&&s.length>0,u=n&&n.length>0,l=i&&i.length>0,h=r&&Object.keys(r).length>0;return a||o||c||u||l||h?void 0:"At least one of add, replace, remove, move, copy, or test 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/${C(t)}`}get body(){const{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=$s({add:e,replace:t,remove:s,move:n,copy:i,test:r});return JSON.stringify(a)}}class zs extends pe{constructor(e){super(),this.parameters=e}operation(){return K.PNGetDataSyncChannelOperation}parse(e){return r(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/${C(t)}`}}class Js extends pe{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateDataSyncMembershipOperation}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.userId?this.parameters.channelId?this.parameters.data?this.parameters.data.classVersion?void 0:"Relationship class version cannot be empty":"Membership data cannot be empty":"Channel id cannot be empty":"User id 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(){const{id:e,userId:t,channelId:s,data:n}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{id:e}:{}),{userId:t,channelId:s,relationshipClassVersion:n.classVersion}),void 0!==n.status?{status:n.status}:{}),void 0!==n.payload?{payload:n.payload}:{})})}}class Xs extends pe{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetDataSyncMembershipsOperation}parse(e){return r(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:i,filter:r,sort:a,filterAdvanced:o}=this.parameters,c=Us(a);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}:{}),i?{limit:`${i}`}:{}),r?{filter:r}:{}),c.length?{sort:c}:{}),o?{filter_advanced:o}:{})}}class Qs extends pe{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNSetDataSyncMembershipOperation}parse(e){return r(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.userId?this.parameters.channelId?this.parameters.data?this.parameters.data.classVersion?void 0:"Relationship class version cannot be empty":"Membership data cannot be empty":"Channel id cannot be empty":"User id 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/${C(t)}`}get body(){const{userId:e,channelId:t,data:s}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign({userId:e,channelId:t,relationshipClassVersion:s.classVersion},void 0!==s.status?{status:s.status}:{}),void 0!==s.payload?{payload:s.payload}:{})})}}class Ys extends pe{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveDataSyncMembershipOperation}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 r(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/${C(t)}`}}class Zs extends pe{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNUpdateDataSyncMembershipOperation}parse(e){return r(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{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=e&&Object.keys(e).length>0,o=t&&Object.keys(t).length>0,c=s&&s.length>0,u=n&&n.length>0,l=i&&i.length>0,h=r&&Object.keys(r).length>0;return a||o||c||u||l||h?void 0:"At least one of add, replace, remove, move, copy, or test 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/${C(t)}`}get body(){const{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=$s({add:e,replace:t,remove:s,move:n,copy:i,test:r});return JSON.stringify(a)}}class en extends pe{constructor(e){super(),this.parameters=e}operation(){return K.PNGetDataSyncMembershipOperation}parse(e){return r(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/${C(t)}`}}class tn extends pe{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateDataSyncRelationshipOperation}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.entityAId?this.parameters.entityBId?this.parameters.class?this.parameters.data?this.parameters.data.classVersion?void 0:"Relationship class version cannot be empty":"Relationship data cannot be empty":"Relationship class cannot be empty":"Entity B id cannot be empty":"Entity A id 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(){const{id:e,class:t,entityAId:s,entityBId:n,data:i}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{id:e}:{}),{entityAId:s,entityBId:n,relationshipClass:t,relationshipClassVersion:i.classVersion}),void 0!==i.status?{status:i.status}:{}),void 0!==i.payload?{payload:i.payload}:{})})}}class sn extends pe{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetDataSyncRelationshipsOperation}parse(e){return r(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:i,limit:r,filter:a,sort:o,filterAdvanced:c}=this.parameters,u=Us(o);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}:{}),i?{cursor:i}:{}),r?{limit:`${r}`}:{}),a?{filter:a}:{}),u.length?{sort:u}:{}),c?{filter_advanced:c}:{})}}class nn extends pe{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNSetDataSyncRelationshipOperation}parse(e){return r(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.entityAId?this.parameters.entityBId?this.parameters.data?this.parameters.data.classVersion?void 0:"Relationship class version cannot be empty":"Relationship data cannot be empty":"Entity B id cannot be empty":"Entity A id 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/${C(t)}`}get body(){const{entityAId:e,entityBId:t,data:s}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign({entityAId:e,entityBId:t,relationshipClassVersion:s.classVersion},void 0!==s.status?{status:s.status}:{}),void 0!==s.payload?{payload:s.payload}:{})})}}class rn extends pe{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveDataSyncRelationshipOperation}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`/v1/datasync/subkeys/${e}/relationships/${C(t)}`}}class an extends pe{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNUpdateDataSyncRelationshipOperation}parse(e){return r(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{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=e&&Object.keys(e).length>0,o=t&&Object.keys(t).length>0,c=s&&s.length>0,u=n&&n.length>0,l=i&&i.length>0,h=r&&Object.keys(r).length>0;return a||o||c||u||l||h?void 0:"At least one of add, replace, remove, move, copy, or test 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/${C(t)}`}get body(){const{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=$s({add:e,replace:t,remove:s,move:n,copy:i,test:r});return JSON.stringify(a)}}class on extends pe{constructor(e){super(),this.parameters=e}operation(){return K.PNGetDataSyncRelationshipOperation}parse(e){return r(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/${C(t)}`}}class cn extends pe{constructor(e){super({method:ce.POST}),this.parameters=e}operation(){return K.PNCreateDataSyncEntityOperation}parse(e){return r(this,void 0,void 0,(function*(){const t=this.deserializeResponse(e);return Object.assign(Object.assign({},t),{status:e.status})}))}validate(){return this.parameters.class?this.parameters.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"Entity data cannot be empty":"Entity class 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(){const{id:e,class:t,classLevel:s,data:n}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},void 0!==e?{id:e}:{}),{entityClass:t,entityClassVersion:n.classVersion}),void 0!==s?{entityClassLevel:s}:{}),void 0!==n.status?{status:n.status}:{}),void 0!==n.payload?{payload:n.payload}:{})})}}class un extends pe{constructor(e){var t;super(),this.parameters=e,null!==(t=e.limit)&&void 0!==t||(e.limit=20)}operation(){return K.PNGetDataSyncEntitiesOperation}parse(e){return r(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:i,sort:r,filterAdvanced:a}=this.parameters,o=Us(r);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}:{}),o.length?{sort:o}:{}),a?{filter_advanced:a}:{})}}class ln extends pe{constructor(e){super({method:ce.PUT}),this.parameters=e}operation(){return K.PNSetDataSyncEntityOperation}parse(e){return r(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.data?void 0===this.parameters.data.classVersion||null===this.parameters.data.classVersion?"Entity class version cannot be empty":void 0:"Entity data 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/${C(t)}`}get body(){const{data:e}=this.parameters;return JSON.stringify({data:Object.assign(Object.assign({entityClassVersion:e.classVersion},void 0!==e.status?{status:e.status}:{}),void 0!==e.payload?{payload:e.payload}:{})})}}class hn extends pe{constructor(e){super({method:ce.DELETE}),this.parameters=e}operation(){return K.PNRemoveDataSyncEntityOperation}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`/v1/datasync/subkeys/${e}/entities/${C(t)}`}}class dn extends pe{constructor(e){super({method:ce.PATCH}),this.parameters=e}operation(){return K.PNUpdateDataSyncEntityOperation}parse(e){return r(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{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=e&&Object.keys(e).length>0,o=t&&Object.keys(t).length>0,c=s&&s.length>0,u=n&&n.length>0,l=i&&i.length>0,h=r&&Object.keys(r).length>0;return a||o||c||u||l||h?void 0:"At least one of add, replace, remove, move, copy, or test 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/${C(t)}`}get body(){const{add:e,replace:t,remove:s,move:n,copy:i,test:r}=this.parameters,a=$s({add:e,replace:t,remove:s,move:n,copy:i,test:r});return JSON.stringify(a)}}class pn extends pe{constructor(e){super(),this.parameters=e}operation(){return K.PNGetDataSyncEntityOperation}parse(e){return r(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/${C(t)}`}}class gn{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 cn(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 pn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getEntities(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Entities with parameters:"})));const s=new un(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}setEntity(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Entity with parameters:"})));const s=new ln(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 dn(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 hn(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 tn(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 on(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getRelationships(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Relationships with parameters:"})));const s=new sn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}setRelationship(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Relationship with parameters:"})));const s=new nn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}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 an(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 rn(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createUser(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create User with parameters:"})));const s=new Ds(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getUser(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get User with parameters:"})));const s=new Ls(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getUsers(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 Users with parameters:"})));const n=new Fs(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}setUser(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set User with parameters:"})));const s=new xs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateUser(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update User with parameters:"})));const s=new Gs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeUser(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove User with parameters:"})));const s=new qs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createChannel(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Channel with parameters:"})));const s=new Ks(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getChannel(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Channel with parameters:"})));const s=new zs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getChannels(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 Channels with parameters:"})));const n=new Hs(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}setChannel(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Channel with parameters:"})));const s=new Bs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateChannel(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Channel with parameters:"})));const s=new Vs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeChannel(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Channel with parameters:"})));const s=new Ws(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}createMembership(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Create Membership with parameters:"})));const s=new Js(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getMembership(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Get Membership with parameters:"})));const s=new en(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}getMemberships(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 Memberships with parameters:"})));const n=new Xs(Object.assign(Object.assign({},s),{keySet:this.keySet}));return t?this.sendRequest(n,t):this.sendRequest(n)}))}setMembership(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Set Membership with parameters:"})));const s=new Qs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}updateMembership(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Update Membership with parameters:"})));const s=new Zs(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}removeMembership(e,t){return r(this,void 0,void 0,(function*(){this.logger.debug("PubNub",(()=>({messageType:"object",message:Object.assign({},e),details:"Remove Membership with parameters:"})));const s=new Ys(Object.assign(Object.assign({},e),{keySet:this.keySet}));return t?this.sendRequest(s,t):this.sendRequest(s)}))}}class bn extends pe{constructor(){super()}operation(){return K.PNTimeOperation}parse(e){return r(this,void 0,void 0,(function*(){return{timetoken:this.deserializeResponse(e)[0]}}))}get path(){return"/time/0"}}class yn extends pe{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 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/${C(t)}/files/${C(s)}/${C(n)}`}}class mn{static notificationPayload(e,t){return new Ce(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 gn(this._configuration,this.sendRequest.bind(this)),this._channelGroups=new gs(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this._push=new Ss(this._configuration.logger(),this._configuration.keySet,this.sendRequest.bind(this)),this.eventDispatcher=new fe,this._configuration.enableEventEngine){this.logger.debug("PubNub","Using new subscription loop management.");let e=this._configuration.getHeartbeatInterval();this.presenceState={},e&&(this.presenceEventEngine=new st({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 wt({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===ge.Message||e.type===ge.Signal?R(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 Oe(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 cs(e,this)),t}channelGroup(e){let t=this.entities[`${e}_chg`];return t||(t=this.entities[`${e}_chg`]=new as(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 os(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 Dt({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===K.PNDownloadFileOperation?i.timeout=this._configuration.getFileTimeout():r===K.PNSubscribeOperation||r===K.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=mn.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(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 Ct(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 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 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 _t({}),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 Dt&&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 _t({}),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 Dt?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===Tt.Channel?t:e;i.some((e=>r.includes(e)))&&s.push(n)};Object.values(this.eventHandleCapable).forEach((e=>{e instanceof Dt?e.subscriptions.forEach((e=>{i(e.state.entity)})):e instanceof At&&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 _t({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 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 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:K.PNUnsubscribeOperation,category:h.PNAcknowledgmentCategory,statusCode:200});this.sendRequest(new qt({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 Et(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 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 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 zt(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 Jt(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 Xt(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 Vt(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 Kt(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 Ht(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 Bt(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 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 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 Gt({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 $t(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 xt(Object.assign(Object.assign({},e),{keySet:i,heartbeat:a})):new Ft(Object.assign(Object.assign({},e),{keySet:i,uuid:r}));const c=e=>{e&&this.logger.debug("PubNub","Set presence state success."+(o instanceof xt?" 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: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 r=new xt(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.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 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 ns(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},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 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 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 Qt(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 es(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 Yt(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}=${C(t)}`)).join("&"):`${e}=${C(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 yn(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 Zt(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 bn,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 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)}))}}mn.decoder=new TextDecoder,mn.OPERATIONS=K,mn.CATEGORIES=h,mn.Endpoint=z,mn.ExponentialRetryPolicy=X.ExponentialRetryPolicy,mn.LinearRetryPolicy=X.LinearRetryPolicy,mn.NoneRetryPolicy=X.None,mn.LogLevel=V;class fn{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 vn extends mn{constructor(e){var t;const s=void 0!==e.subscriptionWorkerUrl,i=W(e),r=Object.assign(Object.assign({},i),{sdkFamily:"Web"});r.PubNubFile=o;const a=ie(r,(e=>{if(e.cipherKey){return new F({default:new $(Object.assign(Object.assign({},e),e.logger?{}:{logger:a.logger()})),cryptors:[new j({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 fn((e=>B(n.decode(e))),c)),(a.getCipherKey()||a.secretKey)&&(l=new U({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 A;let y=new de(a.logger(),r.transport);if(i.subscriptionWorkerUrl)try{const e=new H({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&&"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 he({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:vn.CATEGORIES.PNNetworkDownCategory}),this._configuration.restore?this.disconnect(!0):this.destroy(!0)}networkUpDetected(){this.logger.debug("PubNub","Network up detected"),this.emitStatus({category:vn.CATEGORIES.PNNetworkUpCategory}),this.reconnect()}}return vn.CryptoModule=F,vn})); diff --git a/lib/core/components/token_manager.js b/lib/core/components/token_manager.js index 91bac221a..ecdeabd5a 100644 --- a/lib/core/components/token_manager.js +++ b/lib/core/components/token_manager.js @@ -47,6 +47,7 @@ class TokenManager { * @returns Information about resources and permissions which has been granted for them. */ parseToken(tokenString) { + var _a, _b; const parsed = this.cbor.decodeToken(tokenString); if (parsed !== undefined) { const uuidResourcePermissions = parsed.res.uuid ? Object.keys(parsed.res.uuid) : []; @@ -80,6 +81,9 @@ class TokenManager { groupResourcePermissions.forEach((id) => (groups[id] = this.extractPermissions(parsed.res.grp[id]))); } } + const resourceDataSync = this.extractDataSyncScopes(parsed.res); + if (resourceDataSync) + ((_a = result.resources) !== null && _a !== void 0 ? _a : (result.resources = {})).dataSync = resourceDataSync; const uuidPatterns = uuidPatternPermissions.length > 0; const channelPatterns = channelPatternPermissions.length > 0; const groupPatterns = groupPatternPermissions.length > 0; @@ -98,6 +102,9 @@ class TokenManager { groupPatternPermissions.forEach((id) => (groups[id] = this.extractPermissions(parsed.pat.grp[id]))); } } + const patternDataSync = this.extractDataSyncScopes(parsed.pat); + if (patternDataSync) + ((_b = result.patterns) !== null && _b !== void 0 ? _b : (result.patterns = {})).dataSync = patternDataSync; if (parsed.meta && Object.keys(parsed.meta).length > 0) result.meta = parsed.meta; return result; @@ -137,5 +144,49 @@ class TokenManager { permissionsResult.read = true; 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. + */ + extractDataSyncScopes(section) { + const dataSyncScopes = [ + ['entities', 'datasync:entities'], + ['relationships', 'datasync:relationships'], + ['memberships', 'datasync:memberships'], + ]; + let result; + dataSyncScopes.forEach(([scope, wireKey]) => { + const permissions = section[wireKey]; + if (!permissions) + return; + const ids = Object.keys(permissions); + if (ids.length === 0) + return; + const scopeResult = ((result !== null && result !== void 0 ? result : (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. + */ + extractDataSyncPermissions(permissions) { + return { + create: (permissions & 16) === 16, + get: (permissions & 32) === 32, + update: (permissions & 64) === 64, + delete: (permissions & 8) === 8, + }; + } } exports.TokenManager = TokenManager; diff --git a/lib/core/constants/operations.js b/lib/core/constants/operations.js index 0a9a86dea..8b433afb3 100644 --- a/lib/core/constants/operations.js +++ b/lib/core/constants/operations.js @@ -150,123 +150,123 @@ var RequestOperation; /** * Create entity REST API operation. */ - RequestOperation["PNCreateEntityOperation"] = "PNCreateEntityOperation"; + RequestOperation["PNCreateDataSyncEntityOperation"] = "PNCreateDataSyncEntityOperation"; /** * Get entity REST API operation. */ - RequestOperation["PNGetEntityOperation"] = "PNGetEntityOperation"; + RequestOperation["PNGetDataSyncEntityOperation"] = "PNGetDataSyncEntityOperation"; /** * Get all entities REST API operation. */ - RequestOperation["PNGetAllEntitiesOperation"] = "PNGetAllEntitiesOperation"; + RequestOperation["PNGetDataSyncEntitiesOperation"] = "PNGetDataSyncEntitiesOperation"; /** - * Update entity REST API operation. + * Set entity REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateEntityOperation"] = "PNUpdateEntityOperation"; + RequestOperation["PNSetDataSyncEntityOperation"] = "PNSetDataSyncEntityOperation"; /** - * Patch entity REST API operation. + * Update entity REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchEntityOperation"] = "PNPatchEntityOperation"; + RequestOperation["PNUpdateDataSyncEntityOperation"] = "PNUpdateDataSyncEntityOperation"; /** * Remove entity REST API operation. */ - RequestOperation["PNRemoveEntityOperation"] = "PNRemoveEntityOperation"; + RequestOperation["PNRemoveDataSyncEntityOperation"] = "PNRemoveDataSyncEntityOperation"; /** * Create relationship REST API operation. */ - RequestOperation["PNCreateRelationshipOperation"] = "PNCreateRelationshipOperation"; + RequestOperation["PNCreateDataSyncRelationshipOperation"] = "PNCreateDataSyncRelationshipOperation"; /** * Get relationship REST API operation. */ - RequestOperation["PNGetRelationshipOperation"] = "PNGetRelationshipOperation"; + RequestOperation["PNGetDataSyncRelationshipOperation"] = "PNGetDataSyncRelationshipOperation"; /** * Get all relationships REST API operation. */ - RequestOperation["PNGetAllRelationshipsOperation"] = "PNGetAllRelationshipsOperation"; + RequestOperation["PNGetDataSyncRelationshipsOperation"] = "PNGetDataSyncRelationshipsOperation"; /** - * Update relationship REST API operation. + * Set relationship REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateRelationshipOperation"] = "PNUpdateRelationshipOperation"; + RequestOperation["PNSetDataSyncRelationshipOperation"] = "PNSetDataSyncRelationshipOperation"; /** - * Patch relationship REST API operation. + * Update relationship REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchRelationshipOperation"] = "PNPatchRelationshipOperation"; + RequestOperation["PNUpdateDataSyncRelationshipOperation"] = "PNUpdateDataSyncRelationshipOperation"; /** * Remove relationship REST API operation. */ - RequestOperation["PNRemoveRelationshipOperation"] = "PNRemoveRelationshipOperation"; + RequestOperation["PNRemoveDataSyncRelationshipOperation"] = "PNRemoveDataSyncRelationshipOperation"; /** * Create user REST API operation. */ - RequestOperation["PNCreateUserOperation"] = "PNCreateUserOperation"; + RequestOperation["PNCreateDataSyncUserOperation"] = "PNCreateDataSyncUserOperation"; /** * Get user REST API operation. */ - RequestOperation["PNGetUserOperation"] = "PNGetUserOperation"; + RequestOperation["PNGetDataSyncUserOperation"] = "PNGetDataSyncUserOperation"; /** * Get all users REST API operation. */ - RequestOperation["PNGetAllUsersOperation"] = "PNGetAllUsersOperation"; + RequestOperation["PNGetDataSyncUsersOperation"] = "PNGetDataSyncUsersOperation"; /** - * Update user REST API operation. + * Set user REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateUserOperation"] = "PNUpdateUserOperation"; + RequestOperation["PNSetDataSyncUserOperation"] = "PNSetDataSyncUserOperation"; /** - * Patch user REST API operation. + * Update user REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchUserOperation"] = "PNPatchUserOperation"; + RequestOperation["PNUpdateDataSyncUserOperation"] = "PNUpdateDataSyncUserOperation"; /** * Remove user REST API operation. */ - RequestOperation["PNRemoveUserOperation"] = "PNRemoveUserOperation"; + RequestOperation["PNRemoveDataSyncUserOperation"] = "PNRemoveDataSyncUserOperation"; /** * Create channel REST API operation. */ - RequestOperation["PNCreateChannelOperation"] = "PNCreateChannelOperation"; + RequestOperation["PNCreateDataSyncChannelOperation"] = "PNCreateDataSyncChannelOperation"; /** * Get channel REST API operation. */ - RequestOperation["PNGetChannelOperation"] = "PNGetChannelOperation"; + RequestOperation["PNGetDataSyncChannelOperation"] = "PNGetDataSyncChannelOperation"; /** * Get all channels REST API operation. */ - RequestOperation["PNGetAllChannelsOperation"] = "PNGetAllChannelsOperation"; + RequestOperation["PNGetDataSyncChannelsOperation"] = "PNGetDataSyncChannelsOperation"; /** - * Update channel REST API operation. + * Set channel REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateChannelOperation"] = "PNUpdateChannelOperation"; + RequestOperation["PNSetDataSyncChannelOperation"] = "PNSetDataSyncChannelOperation"; /** - * Patch channel REST API operation. + * Update channel REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchChannelOperation"] = "PNPatchChannelOperation"; + RequestOperation["PNUpdateDataSyncChannelOperation"] = "PNUpdateDataSyncChannelOperation"; /** * Remove channel REST API operation. */ - RequestOperation["PNRemoveChannelOperation"] = "PNRemoveChannelOperation"; + RequestOperation["PNRemoveDataSyncChannelOperation"] = "PNRemoveDataSyncChannelOperation"; /** * Create membership REST API operation. */ - RequestOperation["PNCreateMembershipOperation"] = "PNCreateMembershipOperation"; + RequestOperation["PNCreateDataSyncMembershipOperation"] = "PNCreateDataSyncMembershipOperation"; /** * Get membership REST API operation. */ - RequestOperation["PNGetMembershipOperation"] = "PNGetMembershipOperation"; + RequestOperation["PNGetDataSyncMembershipOperation"] = "PNGetDataSyncMembershipOperation"; /** * Get all memberships REST API operation. */ - RequestOperation["PNGetAllMembershipsOperation"] = "PNGetAllMembershipsOperation"; + RequestOperation["PNGetDataSyncMembershipsOperation"] = "PNGetDataSyncMembershipsOperation"; /** - * Update membership REST API operation. + * Set membership REST API operation (full replacement via PUT). */ - RequestOperation["PNUpdateMembershipOperation"] = "PNUpdateMembershipOperation"; + RequestOperation["PNSetDataSyncMembershipOperation"] = "PNSetDataSyncMembershipOperation"; /** - * Patch membership REST API operation. + * Update membership REST API operation (partial update via PATCH). */ - RequestOperation["PNPatchMembershipOperation"] = "PNPatchMembershipOperation"; + RequestOperation["PNUpdateDataSyncMembershipOperation"] = "PNUpdateDataSyncMembershipOperation"; /** * Remove membership REST API operation. */ - RequestOperation["PNRemoveMembershipOperation"] = "PNRemoveMembershipOperation"; + RequestOperation["PNRemoveDataSyncMembershipOperation"] = "PNRemoveDataSyncMembershipOperation"; // -------------------------------------------------------- // -------------------- File Upload API ------------------- // -------------------------------------------------------- diff --git a/lib/core/endpoints/access_manager/grant_token.js b/lib/core/endpoints/access_manager/grant_token.js index a8133967a..91db64450 100644 --- a/lib/core/endpoints/access_manager/grant_token.js +++ b/lib/core/endpoints/access_manager/grant_token.js @@ -41,7 +41,6 @@ class GrantTokenRequest extends request_1.AbstractRequest { return operations_1.default.PNAccessManagerGrantToken; } 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. @@ -54,15 +53,19 @@ class GrantTokenRequest extends request_1.AbstractRequest { return 'Missing Secret Key'; 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 : {}) || - 'uuids' in ((_b = this.parameters.resources) !== null && _b !== void 0 ? _b : {}) || - 'groups' in ((_c = this.parameters.resources) !== null && _c !== void 0 ? _c : {}) || - 'channels' in ((_d = this.parameters.patterns) !== null && _d !== void 0 ? _d : {}) || - 'uuids' in ((_e = this.parameters.patterns) !== null && _e !== void 0 ? _e : {}) || - 'groups' in ((_f = this.parameters.patterns) !== null && _f !== void 0 ? _f : {}))) - return ('Cannot mix `users`, `spaces` and `authorizedUserId` with `uuids`, `channels`,' + - ' `groups` and `authorized_uuid`'); + // A grant may not carry two synonyms for the same target: `users` / `uuids` both map to the + // uuid wire scope, `spaces` / `channels` both map to the channel wire scope, and + // `authorizedUserId` / `authorized_uuid` both name the principal. Everything else combines + // freely, so a single token can grant DataSync `users`, `channels`, `groups`, and `dataSync` + // together. `uuids` / `spaces` / `authorized_uuid` are the deprecated App Context terminology; + // prefer `users` / `channels` / `authorizedUserId`. + const hasScope = (scope) => { var _a, _b; return scope in ((_a = this.parameters.resources) !== null && _a !== void 0 ? _a : {}) || scope in ((_b = this.parameters.patterns) !== null && _b !== void 0 ? _b : {}); }; + if (hasScope('users') && hasScope('uuids')) + return 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`'; + if (hasScope('spaces') && hasScope('channels')) + return 'Cannot mix `spaces` with `channels` — `spaces` is deprecated terminology; use `channels`'; + if ('authorizedUserId' in this.parameters && 'authorized_uuid' in this.parameters) + return 'Cannot mix `authorizedUserId` with `authorized_uuid` — use `authorizedUserId`'; let permissionsEmpty = true; [this.parameters.resources, this.parameters.patterns].forEach((refPerm) => { Object.keys(refPerm !== null && refPerm !== void 0 ? refPerm : {}).forEach((scope) => { @@ -89,11 +92,12 @@ class GrantTokenRequest extends request_1.AbstractRequest { return Object.assign(Object.assign({}, ((_a = super.headers) !== null && _a !== void 0 ? _a : {})), { 'Content-Type': 'application/json' }); } get body() { + var _a; const { ttl, meta } = this.parameters; const body = Object.assign({}, (ttl || ttl === 0 ? { ttl } : {})); - const uuid = this.isVspPermissions(this.parameters) - ? this.parameters.authorizedUserId - : this.parameters.authorized_uuid; + // `authorizedUserId` is the preferred User-terminology principal; `authorized_uuid` is the + // legacy App Context name. Either binds the token to a single principal. + const uuid = (_a = ('authorizedUserId' in this.parameters ? this.parameters.authorizedUserId : undefined)) !== null && _a !== void 0 ? _a : ('authorized_uuid' in this.parameters ? this.parameters.authorized_uuid : undefined); const permissions = {}; const resourcePermissions = {}; const patternPermissions = {}; @@ -109,33 +113,38 @@ class GrantTokenRequest extends request_1.AbstractRequest { let channelsPermissions = {}; let channelGroupsPermissions = {}; let uuidsPermissions = {}; + let usersPermissions = {}; if (!target.channels) target.channels = {}; if (!target.groups) target.groups = {}; if (!target.uuids) target.uuids = {}; - // @ts-expect-error Not used, needed for api backward compatibility if (!target.users) target.users = {}; // @ts-expect-error Not used, needed for api backward compatibility if (!target.spaces) target.spaces = {}; if (refPerm) { - // Check whether working with legacy Objects permissions. - if ('spaces' in refPerm || 'users' in refPerm) { - channelsPermissions = (_a = refPerm.spaces) !== null && _a !== void 0 ? _a : {}; - uuidsPermissions = (_b = refPerm.users) !== null && _b !== void 0 ? _b : {}; - } - else if ('channels' in refPerm || 'uuids' in refPerm || 'groups' in refPerm) { - channelsPermissions = (_c = refPerm.channels) !== null && _c !== void 0 ? _c : {}; - channelGroupsPermissions = (_d = refPerm.groups) !== null && _d !== void 0 ? _d : {}; - uuidsPermissions = (_e = refPerm.uuids) !== null && _e !== void 0 ? _e : {}; - } + // `spaces` (deprecated) still collapses onto the channel wire scope. `users` and `uuids` + // are distinct wire keys: `users` maps to `users`, `uuids` maps to `uuids`. Validation + // already rejects providing both members of a synonym pair. `spaces` is read intentionally + // as the legacy fallback for channels. + const legacyRefPerm = refPerm; + channelsPermissions = + 'channels' in legacyRefPerm + ? ((_a = legacyRefPerm.channels) !== null && _a !== void 0 ? _a : {}) + : 'spaces' in legacyRefPerm + ? ((_b = legacyRefPerm.spaces) !== null && _b !== void 0 ? _b : {}) + : {}; + channelGroupsPermissions = 'groups' in legacyRefPerm ? ((_c = legacyRefPerm.groups) !== null && _c !== void 0 ? _c : {}) : {}; + uuidsPermissions = 'uuids' in legacyRefPerm ? ((_d = legacyRefPerm.uuids) !== null && _d !== void 0 ? _d : {}) : {}; + usersPermissions = 'users' in legacyRefPerm ? ((_e = legacyRefPerm.users) !== null && _e !== void 0 ? _e : {}) : {}; } 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)); + Object.keys(usersPermissions).forEach((users) => mapPermissions(users, this.extractPermissions(usersPermissions[users]), 'users', target)); if (refPerm && 'dataSync' in refPerm) this.mapDataSyncPermissions(refPerm.dataSync, target, mapPermissions); }); @@ -234,20 +243,5 @@ class GrantTokenRequest extends request_1.AbstractRequest { permissionsResult |= 1; return permissionsResult; } - /** - * Check whether provided parameters is part of legacy VSP access token configuration. - * - * @param parameters - Parameters which should be checked. - * - * @returns VSP request parameters if it is legacy configuration. - */ - isVspPermissions(parameters) { - var _a, _b, _c, _d; - return ('authorizedUserId' in parameters || - 'spaces' in ((_a = parameters.resources) !== null && _a !== void 0 ? _a : {}) || - 'users' in ((_b = parameters.resources) !== null && _b !== void 0 ? _b : {}) || - 'spaces' in ((_c = parameters.patterns) !== null && _c !== void 0 ? _c : {}) || - 'users' in ((_d = parameters.patterns) !== null && _d !== void 0 ? _d : {})); - } } exports.GrantTokenRequest = GrantTokenRequest; diff --git a/lib/core/endpoints/data_sync/channel/create.js b/lib/core/endpoints/data_sync/channel/create.js index d03154668..15d761985 100644 --- a/lib/core/endpoints/data_sync/channel/create.js +++ b/lib/core/endpoints/data_sync/channel/create.js @@ -33,7 +33,7 @@ class CreateChannelRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNCreateChannelOperation; + return operations_1.default.PNCreateDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -44,9 +44,9 @@ class CreateChannelRequest extends request_1.AbstractRequest { }); } validate() { - if (!this.parameters.channel) - return 'Channel cannot be empty'; - if (this.parameters.channel.entityClassVersion === undefined || this.parameters.channel.entityClassVersion === null) + if (!this.parameters.data) + return 'Channel data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === null) return 'Entity class version cannot be empty'; } get headers() { @@ -59,7 +59,10 @@ class CreateChannelRequest extends request_1.AbstractRequest { return `/v1/datasync/subkeys/${subscribeKey}/channels`; } get body() { - return JSON.stringify({ data: this.parameters.channel }); + const { id, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } 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 index 4ec4a48f2..9f252d814 100644 --- a/lib/core/endpoints/data_sync/channel/get-all.js +++ b/lib/core/endpoints/data_sync/channel/get-all.js @@ -1,9 +1,42 @@ "use strict"; /** - * Get All Channels REST API module. + * Get Channels REST API module. * * @internal */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); 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) { @@ -17,9 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.GetAllChannelsRequest = void 0; +exports.GetChannelsRequest = void 0; const request_1 = require("../../../components/request"); const operations_1 = __importDefault(require("../../../constants/operations")); +const DataSync = __importStar(require("../../../types/api/data-sync")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- @@ -30,11 +64,11 @@ const operations_1 = __importDefault(require("../../../constants/operations")); const DEFAULT_LIMIT = 20; // endregion /** - * Get All Channels request. + * Get Channels request. * * @internal */ -class GetAllChannelsRequest extends request_1.AbstractRequest { +class GetChannelsRequest extends request_1.AbstractRequest { constructor(parameters) { var _a; super(); @@ -43,7 +77,7 @@ class GetAllChannelsRequest extends request_1.AbstractRequest { (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return operations_1.default.PNGetAllChannelsOperation; + return operations_1.default.PNGetDataSyncChannelsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -58,7 +92,8 @@ class GetAllChannelsRequest extends request_1.AbstractRequest { } 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 } : {})); + const sorting = DataSync.serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } -exports.GetAllChannelsRequest = GetAllChannelsRequest; +exports.GetChannelsRequest = GetChannelsRequest; diff --git a/lib/core/endpoints/data_sync/channel/get.js b/lib/core/endpoints/data_sync/channel/get.js index c2e8cd1e3..3e07d1798 100644 --- a/lib/core/endpoints/data_sync/channel/get.js +++ b/lib/core/endpoints/data_sync/channel/get.js @@ -33,7 +33,7 @@ class GetChannelRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNGetChannelOperation; + return operations_1.default.PNGetDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/core/endpoints/data_sync/channel/remove.js b/lib/core/endpoints/data_sync/channel/remove.js index 648f5d014..beed73155 100644 --- a/lib/core/endpoints/data_sync/channel/remove.js +++ b/lib/core/endpoints/data_sync/channel/remove.js @@ -34,7 +34,7 @@ class RemoveChannelRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNRemoveChannelOperation; + return operations_1.default.PNRemoveDataSyncChannelOperation; } validate() { if (!this.parameters.id) diff --git a/lib/core/endpoints/data_sync/channel/set.js b/lib/core/endpoints/data_sync/channel/set.js new file mode 100644 index 000000000..fad69b763 --- /dev/null +++ b/lib/core/endpoints/data_sync/channel/set.js @@ -0,0 +1,75 @@ +"use strict"; +/** + * Set Channel REST API module. + * + * Full resource replacement via PUT. + * + * @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.SetChannelRequest = 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 +/** + * Set Channel request. + * + * @internal + */ +class SetChannelRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNSetDataSyncChannelOperation; + } + 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'; + if (!this.parameters.data) + return 'Channel data cannot be empty'; + if (this.parameters.data.classVersion === undefined || this.parameters.data.classVersion === 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() { + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); + } +} +exports.SetChannelRequest = SetChannelRequest; diff --git a/lib/core/endpoints/data_sync/channel/update.js b/lib/core/endpoints/data_sync/channel/update.js index 3312e6592..c9a0b2e52 100644 --- a/lib/core/endpoints/data_sync/channel/update.js +++ b/lib/core/endpoints/data_sync/channel/update.js @@ -2,7 +2,10 @@ /** * Update Channel REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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 */ @@ -23,6 +26,7 @@ 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 data_sync_1 = require("../../../types/api/data-sync"); const utils_1 = require("../../../utils"); // endregion /** @@ -32,11 +36,11 @@ const utils_1 = require("../../../utils"); */ class UpdateChannelRequest extends request_1.AbstractRequest { constructor(parameters) { - super({ method: transport_request_1.TransportMethod.PUT }); + super({ method: transport_request_1.TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return operations_1.default.PNUpdateChannelOperation; + return operations_1.default.PNUpdateDataSyncChannelOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -49,24 +53,32 @@ class UpdateChannelRequest extends request_1.AbstractRequest { 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'; + 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'; } 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' }); + 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() { - return JSON.stringify({ data: this.parameters.channel }); + const { add, replace, remove, move, copy, test } = this.parameters; + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)({ add, replace, remove, move, copy, test }); + return JSON.stringify(jsonPatchOps); } } exports.UpdateChannelRequest = UpdateChannelRequest; diff --git a/lib/core/endpoints/data_sync/entity/create.js b/lib/core/endpoints/data_sync/entity/create.js index 1615e603f..95ae8fadf 100644 --- a/lib/core/endpoints/data_sync/entity/create.js +++ b/lib/core/endpoints/data_sync/entity/create.js @@ -33,7 +33,7 @@ class CreateEntityRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNCreateEntityOperation; + return operations_1.default.PNCreateDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -44,11 +44,11 @@ class CreateEntityRequest extends request_1.AbstractRequest { }); } validate() { - if (!this.parameters.entity) - return 'Entity cannot be empty'; - if (!this.parameters.entity.entityClass) + if (!this.parameters.class) return 'Entity class 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'; } get headers() { @@ -61,7 +61,10 @@ class CreateEntityRequest extends request_1.AbstractRequest { return `/v1/datasync/subkeys/${subscribeKey}/entities`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + const { id, class: entityClass, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClass, entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } 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 index 2bc93360c..be34939b6 100644 --- a/lib/core/endpoints/data_sync/entity/get-all.js +++ b/lib/core/endpoints/data_sync/entity/get-all.js @@ -1,9 +1,42 @@ "use strict"; /** - * Get All Entities REST API module. + * Get Entities REST API module. * * @internal */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); 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) { @@ -17,9 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.GetAllEntitiesRequest = void 0; +exports.GetEntitiesRequest = void 0; const request_1 = require("../../../components/request"); const operations_1 = __importDefault(require("../../../constants/operations")); +const DataSync = __importStar(require("../../../types/api/data-sync")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- @@ -30,11 +64,11 @@ const operations_1 = __importDefault(require("../../../constants/operations")); const DEFAULT_LIMIT = 20; // endregion /** - * Get All Entities request. + * Get Entities request. * * @internal */ -class GetAllEntitiesRequest extends request_1.AbstractRequest { +class GetEntitiesRequest extends request_1.AbstractRequest { constructor(parameters) { var _a; super(); @@ -43,7 +77,7 @@ class GetAllEntitiesRequest extends request_1.AbstractRequest { (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return operations_1.default.PNGetAllEntitiesOperation; + return operations_1.default.PNGetDataSyncEntitiesOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -62,7 +96,8 @@ class GetAllEntitiesRequest extends request_1.AbstractRequest { } 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 sorting = DataSync.serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } -exports.GetAllEntitiesRequest = GetAllEntitiesRequest; +exports.GetEntitiesRequest = GetEntitiesRequest; diff --git a/lib/core/endpoints/data_sync/entity/get.js b/lib/core/endpoints/data_sync/entity/get.js index 02a7bbf9b..ef05ea074 100644 --- a/lib/core/endpoints/data_sync/entity/get.js +++ b/lib/core/endpoints/data_sync/entity/get.js @@ -33,7 +33,7 @@ class GetEntityRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNGetEntityOperation; + return operations_1.default.PNGetDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/core/endpoints/data_sync/entity/remove.js b/lib/core/endpoints/data_sync/entity/remove.js index 9979e5c0e..3d60a8145 100644 --- a/lib/core/endpoints/data_sync/entity/remove.js +++ b/lib/core/endpoints/data_sync/entity/remove.js @@ -34,7 +34,7 @@ class RemoveEntityRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNRemoveEntityOperation; + return operations_1.default.PNRemoveDataSyncEntityOperation; } validate() { if (!this.parameters.id) diff --git a/lib/core/endpoints/data_sync/entity/set.js b/lib/core/endpoints/data_sync/entity/set.js new file mode 100644 index 000000000..baa6d9336 --- /dev/null +++ b/lib/core/endpoints/data_sync/entity/set.js @@ -0,0 +1,76 @@ +"use strict"; +/** + * Set Entity REST API module. + * + * Full resource replacement via PUT. + * Note: `entityClass` is immutable and cannot be changed via update. + * + * @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.SetEntityRequest = 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 +/** + * Set Entity request. + * + * @internal + */ +class SetEntityRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNSetDataSyncEntityOperation; + } + 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.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'; + } + 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/${(0, utils_1.encodeString)(id)}`; + } + get body() { + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); + } +} +exports.SetEntityRequest = SetEntityRequest; diff --git a/lib/core/endpoints/data_sync/entity/update.js b/lib/core/endpoints/data_sync/entity/update.js index fa1aa0927..9e64ef804 100644 --- a/lib/core/endpoints/data_sync/entity/update.js +++ b/lib/core/endpoints/data_sync/entity/update.js @@ -2,8 +2,10 @@ /** * Update Entity REST API module. * - * Full resource replacement via PUT. - * Note: `entityClass` is immutable and cannot be changed via update. + * Partial update via JSON Patch (RFC 6902). + * 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 */ @@ -24,6 +26,7 @@ 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 data_sync_1 = require("../../../types/api/data-sync"); const utils_1 = require("../../../utils"); // endregion /** @@ -33,11 +36,11 @@ const utils_1 = require("../../../utils"); */ class UpdateEntityRequest extends request_1.AbstractRequest { constructor(parameters) { - super({ method: transport_request_1.TransportMethod.PUT }); + super({ method: transport_request_1.TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return operations_1.default.PNUpdateEntityOperation; + return operations_1.default.PNUpdateDataSyncEntityOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -50,24 +53,32 @@ class UpdateEntityRequest extends request_1.AbstractRequest { 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'; + 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'; } 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' }); + 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/${(0, utils_1.encodeString)(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.entity }); + const { add, replace, remove, move, copy, test } = this.parameters; + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)({ add, replace, remove, move, copy, test }); + return JSON.stringify(jsonPatchOps); } } exports.UpdateEntityRequest = UpdateEntityRequest; diff --git a/lib/core/endpoints/data_sync/membership/create.js b/lib/core/endpoints/data_sync/membership/create.js index f6e618679..b151bc243 100644 --- a/lib/core/endpoints/data_sync/membership/create.js +++ b/lib/core/endpoints/data_sync/membership/create.js @@ -33,7 +33,7 @@ class CreateMembershipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNCreateMembershipOperation; + return operations_1.default.PNCreateDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -44,13 +44,13 @@ class CreateMembershipRequest extends request_1.AbstractRequest { }); } validate() { - if (!this.parameters.membership) - return 'Membership cannot be empty'; - if (!this.parameters.membership.userId) + if (!this.parameters.userId) return 'User id cannot be empty'; - if (!this.parameters.membership.channelId) + if (!this.parameters.channelId) return 'Channel id cannot be empty'; - if (!this.parameters.membership.relationshipClassVersion) + if (!this.parameters.data) + return 'Membership data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -63,7 +63,11 @@ class CreateMembershipRequest extends request_1.AbstractRequest { return `/v1/datasync/subkeys/${subscribeKey}/memberships`; } get body() { - return JSON.stringify({ data: this.parameters.membership }); + const { id, userId, channelId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { userId, + channelId, relationshipClassVersion: data.classVersion }), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } 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 index 04ffa8074..d8a6f30a9 100644 --- a/lib/core/endpoints/data_sync/membership/get-all.js +++ b/lib/core/endpoints/data_sync/membership/get-all.js @@ -1,9 +1,42 @@ "use strict"; /** - * Get All Memberships REST API module. + * Get Memberships REST API module. * * @internal */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); 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) { @@ -17,9 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.GetAllMembershipsRequest = void 0; +exports.GetMembershipsRequest = void 0; const request_1 = require("../../../components/request"); const operations_1 = __importDefault(require("../../../constants/operations")); +const DataSync = __importStar(require("../../../types/api/data-sync")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- @@ -30,11 +64,11 @@ const operations_1 = __importDefault(require("../../../constants/operations")); const DEFAULT_LIMIT = 20; // endregion /** - * Get All Memberships request. + * Get Memberships request. * * @internal */ -class GetAllMembershipsRequest extends request_1.AbstractRequest { +class GetMembershipsRequest extends request_1.AbstractRequest { constructor(parameters) { var _a; super(); @@ -43,7 +77,7 @@ class GetAllMembershipsRequest extends request_1.AbstractRequest { (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return operations_1.default.PNGetAllMembershipsOperation; + return operations_1.default.PNGetDataSyncMembershipsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -58,7 +92,8 @@ class GetAllMembershipsRequest extends request_1.AbstractRequest { } 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 } : {})); + const sorting = DataSync.serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } -exports.GetAllMembershipsRequest = GetAllMembershipsRequest; +exports.GetMembershipsRequest = GetMembershipsRequest; diff --git a/lib/core/endpoints/data_sync/membership/get.js b/lib/core/endpoints/data_sync/membership/get.js index 328fc0e9d..5a38acc7c 100644 --- a/lib/core/endpoints/data_sync/membership/get.js +++ b/lib/core/endpoints/data_sync/membership/get.js @@ -33,7 +33,7 @@ class GetMembershipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNGetMembershipOperation; + return operations_1.default.PNGetDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/core/endpoints/data_sync/membership/remove.js b/lib/core/endpoints/data_sync/membership/remove.js index 339d6f0bf..8c7e44dc8 100644 --- a/lib/core/endpoints/data_sync/membership/remove.js +++ b/lib/core/endpoints/data_sync/membership/remove.js @@ -34,7 +34,7 @@ class RemoveMembershipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNRemoveMembershipOperation; + return operations_1.default.PNRemoveDataSyncMembershipOperation; } validate() { if (!this.parameters.id) diff --git a/lib/core/endpoints/data_sync/membership/set.js b/lib/core/endpoints/data_sync/membership/set.js new file mode 100644 index 000000000..39608d813 --- /dev/null +++ b/lib/core/endpoints/data_sync/membership/set.js @@ -0,0 +1,80 @@ +"use strict"; +/** + * Set Membership REST API module. + * + * Full resource replacement via PUT. + * + * @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.SetMembershipRequest = 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 +/** + * Set Membership request. + * + * @internal + */ +class SetMembershipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNSetDataSyncMembershipOperation; + } + 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.userId) + return 'User id cannot be empty'; + if (!this.parameters.channelId) + return 'Channel id cannot be empty'; + if (!this.parameters.data) + return 'Membership data cannot be empty'; + if (!this.parameters.data.classVersion) + 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/${(0, utils_1.encodeString)(id)}`; + } + get body() { + const { userId, channelId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ userId, + channelId, relationshipClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); + } +} +exports.SetMembershipRequest = SetMembershipRequest; diff --git a/lib/core/endpoints/data_sync/membership/update.js b/lib/core/endpoints/data_sync/membership/update.js index d88f056c7..e3ac2c451 100644 --- a/lib/core/endpoints/data_sync/membership/update.js +++ b/lib/core/endpoints/data_sync/membership/update.js @@ -2,7 +2,10 @@ /** * Update Membership REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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 */ @@ -23,6 +26,7 @@ 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 data_sync_1 = require("../../../types/api/data-sync"); const utils_1 = require("../../../utils"); // endregion /** @@ -32,11 +36,11 @@ const utils_1 = require("../../../utils"); */ class UpdateMembershipRequest extends request_1.AbstractRequest { constructor(parameters) { - super({ method: transport_request_1.TransportMethod.PUT }); + super({ method: transport_request_1.TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return operations_1.default.PNUpdateMembershipOperation; + return operations_1.default.PNUpdateDataSyncMembershipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -49,28 +53,32 @@ class UpdateMembershipRequest extends request_1.AbstractRequest { 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'; + 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'; } 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' }); + 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() { - return JSON.stringify({ data: this.parameters.membership }); + const { add, replace, remove, move, copy, test } = this.parameters; + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)({ add, replace, remove, move, copy, test }); + return JSON.stringify(jsonPatchOps); } } exports.UpdateMembershipRequest = UpdateMembershipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/create.js b/lib/core/endpoints/data_sync/relationship/create.js index 0d3706408..273a76bf5 100644 --- a/lib/core/endpoints/data_sync/relationship/create.js +++ b/lib/core/endpoints/data_sync/relationship/create.js @@ -33,7 +33,7 @@ class CreateRelationshipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNCreateRelationshipOperation; + return operations_1.default.PNCreateDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -44,15 +44,15 @@ class CreateRelationshipRequest extends request_1.AbstractRequest { }); } validate() { - if (!this.parameters.relationship) - return 'Relationship cannot be empty'; - if (!this.parameters.relationship.entityAId) + if (!this.parameters.entityAId) return 'Entity A id cannot be empty'; - if (!this.parameters.relationship.entityBId) + if (!this.parameters.entityBId) return 'Entity B id cannot be empty'; - if (!this.parameters.relationship.relationshipClass) + if (!this.parameters.class) return 'Relationship class cannot be empty'; - if (!this.parameters.relationship.relationshipClassVersion) + if (!this.parameters.data) + return 'Relationship data cannot be empty'; + if (!this.parameters.data.classVersion) return 'Relationship class version cannot be empty'; } get headers() { @@ -65,7 +65,12 @@ class CreateRelationshipRequest extends request_1.AbstractRequest { return `/v1/datasync/subkeys/${subscribeKey}/relationships`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + const { id, class: relationshipClass, entityAId, entityBId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityAId, + entityBId, + relationshipClass, relationshipClassVersion: data.classVersion }), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } 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 index c41b3c5e9..9168d7550 100644 --- a/lib/core/endpoints/data_sync/relationship/get-all.js +++ b/lib/core/endpoints/data_sync/relationship/get-all.js @@ -1,9 +1,42 @@ "use strict"; /** - * Get All Relationships REST API module. + * Get Relationships REST API module. * * @internal */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); 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) { @@ -17,9 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.GetAllRelationshipsRequest = void 0; +exports.GetRelationshipsRequest = void 0; const request_1 = require("../../../components/request"); const operations_1 = __importDefault(require("../../../constants/operations")); +const DataSync = __importStar(require("../../../types/api/data-sync")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- @@ -30,11 +64,11 @@ const operations_1 = __importDefault(require("../../../constants/operations")); const DEFAULT_LIMIT = 20; // endregion /** - * Get All Relationships request. + * Get Relationships request. * * @internal */ -class GetAllRelationshipsRequest extends request_1.AbstractRequest { +class GetRelationshipsRequest extends request_1.AbstractRequest { constructor(parameters) { var _a; super(); @@ -43,7 +77,7 @@ class GetAllRelationshipsRequest extends request_1.AbstractRequest { (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return operations_1.default.PNGetAllRelationshipsOperation; + return operations_1.default.PNGetDataSyncRelationshipsOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -62,7 +96,8 @@ class GetAllRelationshipsRequest extends request_1.AbstractRequest { } 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 } : {})); + const sorting = DataSync.serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } -exports.GetAllRelationshipsRequest = GetAllRelationshipsRequest; +exports.GetRelationshipsRequest = GetRelationshipsRequest; diff --git a/lib/core/endpoints/data_sync/relationship/get.js b/lib/core/endpoints/data_sync/relationship/get.js index ef244806c..b4d7404c1 100644 --- a/lib/core/endpoints/data_sync/relationship/get.js +++ b/lib/core/endpoints/data_sync/relationship/get.js @@ -33,7 +33,7 @@ class GetRelationshipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNGetRelationshipOperation; + return operations_1.default.PNGetDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/core/endpoints/data_sync/relationship/remove.js b/lib/core/endpoints/data_sync/relationship/remove.js index 74cc8d527..00bbfd72e 100644 --- a/lib/core/endpoints/data_sync/relationship/remove.js +++ b/lib/core/endpoints/data_sync/relationship/remove.js @@ -34,7 +34,7 @@ class RemoveRelationshipRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNRemoveRelationshipOperation; + return operations_1.default.PNRemoveDataSyncRelationshipOperation; } validate() { if (!this.parameters.id) diff --git a/lib/core/endpoints/data_sync/relationship/set.js b/lib/core/endpoints/data_sync/relationship/set.js new file mode 100644 index 000000000..95f2d68be --- /dev/null +++ b/lib/core/endpoints/data_sync/relationship/set.js @@ -0,0 +1,80 @@ +"use strict"; +/** + * Set Relationship REST API module. + * + * Full resource replacement via PUT. + * + * @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.SetRelationshipRequest = 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 +/** + * Set Relationship request. + * + * @internal + */ +class SetRelationshipRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNSetDataSyncRelationshipOperation; + } + 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.entityAId) + return 'Entity A id cannot be empty'; + if (!this.parameters.entityBId) + return 'Entity B id cannot be empty'; + if (!this.parameters.data) + return 'Relationship data cannot be empty'; + if (!this.parameters.data.classVersion) + 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/${(0, utils_1.encodeString)(id)}`; + } + get body() { + const { entityAId, entityBId, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityAId, + entityBId, relationshipClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); + } +} +exports.SetRelationshipRequest = SetRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/relationship/update.js b/lib/core/endpoints/data_sync/relationship/update.js index dda1eb34c..f1b5036db 100644 --- a/lib/core/endpoints/data_sync/relationship/update.js +++ b/lib/core/endpoints/data_sync/relationship/update.js @@ -2,7 +2,11 @@ /** * Update Relationship REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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 */ @@ -23,6 +27,7 @@ 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 data_sync_1 = require("../../../types/api/data-sync"); const utils_1 = require("../../../utils"); // endregion /** @@ -32,11 +37,11 @@ const utils_1 = require("../../../utils"); */ class UpdateRelationshipRequest extends request_1.AbstractRequest { constructor(parameters) { - super({ method: transport_request_1.TransportMethod.PUT }); + super({ method: transport_request_1.TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return operations_1.default.PNUpdateRelationshipOperation; + return operations_1.default.PNUpdateDataSyncRelationshipOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -49,28 +54,32 @@ class UpdateRelationshipRequest extends request_1.AbstractRequest { 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'; + 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'; } 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/json-patch+json' }); } get path() { const { keySet: { subscribeKey }, id, } = this.parameters; return `/v1/datasync/subkeys/${subscribeKey}/relationships/${(0, utils_1.encodeString)(id)}`; } get body() { - return JSON.stringify({ data: this.parameters.relationship }); + const { add, replace, remove, move, copy, test } = this.parameters; + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)({ add, replace, remove, move, copy, test }); + return JSON.stringify(jsonPatchOps); } } exports.UpdateRelationshipRequest = UpdateRelationshipRequest; diff --git a/lib/core/endpoints/data_sync/user/create.js b/lib/core/endpoints/data_sync/user/create.js index 78cdcb7c8..c0bfa8732 100644 --- a/lib/core/endpoints/data_sync/user/create.js +++ b/lib/core/endpoints/data_sync/user/create.js @@ -33,7 +33,7 @@ class CreateUserRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNCreateUserOperation; + return operations_1.default.PNCreateDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -44,9 +44,9 @@ class CreateUserRequest extends request_1.AbstractRequest { }); } validate() { - 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'; } get headers() { @@ -59,7 +59,10 @@ class CreateUserRequest extends request_1.AbstractRequest { return `/v1/datasync/subkeys/${subscribeKey}/users`; } get body() { - return JSON.stringify({ data: this.parameters.user }); + const { id, classLevel, data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (id !== undefined ? { id } : {})), { entityClassVersion: data.classVersion }), (classLevel !== undefined ? { entityClassLevel: classLevel } : {})), (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); } } 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 index 9ccac8f5d..67ecc2df2 100644 --- a/lib/core/endpoints/data_sync/user/get-all.js +++ b/lib/core/endpoints/data_sync/user/get-all.js @@ -1,9 +1,42 @@ "use strict"; /** - * Get All Users REST API module. + * Get Users REST API module. * * @internal */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); 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) { @@ -17,9 +50,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.GetAllUsersRequest = void 0; +exports.GetUsersRequest = void 0; const request_1 = require("../../../components/request"); const operations_1 = __importDefault(require("../../../constants/operations")); +const DataSync = __importStar(require("../../../types/api/data-sync")); // -------------------------------------------------------- // ----------------------- Defaults ----------------------- // -------------------------------------------------------- @@ -30,11 +64,11 @@ const operations_1 = __importDefault(require("../../../constants/operations")); const DEFAULT_LIMIT = 20; // endregion /** - * Get All Users request. + * Get Users request. * * @internal */ -class GetAllUsersRequest extends request_1.AbstractRequest { +class GetUsersRequest extends request_1.AbstractRequest { constructor(parameters) { var _a; super(); @@ -43,7 +77,7 @@ class GetAllUsersRequest extends request_1.AbstractRequest { (_a = parameters.limit) !== null && _a !== void 0 ? _a : (parameters.limit = DEFAULT_LIMIT); } operation() { - return operations_1.default.PNGetAllUsersOperation; + return operations_1.default.PNGetDataSyncUsersOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -58,7 +92,8 @@ class GetAllUsersRequest extends request_1.AbstractRequest { } 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 } : {})); + const sorting = DataSync.serializeDataSyncSort(sort); + 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 } : {})), (sorting.length ? { sort: sorting } : {})), (filterAdvanced ? { filter_advanced: filterAdvanced } : {})); } } -exports.GetAllUsersRequest = GetAllUsersRequest; +exports.GetUsersRequest = GetUsersRequest; diff --git a/lib/core/endpoints/data_sync/user/get.js b/lib/core/endpoints/data_sync/user/get.js index a6cf3a9b6..8d5ec387d 100644 --- a/lib/core/endpoints/data_sync/user/get.js +++ b/lib/core/endpoints/data_sync/user/get.js @@ -33,7 +33,7 @@ class GetUserRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNGetUserOperation; + return operations_1.default.PNGetDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { diff --git a/lib/core/endpoints/data_sync/user/remove.js b/lib/core/endpoints/data_sync/user/remove.js index b2d7aa1f4..ebe97aeae 100644 --- a/lib/core/endpoints/data_sync/user/remove.js +++ b/lib/core/endpoints/data_sync/user/remove.js @@ -34,7 +34,7 @@ class RemoveUserRequest extends request_1.AbstractRequest { this.parameters = parameters; } operation() { - return operations_1.default.PNRemoveUserOperation; + return operations_1.default.PNRemoveDataSyncUserOperation; } validate() { if (!this.parameters.id) diff --git a/lib/core/endpoints/data_sync/user/set.js b/lib/core/endpoints/data_sync/user/set.js new file mode 100644 index 000000000..ff47907de --- /dev/null +++ b/lib/core/endpoints/data_sync/user/set.js @@ -0,0 +1,75 @@ +"use strict"; +/** + * Set User REST API module. + * + * Full resource replacement via PUT. + * + * @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.SetUserRequest = 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 +/** + * Set User request. + * + * @internal + */ +class SetUserRequest extends request_1.AbstractRequest { + constructor(parameters) { + super({ method: transport_request_1.TransportMethod.PUT }); + this.parameters = parameters; + } + operation() { + return operations_1.default.PNSetDataSyncUserOperation; + } + 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'; + 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'; + } + 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() { + const { data } = this.parameters; + return JSON.stringify({ + data: Object.assign(Object.assign({ entityClassVersion: data.classVersion }, (data.status !== undefined ? { status: data.status } : {})), (data.payload !== undefined ? { payload: data.payload } : {})), + }); + } +} +exports.SetUserRequest = SetUserRequest; diff --git a/lib/core/endpoints/data_sync/user/update.js b/lib/core/endpoints/data_sync/user/update.js index 73e58f637..6604281c0 100644 --- a/lib/core/endpoints/data_sync/user/update.js +++ b/lib/core/endpoints/data_sync/user/update.js @@ -2,7 +2,10 @@ /** * Update User REST API module. * - * Full resource replacement via PUT. + * Partial update via JSON Patch (RFC 6902). + * 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 */ @@ -23,6 +26,7 @@ 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 data_sync_1 = require("../../../types/api/data-sync"); const utils_1 = require("../../../utils"); // endregion /** @@ -32,11 +36,11 @@ const utils_1 = require("../../../utils"); */ class UpdateUserRequest extends request_1.AbstractRequest { constructor(parameters) { - super({ method: transport_request_1.TransportMethod.PUT }); + super({ method: transport_request_1.TransportMethod.PATCH }); this.parameters = parameters; } operation() { - return operations_1.default.PNUpdateUserOperation; + return operations_1.default.PNUpdateDataSyncUserOperation; } parse(response) { return __awaiter(this, void 0, void 0, function* () { @@ -49,24 +53,32 @@ class UpdateUserRequest extends request_1.AbstractRequest { 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'; + 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'; } 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' }); + 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() { - return JSON.stringify({ data: this.parameters.user }); + const { add, replace, remove, move, copy, test } = this.parameters; + // Paths are used exactly as provided by the caller (dot notation -> JSON Pointer). The SDK + const jsonPatchOps = (0, data_sync_1.toJsonPatchOperations)({ add, replace, remove, move, copy, test }); + return JSON.stringify(jsonPatchOps); } } exports.UpdateUserRequest = UpdateUserRequest; diff --git a/lib/core/endpoints/subscribe.js b/lib/core/endpoints/subscribe.js index ef98e4f42..cb2c32925 100644 --- a/lib/core/endpoints/subscribe.js +++ b/lib/core/endpoints/subscribe.js @@ -72,12 +72,11 @@ var PubNubEventType; PubNubEventType[PubNubEventType["DataSync"] = 5] = "DataSync"; })(PubNubEventType || (exports.PubNubEventType = PubNubEventType = {})); /** - * Reserved DataSync system class names (lower-cased, prefix-stripped) → normalized object type. + * Reserved DataSync system class names (lower-cased) → 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`). + * Only consulted for classes the service marks as `Global` (see {@link DataSyncClassLevel}), so a + * developer-defined class which happens to share one of these names is not mistaken for a typed + * resource. Keys are compared case-insensitively. * * @internal */ @@ -85,9 +84,6 @@ const DATA_SYNC_RESERVED_CLASSES = { user: 'user', channel: 'channel', membership: 'membership', - pn_user: 'user', - pn_channel: 'channel', - pn_membership: 'membership', }; // endregion /** @@ -316,29 +312,29 @@ class BaseSubscribeRequest extends request_1.AbstractRequest { // 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. + // Wire `className` is a bare class name (`User`, `Membership`, `Customer`); the `:`-splitting below + // is only there to keep tolerating the retired positional composite (`User::` / `::Customer`). 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 classLevel = metadata.classLevel; + // `classLevel` authoritatively separates the built-in classes from developer-defined ones, so a + // developer class named `User` / `Channel` / `Membership` is not mistaken for a typed resource. + // When it is absent (service predating the field) fall back to the legacy positional heuristic, + // where the system class was the first segment. + const systemClass = classLevel === undefined ? classSegments[0] : classLevel === 'Global' ? className : 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 : {}); + // `data` mirrors the object as sent by the service; class identity is reported once, on the event. let data; - if (metadata.event === 'delete') { + 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 }); - } + else if (metadata.type === 'relationship') + data = Object.assign({}, raw); + else + data = Object.assign({}, raw); return { channel, subscription, @@ -350,6 +346,7 @@ class BaseSubscribeRequest extends request_1.AbstractRequest { type: metadata.type, objectType, className, + classLevel, classVersion, data, }, diff --git a/lib/core/pubnub-common.js b/lib/core/pubnub-common.js index abea51bc6..24d76809a 100644 --- a/lib/core/pubnub-common.js +++ b/lib/core/pubnub-common.js @@ -206,7 +206,8 @@ 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.DATA_SYNC_MODULE !== 'disabled') + 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') diff --git a/lib/core/pubnub-data-sync.js b/lib/core/pubnub-data-sync.js index 012511b56..dac0574d2 100644 --- a/lib/core/pubnub-data-sync.js +++ b/lib/core/pubnub-data-sync.js @@ -14,33 +14,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge Object.defineProperty(exports, "__esModule", { value: true }); 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 set_1 = require("./endpoints/data_sync/user/set"); const remove_1 = require("./endpoints/data_sync/user/remove"); -const patch_1 = require("./endpoints/data_sync/user/patch"); +const update_1 = require("./endpoints/data_sync/user/update"); 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 set_2 = require("./endpoints/data_sync/channel/set"); const remove_2 = require("./endpoints/data_sync/channel/remove"); -const patch_2 = require("./endpoints/data_sync/channel/patch"); +const update_2 = require("./endpoints/data_sync/channel/update"); 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 set_3 = require("./endpoints/data_sync/membership/set"); const remove_3 = require("./endpoints/data_sync/membership/remove"); -const patch_3 = require("./endpoints/data_sync/membership/patch"); +const update_3 = require("./endpoints/data_sync/membership/update"); 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 set_4 = require("./endpoints/data_sync/relationship/set"); const remove_4 = require("./endpoints/data_sync/relationship/remove"); -const patch_4 = require("./endpoints/data_sync/relationship/patch"); +const update_4 = require("./endpoints/data_sync/relationship/update"); 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 set_5 = require("./endpoints/data_sync/entity/set"); const remove_5 = require("./endpoints/data_sync/entity/remove"); -const patch_5 = require("./endpoints/data_sync/entity/patch"); +const update_5 = require("./endpoints/data_sync/entity/update"); const get_5 = require("./endpoints/data_sync/entity/get"); /** * PubNub DataSync API interface. @@ -93,7 +93,7 @@ class PubNubDataSync { }); } /** - * Fetch a specific Entity. + * Get a specific Entity. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -114,65 +114,65 @@ class PubNubDataSync { }); } /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get 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. + * @returns Asynchronous get entities response or `void` in case if `callback` provided. */ - getAllEntities(parameters, callback) { + getEntities(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: 'Get Entities with parameters:', })); - const request = new get_all_5.GetAllEntitiesRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_5.GetEntitiesRequest(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). + * Set 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. + * @returns Asynchronous set entity response or `void` in case if `callback` provided. */ - updateEntity(parameters, callback) { + setEntity(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: 'Set Entity with parameters:', })); - const request = new update_5.UpdateEntityRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new set_5.SetEntityRequest(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). + * Update 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. + * @returns Asynchronous update entity response or `void` in case if `callback` provided. */ - patchEntity(parameters, callback) { + updateEntity(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: 'Update Entity with parameters:', })); - const request = new patch_5.PatchEntityRequest(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); @@ -221,7 +221,7 @@ class PubNubDataSync { }); } /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -242,65 +242,65 @@ class PubNubDataSync { }); } /** - * Fetch a paginated list of Relationships. + * Get 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. + * @returns Asynchronous get relationships response or `void` in case if `callback` provided. */ - getAllRelationships(parameters, callback) { + getRelationships(parameters, callback) { return __awaiter(this, void 0, void 0, function* () { this.logger.debug('PubNub', () => ({ messageType: 'object', message: Object.assign({}, parameters), - details: 'Get all Relationships with parameters:', + details: 'Get Relationships with parameters:', })); - const request = new get_all_4.GetAllRelationshipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_4.GetRelationshipsRequest(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). + * Set 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. + * @returns Asynchronous set relationship response or `void` in case if `callback` provided. */ - updateRelationship(parameters, callback) { + setRelationship(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: 'Set Relationship with parameters:', })); - const request = new update_4.UpdateRelationshipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new set_4.SetRelationshipRequest(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). + * Update 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. + * @returns Asynchronous update relationship response or `void` in case if `callback` provided. */ - patchRelationship(parameters, callback) { + updateRelationship(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: 'Update Relationship with parameters:', })); - const request = new patch_4.PatchRelationshipRequest(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); @@ -349,7 +349,7 @@ class PubNubDataSync { }); } /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -370,67 +370,67 @@ class PubNubDataSync { }); } /** - * Fetch a paginated list of Users. + * Get 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. + * @returns Asynchronous get users response or `void` in case if `callback` provided. */ - getAllUsers(parametersOrCallback, callback) { + getUsers(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:', + details: 'Get Users with parameters:', })); - const request = new get_all_1.GetAllUsersRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_1.GetUsersRequest(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). + * Set 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. + * @returns Asynchronous set user response or `void` in case if `callback` provided. */ - updateUser(parameters, callback) { + setUser(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:', + details: 'Set User with parameters:', })); - const request = new update_1.UpdateUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new set_1.SetUserRequest(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). + * Update 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. + * @returns Asynchronous update user response or `void` in case if `callback` provided. */ - patchUser(parameters, callback) { + updateUser(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:', + details: 'Update User with parameters:', })); - const request = new patch_1.PatchUserRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + 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); @@ -479,7 +479,7 @@ class PubNubDataSync { }); } /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -500,67 +500,67 @@ class PubNubDataSync { }); } /** - * Fetch a paginated list of Channels. + * Get 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. + * @returns Asynchronous get channels response or `void` in case if `callback` provided. */ - getAllChannels(parametersOrCallback, callback) { + getChannels(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:', + details: 'Get Channels with parameters:', })); - const request = new get_all_2.GetAllChannelsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_2.GetChannelsRequest(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). + * Set 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. + * @returns Asynchronous set channel response or `void` in case if `callback` provided. */ - updateChannel(parameters, callback) { + setChannel(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:', + details: 'Set Channel with parameters:', })); - const request = new update_2.UpdateChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new set_2.SetChannelRequest(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). + * Update 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. + * @returns Asynchronous update channel response or `void` in case if `callback` provided. */ - patchChannel(parameters, callback) { + updateChannel(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:', + details: 'Update Channel with parameters:', })); - const request = new patch_2.PatchChannelRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + 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); @@ -609,7 +609,7 @@ class PubNubDataSync { }); } /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -630,67 +630,67 @@ class PubNubDataSync { }); } /** - * Fetch a paginated list of Memberships. + * Get 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. + * @returns Asynchronous get memberships response or `void` in case if `callback` provided. */ - getAllMemberships(parametersOrCallback, callback) { + getMemberships(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:', + details: 'Get Memberships with parameters:', })); - const request = new get_all_3.GetAllMembershipsRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new get_all_3.GetMembershipsRequest(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). + * Set 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. + * @returns Asynchronous set membership response or `void` in case if `callback` provided. */ - updateMembership(parameters, callback) { + setMembership(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:', + details: 'Set Membership with parameters:', })); - const request = new update_3.UpdateMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + const request = new set_3.SetMembershipRequest(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). + * Update 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. + * @returns Asynchronous update membership response or `void` in case if `callback` provided. */ - patchMembership(parameters, callback) { + updateMembership(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:', + details: 'Update Membership with parameters:', })); - const request = new patch_3.PatchMembershipRequest(Object.assign(Object.assign({}, parameters), { keySet: this.keySet })); + 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); diff --git a/lib/core/types/api/data-sync.js b/lib/core/types/api/data-sync.js index 4c0b549d5..7376c083c 100644 --- a/lib/core/types/api/data-sync.js +++ b/lib/core/types/api/data-sync.js @@ -5,8 +5,23 @@ * Types for Entity Class CRUD operations. */ Object.defineProperty(exports, "__esModule", { value: true }); +exports.serializeDataSyncSort = serializeDataSyncSort; exports.toJsonPointer = toJsonPointer; exports.toJsonPatchOperations = toJsonPatchOperations; +/** + * 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 + */ +function serializeDataSyncSort(sort) { + if (typeof sort === 'string') + return sort; + return Object.entries(sort !== null && sort !== void 0 ? sort : {}).map(([option, order]) => (order !== null ? `${option}:${order}` : option)); +} /** * Convert dot-notation path to JSON Pointer (RFC 6901). * @@ -19,15 +34,19 @@ function toJsonPointer(dotPath) { return '/' + dotPath.split('.').join('/'); } /** - * 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 */ -function toJsonPatchOperations(add, replace, remove) { +function toJsonPatchOperations(input) { + const { add, replace, remove, move, copy, test } = input; const ops = []; if (add) { for (const [dotPath, value] of Object.entries(add)) { @@ -44,5 +63,20 @@ function toJsonPatchOperations(add, replace, remove) { ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); } } + 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; } diff --git a/lib/transport/middleware.js b/lib/transport/middleware.js index 80d467f04..2f828c8d4 100644 --- a/lib/transport/middleware.js +++ b/lib/transport/middleware.js @@ -12,6 +12,10 @@ exports.PubNubMiddleware = void 0; const transport_request_1 = require("../core/types/transport-request"); const categories_1 = __importDefault(require("../core/constants/categories")); const utils_1 = require("../core/utils"); +/** + * HTTP status codes that represent definitive client outcomes and must not be retried. + */ +const NON_RETRIABLE_STATUS_CODES = [404, 409]; /** * Request signature generator. * @@ -124,8 +128,9 @@ class PubNubMiddleware { const [attemptPromise, attemptCancellation] = transport.makeSendable(this.request(req)); activeCancellation = attemptCancellation; const responseHandler = (res, error) => { - const retriableError = error ? error.category !== categories_1.default.PNCancelledCategory : true; - const retriableStatusCode = (!res || res.status >= 400) && (error === null || error === void 0 ? void 0 : error.statusCode) !== 404; + const retriableError = !error || error.category !== categories_1.default.PNCancelledCategory; + const statusCode = error === null || error === void 0 ? void 0 : error.statusCode; + const retriableStatusCode = (!res || res.status >= 400) && !NON_RETRIABLE_STATUS_CODES.includes(statusCode); let delay = -1; if (retriableError && retriableStatusCode && diff --git a/lib/types/index.d.ts b/lib/types/index.d.ts index 76e784e4b..fbf36968c 100644 --- a/lib/types/index.d.ts +++ b/lib/types/index.d.ts @@ -2053,123 +2053,123 @@ declare namespace PubNub { /** * Create entity REST API operation. */ - PNCreateEntityOperation = 'PNCreateEntityOperation', + PNCreateDataSyncEntityOperation = 'PNCreateDataSyncEntityOperation', /** * Get entity REST API operation. */ - PNGetEntityOperation = 'PNGetEntityOperation', + PNGetDataSyncEntityOperation = 'PNGetDataSyncEntityOperation', /** * Get all entities REST API operation. */ - PNGetAllEntitiesOperation = 'PNGetAllEntitiesOperation', + PNGetDataSyncEntitiesOperation = 'PNGetDataSyncEntitiesOperation', /** - * Update entity REST API operation. + * Set entity REST API operation (full replacement via PUT). */ - PNUpdateEntityOperation = 'PNUpdateEntityOperation', + PNSetDataSyncEntityOperation = 'PNSetDataSyncEntityOperation', /** - * Patch entity REST API operation. + * Update entity REST API operation (partial update via PATCH). */ - PNPatchEntityOperation = 'PNPatchEntityOperation', + PNUpdateDataSyncEntityOperation = 'PNUpdateDataSyncEntityOperation', /** * Remove entity REST API operation. */ - PNRemoveEntityOperation = 'PNRemoveEntityOperation', + PNRemoveDataSyncEntityOperation = 'PNRemoveDataSyncEntityOperation', /** * Create relationship REST API operation. */ - PNCreateRelationshipOperation = 'PNCreateRelationshipOperation', + PNCreateDataSyncRelationshipOperation = 'PNCreateDataSyncRelationshipOperation', /** * Get relationship REST API operation. */ - PNGetRelationshipOperation = 'PNGetRelationshipOperation', + PNGetDataSyncRelationshipOperation = 'PNGetDataSyncRelationshipOperation', /** * Get all relationships REST API operation. */ - PNGetAllRelationshipsOperation = 'PNGetAllRelationshipsOperation', + PNGetDataSyncRelationshipsOperation = 'PNGetDataSyncRelationshipsOperation', /** - * Update relationship REST API operation. + * Set relationship REST API operation (full replacement via PUT). */ - PNUpdateRelationshipOperation = 'PNUpdateRelationshipOperation', + PNSetDataSyncRelationshipOperation = 'PNSetDataSyncRelationshipOperation', /** - * Patch relationship REST API operation. + * Update relationship REST API operation (partial update via PATCH). */ - PNPatchRelationshipOperation = 'PNPatchRelationshipOperation', + PNUpdateDataSyncRelationshipOperation = 'PNUpdateDataSyncRelationshipOperation', /** * Remove relationship REST API operation. */ - PNRemoveRelationshipOperation = 'PNRemoveRelationshipOperation', + PNRemoveDataSyncRelationshipOperation = 'PNRemoveDataSyncRelationshipOperation', /** * Create user REST API operation. */ - PNCreateUserOperation = 'PNCreateUserOperation', + PNCreateDataSyncUserOperation = 'PNCreateDataSyncUserOperation', /** * Get user REST API operation. */ - PNGetUserOperation = 'PNGetUserOperation', + PNGetDataSyncUserOperation = 'PNGetDataSyncUserOperation', /** * Get all users REST API operation. */ - PNGetAllUsersOperation = 'PNGetAllUsersOperation', + PNGetDataSyncUsersOperation = 'PNGetDataSyncUsersOperation', /** - * Update user REST API operation. + * Set user REST API operation (full replacement via PUT). */ - PNUpdateUserOperation = 'PNUpdateUserOperation', + PNSetDataSyncUserOperation = 'PNSetDataSyncUserOperation', /** - * Patch user REST API operation. + * Update user REST API operation (partial update via PATCH). */ - PNPatchUserOperation = 'PNPatchUserOperation', + PNUpdateDataSyncUserOperation = 'PNUpdateDataSyncUserOperation', /** * Remove user REST API operation. */ - PNRemoveUserOperation = 'PNRemoveUserOperation', + PNRemoveDataSyncUserOperation = 'PNRemoveDataSyncUserOperation', /** * Create channel REST API operation. */ - PNCreateChannelOperation = 'PNCreateChannelOperation', + PNCreateDataSyncChannelOperation = 'PNCreateDataSyncChannelOperation', /** * Get channel REST API operation. */ - PNGetChannelOperation = 'PNGetChannelOperation', + PNGetDataSyncChannelOperation = 'PNGetDataSyncChannelOperation', /** * Get all channels REST API operation. */ - PNGetAllChannelsOperation = 'PNGetAllChannelsOperation', + PNGetDataSyncChannelsOperation = 'PNGetDataSyncChannelsOperation', /** - * Update channel REST API operation. + * Set channel REST API operation (full replacement via PUT). */ - PNUpdateChannelOperation = 'PNUpdateChannelOperation', + PNSetDataSyncChannelOperation = 'PNSetDataSyncChannelOperation', /** - * Patch channel REST API operation. + * Update channel REST API operation (partial update via PATCH). */ - PNPatchChannelOperation = 'PNPatchChannelOperation', + PNUpdateDataSyncChannelOperation = 'PNUpdateDataSyncChannelOperation', /** * Remove channel REST API operation. */ - PNRemoveChannelOperation = 'PNRemoveChannelOperation', + PNRemoveDataSyncChannelOperation = 'PNRemoveDataSyncChannelOperation', /** * Create membership REST API operation. */ - PNCreateMembershipOperation = 'PNCreateMembershipOperation', + PNCreateDataSyncMembershipOperation = 'PNCreateDataSyncMembershipOperation', /** * Get membership REST API operation. */ - PNGetMembershipOperation = 'PNGetMembershipOperation', + PNGetDataSyncMembershipOperation = 'PNGetDataSyncMembershipOperation', /** * Get all memberships REST API operation. */ - PNGetAllMembershipsOperation = 'PNGetAllMembershipsOperation', + PNGetDataSyncMembershipsOperation = 'PNGetDataSyncMembershipsOperation', /** - * Update membership REST API operation. + * Set membership REST API operation (full replacement via PUT). */ - PNUpdateMembershipOperation = 'PNUpdateMembershipOperation', + PNSetDataSyncMembershipOperation = 'PNSetDataSyncMembershipOperation', /** - * Patch membership REST API operation. + * Update membership REST API operation (partial update via PATCH). */ - PNPatchMembershipOperation = 'PNPatchMembershipOperation', + PNUpdateDataSyncMembershipOperation = 'PNUpdateDataSyncMembershipOperation', /** * Remove membership REST API operation. */ - PNRemoveMembershipOperation = 'PNRemoveMembershipOperation', + PNRemoveDataSyncMembershipOperation = 'PNRemoveDataSyncMembershipOperation', /** * Fetch list of files sent to the channel REST API operation. */ @@ -4035,16 +4035,29 @@ declare namespace PubNub { type DataSyncObjectType = 'entity' | 'relationship'; /** - * Normalized DataSync object kind derived from the wire `className`. + * Scope of the class definition a DataSync object belongs to. + * + * `Global` identifies the built-in classes provided by the service (`User`, `Channel`, + * `Membership`); `SubKey` identifies classes defined by the developer on their own key set. + */ + export type DataSyncClassLevel = 'Global' | 'SubKey'; + + /** + * Normalized DataSync object kind. * * 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. + * class-name strings. Falls back to the raw wire {@link DataSyncObjectType} for developer-defined + * classes. */ export type DataSyncNormalizedType = 'user' | 'channel' | 'membership' | 'entity' | 'relationship'; /** * DataSync entity change payload (create / update). + * + * Mirrors the object as sent by the service. Class identity is not repeated here: it is reported once + * on the event itself as {@link DataSyncData.className} / {@link DataSyncData.classLevel} / + * {@link DataSyncData.classVersion}. */ export type DataSyncEntityData = { /** @@ -4075,36 +4088,27 @@ declare namespace PubNub { * 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). + * + * Class identity is not repeated here: it is reported once on the event itself as + * {@link DataSyncData.className} / {@link DataSyncData.classLevel} / {@link DataSyncData.classVersion}. */ - export type DataSyncRelationshipData = Omit & { + export type DataSyncRelationshipData = DataSyncEntityData & { /** * First entity id in the relationship. + * + * For a membership this is the channel id. */ entityAId?: string; /** * Second entity id in the relationship. + * + * For a membership this is the user id. */ 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; }; /** @@ -4144,16 +4148,20 @@ declare namespace PubNub { /** * 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. + * The built-in `User` / `Channel` / `Membership` classes map to `'user'` / `'channel'` / + * `'membership'`; developer-defined classes fall 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`). + * Object class name. */ className?: string; + /** + * Scope of the class definition: `Global` for the built-in classes (`User` / `Channel` / + * `Membership`), `SubKey` for classes defined by the developer on their own key set. + */ + classLevel?: DataSyncClassLevel; /** * Version of the object class schema (parsed from the wire `classVersion`). */ @@ -5822,14 +5830,14 @@ declare namespace PubNub { */ createEntity(parameters: DataSync.CreateEntityParameters): Promise; /** - * Fetch a specific Entity. + * Get 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. + * Get a specific Entity. * * @param parameters - Request configuration parameters. * @@ -5837,63 +5845,60 @@ declare namespace PubNub { */ getEntity(parameters: DataSync.GetEntityParameters): Promise; /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get 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, + getEntities( + parameters: DataSync.GetEntitiesParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Entities for a given Entity Class. + * Get a paginated list of Entities for a given Entity Class. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get all entities response. + * @returns Asynchronous get entities response. */ - getAllEntities(parameters: DataSync.GetAllEntitiesParameters): Promise; + getEntities(parameters: DataSync.GetEntitiesParameters): Promise; /** - * Update an Entity (full replacement via PUT). + * Set an Entity (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - updateEntity( - parameters: DataSync.UpdateEntityParameters, - callback: ResultCallback, - ): void; + setEntity(parameters: DataSync.SetEntityParameters, callback: ResultCallback): void; /** - * Update an Entity (full replacement via PUT). + * Set an Entity (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update entity response. + * @returns Asynchronous set entity response. */ - updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; + setEntity(parameters: DataSync.SetEntityParameters): Promise; /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Update 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. */ - patchEntity( - parameters: DataSync.PatchEntityParameters, - callback: ResultCallback, + updateEntity( + parameters: DataSync.UpdateEntityParameters, + callback: ResultCallback, ): void; /** - * Patch an Entity (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update entity response. */ - patchEntity(parameters: DataSync.PatchEntityParameters): Promise; + updateEntity(parameters: DataSync.UpdateEntityParameters): Promise; /** * Remove an Entity. * @@ -5931,7 +5936,7 @@ declare namespace PubNub { */ createRelationship(parameters: DataSync.CreateRelationshipParameters): Promise; /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -5941,7 +5946,7 @@ declare namespace PubNub { callback: ResultCallback, ): void; /** - * Fetch a specific Relationship. + * Get a specific Relationship. * * @param parameters - Request configuration parameters. * @@ -5949,65 +5954,63 @@ declare namespace PubNub { */ getRelationship(parameters: DataSync.GetRelationshipParameters): Promise; /** - * Fetch a paginated list of Relationships. + * Get a paginated list of Relationships. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - getAllRelationships( - parameters: DataSync.GetAllRelationshipsParameters, - callback: ResultCallback, + getRelationships( + parameters: DataSync.GetRelationshipsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Relationships. + * Get a paginated list of Relationships. * * @param parameters - Request configuration parameters. * - * @returns Asynchronous get all relationships response. + * @returns Asynchronous get relationships response. */ - getAllRelationships( - parameters: DataSync.GetAllRelationshipsParameters, - ): Promise; + getRelationships(parameters: DataSync.GetRelationshipsParameters): Promise; /** - * Update a Relationship (full replacement via PUT). + * Set a Relationship (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - updateRelationship( - parameters: DataSync.UpdateRelationshipParameters, - callback: ResultCallback, + setRelationship( + parameters: DataSync.SetRelationshipParameters, + callback: ResultCallback, ): void; /** - * Update a Relationship (full replacement via PUT). + * Set a Relationship (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update relationship response. + * @returns Asynchronous set relationship response. */ - updateRelationship(parameters: DataSync.UpdateRelationshipParameters): Promise; + setRelationship(parameters: DataSync.SetRelationshipParameters): Promise; /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Update 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. */ - patchRelationship( - parameters: DataSync.PatchRelationshipParameters, - callback: ResultCallback, + updateRelationship( + parameters: DataSync.UpdateRelationshipParameters, + callback: ResultCallback, ): void; /** - * Patch a Relationship (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update relationship response. */ - patchRelationship(parameters: DataSync.PatchRelationshipParameters): Promise; + updateRelationship(parameters: DataSync.UpdateRelationshipParameters): Promise; /** * Remove a Relationship. * @@ -6042,14 +6045,14 @@ declare namespace PubNub { */ createUser(parameters: DataSync.CreateUserParameters): Promise; /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ getUser(parameters: DataSync.GetUserParameters, callback: ResultCallback): void; /** - * Fetch a specific User. + * Get a specific User. * * @param parameters - Request configuration parameters. * @@ -6057,63 +6060,60 @@ declare namespace PubNub { */ getUser(parameters: DataSync.GetUserParameters): Promise; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param callback - Request completion handler callback. */ - getAllUsers(callback: ResultCallback): void; + getUsers(callback: ResultCallback): void; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - getAllUsers( - parameters: DataSync.GetAllUsersParameters, - callback: ResultCallback, - ): void; + getUsers(parameters: DataSync.GetUsersParameters, callback: ResultCallback): void; /** - * Fetch a paginated list of Users. + * Get a paginated list of Users. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all users response. + * @returns Asynchronous get users response. */ - getAllUsers(parameters?: DataSync.GetAllUsersParameters): Promise; + getUsers(parameters?: DataSync.GetUsersParameters): Promise; /** - * Update a User (full replacement via PUT). + * Set a User (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - updateUser(parameters: DataSync.UpdateUserParameters, callback: ResultCallback): void; + setUser(parameters: DataSync.SetUserParameters, callback: ResultCallback): void; /** - * Update a User (full replacement via PUT). + * Set a User (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update user response. + * @returns Asynchronous set user response. */ - updateUser(parameters: DataSync.UpdateUserParameters): Promise; + setUser(parameters: DataSync.SetUserParameters): Promise; /** - * Patch a User (partial update via JSON Patch RFC 6902). + * Update 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. */ - patchUser(parameters: DataSync.PatchUserParameters, callback: ResultCallback): void; + updateUser(parameters: DataSync.UpdateUserParameters, callback: ResultCallback): void; /** - * Patch a User (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update user response. */ - patchUser(parameters: DataSync.PatchUserParameters): Promise; + updateUser(parameters: DataSync.UpdateUserParameters): Promise; /** * Remove a User. * @@ -6148,14 +6148,14 @@ declare namespace PubNub { */ createChannel(parameters: DataSync.CreateChannelParameters): Promise; /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ getChannel(parameters: DataSync.GetChannelParameters, callback: ResultCallback): void; /** - * Fetch a specific Channel. + * Get a specific Channel. * * @param parameters - Request configuration parameters. * @@ -6163,69 +6163,66 @@ declare namespace PubNub { */ getChannel(parameters: DataSync.GetChannelParameters): Promise; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param callback - Request completion handler callback. */ - getAllChannels(callback: ResultCallback): void; + getChannels(callback: ResultCallback): void; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - getAllChannels( - parameters: DataSync.GetAllChannelsParameters, - callback: ResultCallback, + getChannels( + parameters: DataSync.GetChannelsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Channels. + * Get a paginated list of Channels. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all channels response. + * @returns Asynchronous get channels response. */ - getAllChannels(parameters?: DataSync.GetAllChannelsParameters): Promise; + getChannels(parameters?: DataSync.GetChannelsParameters): Promise; /** - * Update a Channel (full replacement via PUT). + * Set a Channel (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - updateChannel( - parameters: DataSync.UpdateChannelParameters, - callback: ResultCallback, - ): void; + setChannel(parameters: DataSync.SetChannelParameters, callback: ResultCallback): void; /** - * Update a Channel (full replacement via PUT). + * Set a Channel (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update channel response. + * @returns Asynchronous set channel response. */ - updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; + setChannel(parameters: DataSync.SetChannelParameters): Promise; /** - * Patch a Channel (partial update via JSON Patch RFC 6902). + * Update 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. */ - patchChannel( - parameters: DataSync.PatchChannelParameters, - callback: ResultCallback, + updateChannel( + parameters: DataSync.UpdateChannelParameters, + callback: ResultCallback, ): void; /** - * Patch a Channel (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update channel response. */ - patchChannel(parameters: DataSync.PatchChannelParameters): Promise; + updateChannel(parameters: DataSync.UpdateChannelParameters): Promise; /** * Remove a Channel. * @@ -6263,7 +6260,7 @@ declare namespace PubNub { */ createMembership(parameters: DataSync.CreateMembershipParameters): Promise; /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -6273,7 +6270,7 @@ declare namespace PubNub { callback: ResultCallback, ): void; /** - * Fetch a specific Membership. + * Get a specific Membership. * * @param parameters - Request configuration parameters. * @@ -6281,69 +6278,69 @@ declare namespace PubNub { */ getMembership(parameters: DataSync.GetMembershipParameters): Promise; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param callback - Request completion handler callback. */ - getAllMemberships(callback: ResultCallback): void; + getMemberships(callback: ResultCallback): void; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - getAllMemberships( - parameters: DataSync.GetAllMembershipsParameters, - callback: ResultCallback, + getMemberships( + parameters: DataSync.GetMembershipsParameters, + callback: ResultCallback, ): void; /** - * Fetch a paginated list of Memberships. + * Get a paginated list of Memberships. * * @param [parameters] - Request configuration parameters. * - * @returns Asynchronous get all memberships response. + * @returns Asynchronous get memberships response. */ - getAllMemberships(parameters?: DataSync.GetAllMembershipsParameters): Promise; + getMemberships(parameters?: DataSync.GetMembershipsParameters): Promise; /** - * Update a Membership (full replacement via PUT). + * Set a Membership (full replacement via PUT). * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ - updateMembership( - parameters: DataSync.UpdateMembershipParameters, - callback: ResultCallback, + setMembership( + parameters: DataSync.SetMembershipParameters, + callback: ResultCallback, ): void; /** - * Update a Membership (full replacement via PUT). + * Set a Membership (full replacement via PUT). * * @param parameters - Request configuration parameters. * - * @returns Asynchronous update membership response. + * @returns Asynchronous set membership response. */ - updateMembership(parameters: DataSync.UpdateMembershipParameters): Promise; + setMembership(parameters: DataSync.SetMembershipParameters): Promise; /** - * Patch a Membership (partial update via JSON Patch RFC 6902). + * Update 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, + updateMembership( + parameters: DataSync.UpdateMembershipParameters, + callback: ResultCallback, ): void; /** - * Patch a Membership (partial update via JSON Patch RFC 6902). + * Update 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. + * @returns Asynchronous update membership response. */ - patchMembership(parameters: DataSync.PatchMembershipParameters): Promise; + updateMembership(parameters: DataSync.UpdateMembershipParameters): Promise; /** * Remove a Membership. * @@ -9220,6 +9217,13 @@ declare namespace PubNub { * Whether `write` operations are permitted for corresponding level or not. */ write?: boolean; + /** + * Whether `create` operations are permitted for corresponding level or not. + * + * Used by DataSync `Channel` grants (a DataSync Channel is an entity, granted through the reused + * `channels` scope). Ignored for classic messaging channels. + */ + create?: boolean; /** * Whether `get` operations are permitted for corresponding level or not. */ @@ -9265,6 +9269,13 @@ declare namespace PubNub { * Uuid-specific token permissions. */ export type UuidTokenPermissions = { + /** + * Whether `create` operations are permitted for corresponding level or not. + * + * Used by DataSync `User` grants (a DataSync User is an entity, granted through the reused + * `users` / `uuids` scope). Ignored for App Context UUID-metadata grants. + */ + create?: boolean; /** * Whether `get` operations are permitted for corresponding level or not. */ @@ -9282,7 +9293,7 @@ declare namespace PubNub { /** * User-specific token permissions. */ - type UserTokenPermissions = UuidTokenPermissions; + export type UserTokenPermissions = UuidTokenPermissions; /** * DataSync entity-level token permissions. @@ -9446,8 +9457,19 @@ declare namespace PubNub { * Object containing resource permissions. */ resources?: { + /** + * Object containing `user` permissions. + * + * Preferred DataSync terminology for granting permissions on `User` resources (create / get / + * update / delete). Serialized to the same wire scope as {@link uuids}; may be combined with + * `channels`, `groups`, `uuids`, and `dataSync` in a single grant. + */ + users?: Record; /** * Object containing `uuid` metadata permissions. + * + * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. + * `uuids` remains for App Context UUID-metadata permissions. */ uuids?: Record; /** @@ -9467,9 +9489,19 @@ declare namespace PubNub { * Object containing permissions to multiple resources specified by a RegEx pattern. */ patterns?: { + /** + * Object containing `user` permissions to apply to all `users` matching the RegEx pattern. + * + * Preferred DataSync terminology for granting permissions on `User` resources. Serialized to the + * same wire scope as {@link uuids}; may be combined with `channels`, `groups`, `uuids`, and + * `dataSync`. + */ + users?: Record; /** * Object containing `uuid` metadata permissions to apply to all `uuids` matching the RegEx * pattern. + * + * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. */ uuids?: Record; /** @@ -9540,11 +9572,21 @@ declare namespace PubNub { /** * 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. */ @@ -9641,6 +9683,52 @@ declare namespace PubNub { 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; + }; + /** * Channel-specific permissions. * @@ -10009,12 +10097,32 @@ declare namespace PubNub { /** Filter expression for results. */ 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; + + /** + * Class hierarchy level used to disambiguate classes that share a name at different levels. + * + * `Global` targets a class provided by the service; `SubKey` targets one defined on the key set. + * Mirrors the event-side `DataSyncClassLevel` reported on subscribe messages. + */ + export type ClassLevel = 'Global' | 'SubKey'; + /** * Single-entity response envelope. */ @@ -10044,15 +10152,25 @@ declare namespace PubNub { }; /** - * Entity properties for create requests. + * 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; + }; + + /** + * 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; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10060,13 +10178,15 @@ declare namespace PubNub { }; /** - * 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 SetEntityParameters}. `entityClass` is immutable after creation and therefore + * has no place in updates. */ - export type UpdateEntityProperties = { + export type SetEntityData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10102,19 +10222,26 @@ declare namespace PubNub { */ 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; + /** + * Class hierarchy level of `class`. Set at creation time and 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. + * Omit to let the service apply its default. */ - entity: CreateEntityProperties & { - /** - * Optional entity ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; + classLevel?: ClassLevel; + /** + * Mutable, versioned entity data (class version, status, and payload). + * + * 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; }; /** @@ -10130,7 +10257,7 @@ declare namespace PubNub { * * `entityClass` is required — entities are always listed within the context of their class. */ - export type GetAllEntitiesParameters = PagedRequestParameters & { + export type GetEntitiesParameters = PagedRequestParameters & { /** Entity class name to filter by (required). */ entityClass: string; /** @@ -10147,16 +10274,16 @@ declare namespace PubNub { }; /** - * Update Entity request parameters (full replacement via PUT). + * Set 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 = { + export type SetEntityParameters = { /** Entity ID. */ id: string; - /** Complete entity properties for replacement (excludes immutable `entityClass`). */ - entity: UpdateEntityProperties; + /** Complete, mutable entity data for replacement (excludes immutable `entityClass`). */ + data: SetEntityData; /** * ETag for optimistic concurrency control. * If provided, the update only succeeds if the server's ETag matches. @@ -10165,14 +10292,14 @@ declare namespace PubNub { }; /** - * Patch Entity request parameters (partial update via JSON Patch RFC 6902). + * Update 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 = { + export type UpdateEntityParameters = { /** Entity ID. */ id: string; /** @@ -10216,6 +10343,42 @@ declare namespace PubNub { * ``` */ 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. @@ -10243,13 +10406,13 @@ declare namespace PubNub { export type GetEntityResponse = DataSyncEntityResponse; /** Response for listing entities. */ - export type GetAllEntitiesResponse = DataSyncPagedResponse; + export type GetEntitiesResponse = DataSyncPagedResponse; /** Response for updating an entity (PUT). */ - export type UpdateEntityResponse = DataSyncEntityResponse; + export type SetEntityResponse = DataSyncEntityResponse; /** Response for patching an entity (PATCH). */ - export type PatchEntityResponse = DataSyncEntityResponse; + export type UpdateEntityResponse = DataSyncEntityResponse; /** Response for removing an entity. */ export type RemoveEntityResponse = { @@ -10258,19 +10421,15 @@ declare namespace PubNub { }; /** - * 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; /** User-defined JSON payload. */ @@ -10278,19 +10437,15 @@ declare namespace PubNub { }; /** - * 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 SetRelationshipParameters}. `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 SetRelationshipData = { /** Version of the relationship class schema. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload. */ @@ -10330,17 +10485,18 @@ declare namespace PubNub { */ export type CreateRelationshipParameters = { /** - * Relationship properties to create. - * - * All relationship properties go inside `relationship` because they map to the request body envelope. + * Optional relationship ID. + * Server auto-generates a UUID if not provided. */ - relationship: CreateRelationshipProperties & { - /** - * Optional relationship ID. - * Server auto-generates a UUID if not provided. - */ - id?: string; - }; + 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; }; /** @@ -10354,7 +10510,7 @@ declare namespace PubNub { /** * Get All Relationships request parameters. */ - export type GetAllRelationshipsParameters = PagedRequestParameters & { + export type GetRelationshipsParameters = PagedRequestParameters & { /** Relationship class name (required by the server). */ relationshipClass: string; /** Relationship class version. */ @@ -10373,13 +10529,17 @@ declare namespace PubNub { }; /** - * Update Relationship request parameters (full replacement via PUT). + * Set Relationship request parameters (full replacement via PUT). */ - export type UpdateRelationshipParameters = { + export type SetRelationshipParameters = { /** 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: SetRelationshipData; /** * ETag for optimistic concurrency control. * If provided, the update only succeeds if the server's ETag matches. @@ -10388,26 +10548,26 @@ declare namespace PubNub { }; /** - * Patch Relationship request parameters (partial update via JSON Patch RFC 6902). + * Update 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 = { + export type UpdateRelationshipParameters = { /** Relationship ID. */ id: string; /** * 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', * } * ``` */ @@ -10415,29 +10575,46 @@ declare namespace PubNub { /** * 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. @@ -10465,13 +10642,13 @@ declare namespace PubNub { export type GetRelationshipResponse = DataSyncEntityResponse; /** Response for listing relationships. */ - export type GetAllRelationshipsResponse = DataSyncPagedResponse; + export type GetRelationshipsResponse = DataSyncPagedResponse; /** Response for updating a relationship (PUT). */ - export type UpdateRelationshipResponse = DataSyncEntityResponse; + export type SetRelationshipResponse = DataSyncEntityResponse; /** Response for patching a relationship (PATCH). */ - export type PatchRelationshipResponse = DataSyncEntityResponse; + export type UpdateRelationshipResponse = DataSyncEntityResponse; /** Response for removing a relationship. */ export type RemoveRelationshipResponse = { @@ -10480,11 +10657,14 @@ declare namespace PubNub { }; /** - * 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; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10518,23 +10698,29 @@ declare namespace PubNub { */ 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; + /** + * Class hierarchy level of the user's entity class. Set at creation time and immutable afterward. + * + * Omit to let the service apply its default. + */ + classLevel?: ClassLevel; + /** 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 SetUserParameters}. */ - export type UpdateUserProperties = { + export type SetUserData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10552,7 +10738,7 @@ declare namespace PubNub { /** * Get All Users request parameters. */ - export type GetAllUsersParameters = PagedRequestParameters & { + export type GetUsersParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns users for the latest version. */ @@ -10564,13 +10750,13 @@ declare namespace PubNub { }; /** - * Update User request parameters (full replacement via PUT). + * Set User request parameters (full replacement via PUT). */ - export type UpdateUserParameters = { + export type SetUserParameters = { /** User ID. */ id: string; - /** Complete user properties for replacement. */ - user: UpdateUserProperties; + /** Complete, mutable user data for replacement. */ + data: SetUserData; /** * ETag for optimistic concurrency control. * If provided, the update only succeeds if the server's ETag matches. @@ -10579,14 +10765,14 @@ declare namespace PubNub { }; /** - * Patch User request parameters (partial update via JSON Patch RFC 6902). + * Update 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 = { + export type UpdateUserParameters = { /** User ID. */ id: string; /** @@ -10604,6 +10790,23 @@ declare namespace PubNub { * The SDK converts these to JSON Patch "remove" operations. */ 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. */ @@ -10629,13 +10832,13 @@ declare namespace PubNub { export type GetUserResponse = DataSyncEntityResponse; /** Response for listing users. */ - export type GetAllUsersResponse = DataSyncPagedResponse; + export type GetUsersResponse = DataSyncPagedResponse; /** Response for updating a user (PUT). */ - export type UpdateUserResponse = DataSyncEntityResponse; + export type SetUserResponse = DataSyncEntityResponse; /** Response for patching a user (PATCH). */ - export type PatchUserResponse = DataSyncEntityResponse; + export type UpdateUserResponse = DataSyncEntityResponse; /** Response for removing a user. */ export type RemoveUserResponse = { @@ -10644,11 +10847,14 @@ declare namespace PubNub { }; /** - * 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; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10656,11 +10862,14 @@ declare namespace PubNub { }; /** - * 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 SetChannelParameters}. */ - export type UpdateChannelProperties = { + export type SetChannelData = { /** Version of the entity class schema. */ - entityClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload conforming to the entity class schema. */ @@ -10694,15 +10903,19 @@ declare namespace PubNub { */ 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; + /** + * Class hierarchy level of the channel's entity class. Set at creation time and immutable + * afterward. + * + * Omit to let the service apply its default. + */ + classLevel?: ClassLevel; + /** Mutable, versioned channel data (class version, status, and payload). */ + data: CreateChannelData; }; /** @@ -10716,7 +10929,7 @@ declare namespace PubNub { /** * Get All Channels request parameters. */ - export type GetAllChannelsParameters = PagedRequestParameters & { + export type GetChannelsParameters = PagedRequestParameters & { /** * Entity class version. If not provided, the server returns channels for the latest version. */ @@ -10728,13 +10941,13 @@ declare namespace PubNub { }; /** - * Update Channel request parameters (full replacement via PUT). + * Set Channel request parameters (full replacement via PUT). */ - export type UpdateChannelParameters = { + export type SetChannelParameters = { /** Channel ID. */ id: string; - /** Complete channel properties for replacement. */ - channel: UpdateChannelProperties; + /** Complete, mutable channel data for replacement. */ + data: SetChannelData; /** * ETag for optimistic concurrency control. */ @@ -10742,13 +10955,13 @@ declare namespace PubNub { }; /** - * Patch Channel request parameters (partial update via JSON Patch RFC 6902). + * Update 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 = { + export type UpdateChannelParameters = { /** Channel ID. */ id: string; /** @@ -10766,6 +10979,23 @@ declare namespace PubNub { * The SDK converts these to JSON Patch "remove" operations. */ 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. */ @@ -10791,13 +11021,13 @@ declare namespace PubNub { export type GetChannelResponse = DataSyncEntityResponse; /** Response for listing channels. */ - export type GetAllChannelsResponse = DataSyncPagedResponse; + export type GetChannelsResponse = DataSyncPagedResponse; /** Response for updating a channel (PUT). */ - export type UpdateChannelResponse = DataSyncEntityResponse; + export type SetChannelResponse = DataSyncEntityResponse; /** Response for patching a channel (PATCH). */ - export type PatchChannelResponse = DataSyncEntityResponse; + export type UpdateChannelResponse = DataSyncEntityResponse; /** Response for removing a channel. */ export type RemoveChannelResponse = { @@ -10806,17 +11036,15 @@ declare namespace PubNub { }; /** - * 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; /** User-defined JSON payload. */ @@ -10824,19 +11052,15 @@ declare namespace PubNub { }; /** - * 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 SetMembershipParameters}. The server rejects a PUT that omits `classVersion` + * (`SYN-0004: must not be null`), mirroring {@link SetRelationshipData}. */ - export type UpdateMembershipProperties = { - /** User ID reference. */ - userId: string; - /** Channel ID reference. */ - channelId: string; + export type SetMembershipData = { /** Version of the Membership relationship class. */ - relationshipClassVersion: number; + classVersion: number; /** Optional lifecycle status. */ status?: string; /** User-defined JSON payload. */ @@ -10877,15 +11101,16 @@ declare namespace PubNub { */ 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; }; /** @@ -10899,7 +11124,7 @@ declare namespace PubNub { /** * Get All Memberships request parameters. */ - export type GetAllMembershipsParameters = PagedRequestParameters & { + export type GetMembershipsParameters = PagedRequestParameters & { /** Filter memberships by user ID. */ userId?: string; /** Filter memberships by channel ID. */ @@ -10916,13 +11141,17 @@ declare namespace PubNub { }; /** - * Update Membership request parameters (full replacement via PUT). + * Set Membership request parameters (full replacement via PUT). */ - export type UpdateMembershipParameters = { + export type SetMembershipParameters = { /** 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: SetMembershipData; /** * ETag for optimistic concurrency control. */ @@ -10930,13 +11159,13 @@ declare namespace PubNub { }; /** - * Patch Membership request parameters (partial update via JSON Patch RFC 6902). + * Update 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 = { + export type UpdateMembershipParameters = { /** Membership ID. */ id: string; /** @@ -10954,6 +11183,23 @@ declare namespace PubNub { * The SDK converts these to JSON Patch "remove" operations. */ 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. */ @@ -10979,13 +11225,13 @@ declare namespace PubNub { export type GetMembershipResponse = DataSyncEntityResponse; /** Response for listing memberships. */ - export type GetAllMembershipsResponse = DataSyncPagedResponse; + export type GetMembershipsResponse = DataSyncPagedResponse; /** Response for updating a membership (PUT). */ - export type UpdateMembershipResponse = DataSyncEntityResponse; + export type SetMembershipResponse = DataSyncEntityResponse; /** Response for patching a membership (PATCH). */ - export type PatchMembershipResponse = DataSyncEntityResponse; + export type UpdateMembershipResponse = DataSyncEntityResponse; /** Response for removing a membership. */ export type RemoveMembershipResponse = { From 25b05863ab03576e89e880616d4f8e1cb26b9152 Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Mon, 17 Aug 2026 21:38:48 +0530 Subject: [PATCH 25/27] parseToken to parse users permissions, fix stale test failures of grantToken --- src/core/components/token_manager.ts | 42 +- src/core/types/api/access-manager.ts | 198 ++++-- .../components/token_manager.test.ts | 93 +++ .../integration/endpoints/grant_token.test.ts | 597 +++++++++++++----- .../access_manager_grant_token.test.ts | 188 ++++-- 5 files changed, 860 insertions(+), 258 deletions(-) diff --git a/src/core/components/token_manager.ts b/src/core/components/token_manager.ts index d3e69eef2..ae0bf6d9c 100644 --- a/src/core/components/token_manager.ts +++ b/src/core/components/token_manager.ts @@ -20,9 +20,12 @@ type DataSyncWireKey = 'datasync:entities' | 'datasync:relationships' | 'datasyn /** * Raw bit-encoded permissions section (`res` or `pat`) stored in the access token. + * + * `usr` is the wire key for permissions granted through the `users` scope; it is distinct from the + * legacy App Context `uuid` scope. */ type RawTokenPermissions = Record<'chan' | 'grp' | 'uuid', Record> & - Partial>>; + Partial>>; /** * Raw parsed token. @@ -120,9 +123,11 @@ export class TokenManager { if (parsed !== undefined) { const uuidResourcePermissions = parsed.res.uuid ? Object.keys(parsed.res.uuid) : []; + const userResourcePermissions = parsed.res.usr ? Object.keys(parsed.res.usr) : []; const channelResourcePermissions = Object.keys(parsed.res.chan); const groupResourcePermissions = Object.keys(parsed.res.grp); const uuidPatternPermissions = parsed.pat.uuid ? Object.keys(parsed.pat.uuid) : []; + const userPatternPermissions = parsed.pat.usr ? Object.keys(parsed.pat.usr) : []; const channelPatternPermissions = Object.keys(parsed.pat.chan); const groupPatternPermissions = Object.keys(parsed.pat.grp); @@ -135,10 +140,11 @@ export class TokenManager { }; const uuidResources = uuidResourcePermissions.length > 0; + const userResources = userResourcePermissions.length > 0; const channelResources = channelResourcePermissions.length > 0; const groupResources = groupResourcePermissions.length > 0; - if (uuidResources || channelResources || groupResources) { + if (uuidResources || userResources || channelResources || groupResources) { result.resources = {}; if (uuidResources) { @@ -146,6 +152,11 @@ export class TokenManager { uuidResourcePermissions.forEach((id) => (uuids[id] = this.extractPermissions(parsed.res.uuid[id]))); } + if (userResources) { + const users: typeof result.resources.users = (result.resources.users = {}); + userResourcePermissions.forEach((id) => (users[id] = this.extractUserPermissions(parsed.res.usr![id]))); + } + if (channelResources) { const channels: typeof result.resources.channels = (result.resources.channels = {}); channelResourcePermissions.forEach((id) => (channels[id] = this.extractPermissions(parsed.res.chan[id]))); @@ -161,10 +172,11 @@ export class TokenManager { if (resourceDataSync) (result.resources ??= {}).dataSync = resourceDataSync; const uuidPatterns = uuidPatternPermissions.length > 0; + const userPatterns = userPatternPermissions.length > 0; const channelPatterns = channelPatternPermissions.length > 0; const groupPatterns = groupPatternPermissions.length > 0; - if (uuidPatterns || channelPatterns || groupPatterns) { + if (uuidPatterns || userPatterns || channelPatterns || groupPatterns) { result.patterns = {}; if (uuidPatterns) { @@ -172,6 +184,11 @@ export class TokenManager { uuidPatternPermissions.forEach((id) => (uuids[id] = this.extractPermissions(parsed.pat.uuid[id]))); } + if (userPatterns) { + const users: typeof result.patterns.users = (result.patterns.users = {}); + userPatternPermissions.forEach((id) => (users[id] = this.extractUserPermissions(parsed.pat.usr![id]))); + } + if (channelPatterns) { const channels: typeof result.patterns.channels = (result.patterns.channels = {}); channelPatternPermissions.forEach((id) => (channels[id] = this.extractPermissions(parsed.pat.chan[id]))); @@ -223,6 +240,25 @@ export class TokenManager { return permissionsResult; } + /** + * Extract `User` scope access permission information. + * + * Permissions granted through the `users` scope only carry the CRUD operations, so the same bits + * as DataSync resources are decoded. + * + * @param permissions - Bit-encoded resource permissions. + * + * @returns Human-readable `User` resource permissions. + */ + private extractUserPermissions(permissions: number): PAM.UserScopePermissions { + return { + create: (permissions & 16) === 16, + get: (permissions & 32) === 32, + update: (permissions & 64) === 64, + delete: (permissions & 8) === 8, + }; + } + /** * Extract DataSync permission scopes from a token permissions section. * diff --git a/src/core/types/api/access-manager.ts b/src/core/types/api/access-manager.ts index a201163db..14b6debeb 100644 --- a/src/core/types/api/access-manager.ts +++ b/src/core/types/api/access-manager.ts @@ -104,8 +104,31 @@ export type UuidTokenPermissions = { /** * User-specific token permissions. + * + * DataSync `User` resources only support the CRUD operations; `read` / `write` / `manage` / `join` + * remain classic messaging concepts and are intentionally not part of this type. */ -export type UserTokenPermissions = UuidTokenPermissions; +export type UserTokenPermissions = { + /** + * 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 entity-level token permissions. @@ -266,6 +289,64 @@ export type ObjectsGrantTokenParameters = { authorizedUserId?: string; }; +/** + * Grant scopes which may appear in both the `resources` and `patterns` sections. + * + * Keys are concrete resource ids for `resources` and RegEx patterns for `patterns`. + */ +type CommonGrantScopes = { + /** + * Object containing `channel` permissions. + */ + channels?: Record; + + /** + * Object containing `channel group` permissions. + */ + groups?: Record; + + /** + * Object containing DataSync entity-level permissions. + */ + dataSync?: DataSyncTokenScopes; +}; + +/** + * Principal grant scope. + * + * `users` and `uuids` name the same underlying target, so only one of them may be supplied in a + * single grant — providing both is a compile-time error (and is rejected at runtime as well). + */ +type PrincipalGrantScopes = + | { + /** + * Object containing `user` permissions. + * + * Preferred DataSync terminology for granting permissions on `User` resources (create / get / + * update / delete). May be combined with `channels`, `groups`, and `dataSync` in a single + * grant, but not with the deprecated {@link PrincipalGrantScopes.uuids | uuids} scope. + */ + users?: Record; + + uuids?: never; + } + | { + /** + * Object containing `uuid` metadata permissions. + * + * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer `users`. + * `uuids` remains for App Context UUID-metadata permissions. + */ + uuids?: Record; + + users?: never; + }; + +/** + * Permission scopes accepted by the `resources` and `patterns` sections of a grant. + */ +export type GrantScopes = CommonGrantScopes & PrincipalGrantScopes; + /** * Generate token with permissions. * @@ -282,80 +363,17 @@ export type GrantTokenParameters = { /** * Object containing resource permissions. + * + * Keys within each scope are concrete resource ids. `users` and `uuids` are mutually exclusive. */ - resources?: { - /** - * Object containing `user` permissions. - * - * Preferred DataSync terminology for granting permissions on `User` resources (create / get / - * update / delete). Serialized to the same wire scope as {@link uuids}; may be combined with - * `channels`, `groups`, `uuids`, and `dataSync` in a single grant. - */ - users?: Record; - - /** - * Object containing `uuid` metadata permissions. - * - * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. - * `uuids` remains for App Context 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; - }; + resources?: GrantScopes; /** * Object containing permissions to multiple resources specified by a RegEx pattern. + * + * Keys within each scope are RegEx patterns. `users` and `uuids` are mutually exclusive. */ - patterns?: { - /** - * Object containing `user` permissions to apply to all `users` matching the RegEx pattern. - * - * Preferred DataSync terminology for granting permissions on `User` resources. Serialized to the - * same wire scope as {@link uuids}; may be combined with `channels`, `groups`, `uuids`, and - * `dataSync`. - */ - users?: Record; - - /** - * Object containing `uuid` metadata permissions to apply to all `uuids` matching the RegEx - * pattern. - * - * @deprecated Legacy App Context terminology. For DataSync `User` grants prefer {@link users}. - */ - 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; - }; + patterns?: GrantScopes; /** * Extra metadata to be published with the request. @@ -423,6 +441,11 @@ export type Token = { * Permissions granted to specific resources. */ resources?: Partial>> & { + /** + * Permissions granted to specific `User` resources through the `users` scope. + */ + users?: Record; + /** * DataSync entity-level permissions granted to specific resources. */ @@ -433,6 +456,12 @@ export type Token = { * Permissions granted to resources which match specified regular expression. */ patterns?: Partial>> & { + /** + * Permissions granted through the `users` scope to `User` resources which match specified + * regular expression. + */ + users?: Record; + /** * DataSync entity-level permissions granted to resources which match specified regular expression. */ @@ -543,6 +572,35 @@ export type Permissions = { join: boolean; }; +/** + * Granted `User` scope permissions. + * + * Decoded from the token `res` / `pat` wire key `usr`, which backs the `users` grant scope. Mirrors + * {@link UserTokenPermissions}: only the CRUD-relevant operations apply, so `read` / `write` / + * `manage` / `join` are intentionally not part of this type. + */ +export type UserScopePermissions = { + /** + * Resource `create` permission. + */ + create: boolean; + + /** + * Resource `get` permission. + */ + get: boolean; + + /** + * Resource `update` permission. + */ + update: boolean; + + /** + * Resource `delete` permission. + */ + delete: boolean; +}; + /** * Granted DataSync entity-level permissions. * diff --git a/test/integration/components/token_manager.test.ts b/test/integration/components/token_manager.test.ts index e3a144155..be4d0fe7b 100644 --- a/test/integration/components/token_manager.test.ts +++ b/test/integration/components/token_manager.test.ts @@ -65,6 +65,99 @@ describe('#components/token_manager', () => { assert(permissions.patterns.groups['.*'] !== undefined); assert(permissions.patterns.groups['.*'].read === true); }); + + it('contains correct `users` scope permissions', () => { + // Token granting `users` scope permissions (wire key `usr`) as resources (get / update / + // delete on `user-alice-042`) and as a pattern (full CRUD on `user-.*`), alongside a classic + // channel resource permission. + const tokenWithUsers = + 'qGF2AmF0GmpmPWBjdHRsGDxjcmVzpWRjaGFuoWljaGFubmVsLTEBY2dycKBkdXVpZKBjdXNyoW51c2VyLWFsaWNlLT' + + 'A0MhhoY3NwY6BjcGF0pWRjaGFuoGNncnCgZHV1aWSgY3VzcqFndXNlci0uKhh4Y3NwY6BkdXVpZG9kYXRhU3luYy10' + + 'ZXN0ZXJkbWV0YaBjc2lnWCAHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw'; + const permissions = pubnub.parseToken(tokenWithUsers)!; + + assert(permissions.authorized_uuid === 'dataSync-tester'); + + // Resource-level `users` permissions. + assert(permissions.resources !== undefined); + assert(typeof permissions.resources.users === 'object'); + assert.deepEqual(permissions.resources.users!['user-alice-042'], { + create: false, + get: true, + update: true, + delete: true, + }); + + // `users` is a distinct scope from the legacy App Context `uuids` scope. + assert(permissions.resources.uuids === undefined); + + // Non-`users` scopes in the same token are unaffected. + assert(permissions.resources.channels!['channel-1']!.read === true); + + // Pattern-level `users` permissions. + assert(permissions.patterns !== undefined); + assert(typeof permissions.patterns.users === 'object'); + assert.deepEqual(permissions.patterns.users!['user-.*'], { + create: true, + get: true, + update: true, + delete: true, + }); + }); + + it('contains correct DataSync permissions', () => { + // Token granting DataSync resource permissions (entities / relationships / memberships) and a + // DataSync entity pattern permission. + const tokenWithDataSync = + 'qEF2AkF0GmpjVu5DdHRsGDxDcmVzqERjaGFuoENncnCgQ3NwY6BDdXNyoER1dWlkoFFkYXRhc3luYzplbnRpdGllc6' + + 'FpaHVtYW4tMDEyGCBWZGF0YXN5bmM6cmVsYXRpb25zaGlwc6F4JnN0dWRlbnQtYWxpY2UtMDQyOnNjaG9vbC1ncmVl' + + 'bndvb2QtMDAxGCBUZGF0YXN5bmM6bWVtYmVyc2hpcHOheCZ1c2VyLWFsaWNlLTA0MjpjaGFubmVsLWVuZ2luZWVyaW' + + '5nLTAwMRhgQ3BhdKZEY2hhbqBDZ3JwoENzcGOgQ3VzcqBEdXVpZKBRZGF0YXN5bmM6ZW50aXRpZXOhZ2h1bWFuLSoY' + + 'eERtZXRhoER1dWlkb2RhdGFTeW5jLXRlc3RlckNzaWdYIIpWPzFf3TIyaoHMONNbwce9IeFNwdmyZKo-y4CB5qi-'; + const permissions = pubnub.parseToken(tokenWithDataSync)!; + + assert(permissions.authorized_uuid === 'dataSync-tester'); + + // Resource-level DataSync permissions. + assert(permissions.resources !== undefined); + const resourceDataSync = permissions.resources.dataSync; + assert(typeof resourceDataSync === 'object'); + + assert(resourceDataSync!.entities !== undefined); + assert.deepEqual(resourceDataSync!.entities!['human-012'], { + create: false, + get: true, + update: false, + delete: false, + }); + + assert(resourceDataSync!.relationships !== undefined); + assert.deepEqual(resourceDataSync!.relationships!['student-alice-042:school-greenwood-001'], { + create: false, + get: true, + update: false, + delete: false, + }); + + assert(resourceDataSync!.memberships !== undefined); + assert.deepEqual(resourceDataSync!.memberships!['user-alice-042:channel-engineering-001'], { + create: false, + get: true, + update: true, + delete: false, + }); + + // Pattern-level DataSync permissions. + assert(permissions.patterns !== undefined); + const patternDataSync = permissions.patterns.dataSync; + assert(typeof patternDataSync === 'object'); + assert.deepEqual(patternDataSync!.entities!['human-*'], { + create: true, + get: true, + update: true, + delete: true, + }); + }); }); describe('supports token update', () => { diff --git a/test/integration/endpoints/grant_token.test.ts b/test/integration/endpoints/grant_token.test.ts index 247dcf76f..6b021a254 100644 --- a/test/integration/endpoints/grant_token.test.ts +++ b/test/integration/endpoints/grant_token.test.ts @@ -5,6 +5,26 @@ import utils from '../../utils'; import PubNub from '../../../src/node/index'; import { PubNubError } from '../../../src/errors/pubnub-error'; +/** + * Permission bits used by the grant token wire format. + * + * `create` (16) is only meaningful for DataSync scopes; `read` / `write` / `manage` / `join` remain + * classic messaging concepts. + */ +const JOIN = 128; +const UPDATE = 64; +const GET = 32; +const CREATE = 16; +const DELETE = 8; +const MANAGE = 4; +const WRITE = 2; +const READ = 1; + +/** + * Scope maps which the serializer always emits, even when a grant doesn't use them. + */ +const EMPTY_SCOPES = { channels: {}, groups: {}, uuids: {}, users: {}, spaces: {} }; + describe('grant token endpoint', () => { let originalVersionFunction: (() => string) | null = null; let clock: sinon.SinonFakeTimers; @@ -43,175 +63,454 @@ describe('grant token endpoint', () => { pubnub.destroy(true); }); + /** + * Match the stable parts of the grant query string. + * + * The `v2` signature is a HMAC over the request body, so pinning its exact value would make every + * body change fail as an unmatched interceptor (a request timeout) instead of a readable assertion + * failure. The signature is shape-checked instead. + */ + const grantQuery = (query: Record) => + query.uuid === 'myUUID' && + query.pnsdk === `PubNub-JS-Nodejs/${pubnub.getVersion()}` && + query.timestamp === '1571360790' && + typeof query.signature === 'string' && + (query.signature as string).startsWith('v2.'); + + /** + * Grant request body as it appears on the wire. + * + * Every scope map is bit-encoded, so permissions are plain numbers keyed by resource id. + */ + type GrantRequestBody = { + ttl?: number; + permissions: { + uuid?: string; + resources: Record>; + patterns: Record>; + meta: Record; + }; + }; + + /** + * Mock a successful grant and capture the request body which the SDK sent. + */ + const mockGrant = () => { + let requestBody: GrantRequestBody; + const scope = utils + .createNock() + .post('/v3/pam/mySubscribeKey/grant', (body) => { + requestBody = body as GrantRequestBody; + return true; + }) + .query(grantQuery) + .reply(200, { message: 'Success', data: { token: 'token' } }); + + return { scope, body: () => requestBody }; + }; + + /** + * Assert that a grant is rejected during validation, before any request is sent. + */ + const assertRejects = async (parameters: unknown, message: string) => { + const scope = utils + .createNock() + .post('/v3/pam/mySubscribeKey/grant') + .query(() => true) + .reply(200, { message: 'Success', data: { token: 'token' } }); + + await assert.rejects( + () => pubnub.grantToken(parameters as Parameters[0]), + (err: unknown) => { + assert(err instanceof PubNubError); + assert.strictEqual(err.status!.message, message); + return true; + }, + ); + + assert.strictEqual(scope.isDone(), false, 'no request should be sent when validation fails'); + }; + describe('#grantToken', () => { describe('##validation', () => { - it('ensure resources or patterns', (done) => { - const scope = utils - .createNock() - .post('/v3/pam/mySubscribeKey/grant') - .query({ - uuid: 'myUUID', - pnsdk: `PubNub-JS-Nodejs/${pubnub.getVersion()}`, - timestamp: 1571360790, - signature: 'v2.pJobOYLaDTsauQo8UZa-4Eu4JKYYRuaeyPS8IHpNN-E', - }) - .reply(200, { - message: 'Success', - data: { - token: 'token', - }, - }); + it('ensure resources or patterns', async () => { + await assertRejects({ ttl: 1440 }, 'Missing values for either Resources or Patterns'); + }); - pubnub - .grantToken({ - ttl: 1440, - }) - .catch((err) => { - try { - assert.equal(scope.isDone(), false); - assert.equal(err.status.message, 'Missing values for either Resources or Patterns'); - done(); - } catch (error) { - done(error); - } - }); - }); - - it('fail on resources without any resource permissions', (done) => { - const scope = utils - .createNock() - .post('/v3/pam/mySubscribeKey/grant') - .query({ - uuid: 'myUUID', - pnsdk: `PubNub-JS-Nodejs/${pubnub.getVersion()}`, - timestamp: 1571360790, - signature: 'v2.pJobOYLaDTsauQo8UZa-4Eu4JKYYRuaeyPS8IHpNN-E', - }) - .reply(200, { - message: 'Success', - data: { - token: 'token', - }, - }); + it('fail on resources without any resource permissions', async () => { + await assertRejects( + { ttl: 1440, resources: { channels: {}, groups: {}, uuids: {} } }, + 'Missing values for either Resources or Patterns', + ); + }); + + it('fail on resources without any pattern permissions', async () => { + await assertRejects( + { ttl: 1440, patterns: { channels: {}, groups: {}, uuids: {} } }, + 'Missing values for either Resources or Patterns', + ); + }); - pubnub - .grantToken({ + it('fail on empty `users` and `dataSync` scopes', async () => { + await assertRejects( + { ttl: 1440, resources: { users: {}, dataSync: {} } }, + 'Missing values for either Resources or Patterns', + ); + }); + + it('should reject mixing `users` with `uuids`', async () => { + await assertRejects( + { ttl: 1440, resources: { - channels: {}, - groups: {}, - uuids: {}, - }, - }) - .catch((err) => { - try { - assert.equal(scope.isDone(), false); - assert.equal(err.status.message, 'Missing values for either Resources or Patterns'); - done(); - } catch (error) { - done(error); - } - }); - }); - - it('fail on resources without any pattern permissions', (done) => { - const scope = utils - .createNock() - .post('/v3/pam/mySubscribeKey/grant') - .query({ - uuid: 'myUUID', - pnsdk: `PubNub-JS-Nodejs/${pubnub.getVersion()}`, - timestamp: 1571360790, - signature: 'v2.pJobOYLaDTsauQo8UZa-4Eu4JKYYRuaeyPS8IHpNN-E', - }) - .reply(200, { - message: 'Success', - data: { - token: 'token', + users: { 'user-alice-042': { get: true } }, + // Mixing the two synonyms is also a compile-time error; see the `users` / `uuids` + // union in `GrantScopes`. + uuids: { 'appctx-uuid': { get: true } }, }, - }); + }, + 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`', + ); + }); + + it('should reject mixing `users` in resources with `uuids` in patterns', async () => { + // Split across sections the type system can't see the conflict, so this is the case the + // runtime check exists for. + await assertRejects( + { + ttl: 1440, + resources: { users: { 'user-alice-042': { get: true } } }, + patterns: { uuids: { 'appctx-.*': { get: true } } }, + }, + 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`', + ); + }); - pubnub - .grantToken({ + it('should reject mixing `spaces` with `channels`', async () => { + await assertRejects( + { ttl: 1440, - patterns: { - channels: {}, - groups: {}, - uuids: {}, + resources: { + spaces: { space1: { read: true } }, + channels: { 'channel-engineering-001': { read: true } }, }, - }) - .catch((err) => { - try { - assert.equal(scope.isDone(), false); - assert.equal(err.status.message, 'Missing values for either Resources or Patterns'); - done(); - } catch (error) { - done(error); - } - }); - }); - - it('should throw when mixing legacy and VSP terms', async () => { - try { - await pubnub.grantToken({ + }, + 'Cannot mix `spaces` with `channels` — `spaces` is deprecated terminology; use `channels`', + ); + }); + + it('should reject mixing `authorizedUserId` with `authorized_uuid`', async () => { + await assertRejects( + { ttl: 1440, + authorizedUserId: 'user-alice-042', + authorized_uuid: 'user-alice-042', + resources: { users: { 'user-alice-042': { get: true } } }, + }, + 'Cannot mix `authorizedUserId` with `authorized_uuid` — use `authorizedUserId`', + ); + }); + + it('should accept a grant which carries only DataSync projections', async () => { + const { scope, body } = mockGrant(); + + const token = await pubnub.grantToken({ + ttl: 1440, + dataSyncProjections: { + resources: { entities: { 'user.A': 'proj1' } }, + }, + }); + + assert.strictEqual(token, 'token'); + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.meta, { + 'pn-projections': { res: { 'datasync:entities:user.A': 'proj1' } }, + }); + }); + }); + + describe('##App Context (legacy) permissions', () => { + it('should serialize channels, groups and uuids with `authorized_uuid`', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + authorized_uuid: 'appctx-uuid', + resources: { + channels: { 'channel-engineering-001': { read: true } }, + groups: { 'group-eng': { read: true, manage: true } }, + uuids: { 'appctx-uuid': { get: true, update: true, delete: true } }, + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body(), { + ttl: 1440, + permissions: { + uuid: 'appctx-uuid', resources: { - // @ts-expect-error It is not allowed to mix in VSP and new permissions type. - users: { user1: { read: true } }, + ...EMPTY_SCOPES, + channels: { 'channel-engineering-001': READ }, + groups: { 'group-eng': READ + MANAGE }, + uuids: { 'appctx-uuid': GET + UPDATE + DELETE }, + }, + patterns: { ...EMPTY_SCOPES }, + meta: {}, + }, + }); + }); + + it('should map deprecated `spaces` onto the `channels` wire scope', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { spaces: { space1: { read: true, write: true } } }, + patterns: { spaces: { 'space.*': { manage: true } } }, + // `spaces` is legacy VSP terminology which isn't part of `GrantTokenParameters`. + } as unknown as Parameters[0]); + + assert.strictEqual(scope.isDone(), true); + // `spaces` collapses onto `channels`, and the `spaces` wire map stays empty. + assert.deepEqual(body().permissions.resources.channels, { space1: READ + WRITE }); + assert.deepEqual(body().permissions.resources.spaces, {}); + assert.deepEqual(body().permissions.patterns.channels, { 'space.*': MANAGE }); + assert.deepEqual(body().permissions.patterns.spaces, {}); + }); + + it('should keep classic channel permissions unchanged', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { + channels: { + 'channel-engineering-001': { + read: true, + write: true, + manage: true, + delete: true, + get: true, + update: true, + join: true, + }, + }, + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.strictEqual( + body().permissions.resources.channels['channel-engineering-001'], + READ + WRITE + MANAGE + DELETE + GET + UPDATE + JOIN, + ); + }); + }); + + describe('##DataSync permissions', () => { + it('should serialize `users` into its own wire scope, not `uuids`', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { users: { user1: { get: true } } }, + patterns: { users: { '.*': { get: true } } }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body(), { + ttl: 1440, + permissions: { + resources: { ...EMPTY_SCOPES, users: { user1: GET } }, + patterns: { ...EMPTY_SCOPES, users: { '.*': GET } }, + meta: {}, + }, + }); + }); + + it('should serialize the full `users` CRUD set', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { + users: { 'user-alice-042': { create: true, get: true, update: true, delete: true } }, + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.strictEqual(body().permissions.resources.users['user-alice-042'], CREATE + GET + UPDATE + DELETE); + }); + + it('should use `authorizedUserId` as the token principal', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + authorizedUserId: 'user-alice-042', + resources: { users: { 'user-alice-042': { get: true } } }, + // `authorizedUserId` belongs to the Objects grant parameters. + } as unknown as Parameters[0]); + + assert.strictEqual(scope.isDone(), true); + assert.strictEqual(body().permissions.uuid, 'user-alice-042'); + }); + + it('should serialize dataSync entities, relationships and memberships', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { + dataSync: { + entities: { 'school-greenwood-001': { get: true } }, + relationships: { 'student-alice-042:school-greenwood-001': { get: true } }, + memberships: { 'user-alice-042:channel-engineering-001': { get: true, update: true } }, }, - patterns: { - channels: { '.*': { read: true } }, + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.resources, { + ...EMPTY_SCOPES, + 'datasync:entities': { 'school-greenwood-001': GET }, + 'datasync:relationships': { 'student-alice-042:school-greenwood-001': GET }, + 'datasync:memberships': { 'user-alice-042:channel-engineering-001': GET + UPDATE }, + }); + // Unused DataSync scopes are omitted from the other section entirely. + assert.deepEqual(body().permissions.patterns, { ...EMPTY_SCOPES }); + }); + + it('should serialize dataSync patterns', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + patterns: { + dataSync: { + entities: { 'human-*': { create: true, get: true, update: true, delete: true } }, }, - }); - } catch (e) { - assert(e instanceof PubNubError); - assert.strictEqual( - e.status!.message, - // eslint-disable-next-line max-len - 'Cannot mix `users`, `spaces` and `authorizedUserId` with `uuids`, `channels`, `groups` and `authorized_uuid`', - ); - } - }); - - it('should correctly translate VSP terms into legacy terms', async () => { - const scope = utils - .createNock() - .post( - '/v3/pam/mySubscribeKey/grant', - // eslint-disable-next-line max-len - '{"ttl":1440,"permissions":{"resources":{"channels":{},"groups":{},"uuids":{"user1":1},"users":{},"spaces":{}},"patterns":{"channels":{},"groups":{},"uuids":{".*":1},"users":{},"spaces":{}},"meta":{}}}', - ) - .query({ - uuid: 'myUUID', - pnsdk: `PubNub-JS-Nodejs/${pubnub.getVersion()}`, - timestamp: 1571360790, - signature: 'v2.A1ldFjcfAiD0rw7-kFKKwY5j0Mpq1R5u8JDeej7P3jo', - }) - .reply(200, { - message: 'Success', - data: { - token: 'token', + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.patterns, { + ...EMPTY_SCOPES, + 'datasync:entities': { 'human-*': CREATE + GET + UPDATE + DELETE }, + }); + assert.deepEqual(body().permissions.resources, { ...EMPTY_SCOPES }); + }); + + it('should encode `dataSyncProjections` into meta and preserve user meta', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + meta: { tenant: 'acme', revision: 7 }, + resources: { channels: { 'channel-engineering-001': { read: true } } }, + dataSyncProjections: { + resources: { entities: { 'user.A': 'proj1' } }, + patterns: { memberships: { 'user.*': '__default__' } }, + }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.meta, { + tenant: 'acme', + revision: 7, + 'pn-projections': { + res: { 'datasync:entities:user.A': 'proj1' }, + pat: { 'datasync:memberships:user.*': '__default__' }, + }, + }); + }); + + it('should omit `pn-projections` when no projections are set', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { channels: { 'channel-engineering-001': { read: true } } }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.meta, {}); + }); + }); + + describe('##combined legacy and DataSync permissions', () => { + it('should grant `users`, `channels`, `groups` and `dataSync` in a single token', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + authorizedUserId: 'user-alice-042', + resources: { + users: { 'user-alice-042': { create: true, get: true, update: true, delete: true } }, + channels: { 'channel-engineering-001': { create: true, get: true, update: true, delete: true } }, + groups: { 'group-eng': { read: true, manage: true } }, + dataSync: { + entities: { 'school-greenwood-001': { get: true } }, + relationships: { 'student-alice-042:school-greenwood-001': { get: true } }, + memberships: { 'user-alice-042:channel-engineering-001': { get: true, update: true } }, }, - }); + }, + } as unknown as Parameters[0]); - try { - await pubnub.grantToken({ - ttl: 1440, + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body(), { + ttl: 1440, + permissions: { + uuid: 'user-alice-042', resources: { - // @ts-expect-error Intentianally using VSP types. - users: { user1: { read: true } }, + ...EMPTY_SCOPES, + users: { 'user-alice-042': CREATE + GET + UPDATE + DELETE }, + channels: { 'channel-engineering-001': CREATE + GET + UPDATE + DELETE }, + groups: { 'group-eng': READ + MANAGE }, + 'datasync:entities': { 'school-greenwood-001': GET }, + 'datasync:relationships': { 'student-alice-042:school-greenwood-001': GET }, + 'datasync:memberships': { 'user-alice-042:channel-engineering-001': GET + UPDATE }, }, - patterns: { - // @ts-expect-error Intentianally using VSP types. - users: { '.*': { read: true } }, - }, - }); - } catch (e) { - assert(e instanceof PubNubError); - console.log(e.status); - } + patterns: { ...EMPTY_SCOPES }, + meta: {}, + }, + }); + }); + + it('should allow `users` in resources alongside `channels` in patterns', async () => { + // This combination used to be rejected by the removed VSP / legacy either-or gate. + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + resources: { users: { user1: { get: true } } }, + patterns: { channels: { '.*': { read: true } } }, + }); + + assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.resources.users, { user1: GET }); + assert.deepEqual(body().permissions.patterns.channels, { '.*': READ }); + }); + + it('should allow legacy `uuids` alongside `channels`, `groups` and `dataSync`', async () => { + const { scope, body } = mockGrant(); + + await pubnub.grantToken({ + ttl: 1440, + authorized_uuid: 'appctx-uuid', + resources: { + uuids: { 'appctx-uuid': { get: true, update: true } }, + channels: { 'channel-engineering-001': { read: true } }, + groups: { 'group-eng': { read: true } }, + dataSync: { entities: { 'school-greenwood-001': { get: true } } }, + }, + }); assert.strictEqual(scope.isDone(), true); + assert.deepEqual(body().permissions.resources.uuids, { 'appctx-uuid': GET + UPDATE }); + assert.deepEqual(body().permissions.resources.users, {}); + assert.deepEqual(body().permissions.resources['datasync:entities'], { + 'school-greenwood-001': GET, + }); }); }); }); diff --git a/test/unit/access_manager/access_manager_grant_token.test.ts b/test/unit/access_manager/access_manager_grant_token.test.ts index cd2976c97..03f00fb92 100644 --- a/test/unit/access_manager/access_manager_grant_token.test.ts +++ b/test/unit/access_manager/access_manager_grant_token.test.ts @@ -131,72 +131,122 @@ describe('GrantTokenRequest', () => { }); }); - describe('VSP legacy permissions validation', () => { - it('should validate VSP authorizedUserId without new permission fields', () => { - const vspRequest = new GrantTokenRequest({ + describe('terminology synonym validation', () => { + it('should validate `users` with `authorizedUserId`', () => { + const request = new GrantTokenRequest({ keySet: defaultKeySet, ttl: 60, authorizedUserId: 'user123', resources: { users: { - user1: { - get: true, // VSP legacy - using valid UuidTokenPermissions property - }, + user1: { get: true }, }, }, - } as any); // Type assertion for VSP legacy - assert.equal(vspRequest.validate(), undefined); + }); + assert.equal(request.validate(), undefined); }); - it('should reject mixing VSP and new permissions in resources', () => { + it('should reject mixing `users` with `uuids` (same wire scope)', () => { const mixedRequest = new GrantTokenRequest({ keySet: defaultKeySet, ttl: 60, - authorizedUserId: 'user123', resources: { users: { - user1: { - get: true, - }, + 'user-alice-042': { get: true }, }, - channels: { - channel1: { - read: true, - }, + uuids: { + 'appctx-uuid': { get: true }, }, }, - } as any); // Type assertion for VSP legacy + }); assert.equal( mixedRequest.validate(), - "Cannot mix `users`, `spaces` and `authorizedUserId` with `uuids`, `channels`, `groups` and `authorized_uuid`" + 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`' ); }); - it('should reject mixing VSP and new permissions in patterns', () => { + it('should reject mixing `users` with `uuids` across resources and patterns', () => { const mixedRequest = new GrantTokenRequest({ keySet: defaultKeySet, ttl: 60, - authorizedUserId: 'user123', resources: { users: { - user1: { - get: true, - }, + 'user-alice-042': { get: true }, }, }, patterns: { + uuids: { + 'appctx-*': { get: true }, + }, + }, + }); + assert.equal( + mixedRequest.validate(), + 'Cannot mix `users` with `uuids` — `uuids` is deprecated App Context terminology; use `users`' + ); + }); + + it('should reject mixing `spaces` with `channels` (same wire scope)', () => { + const mixedRequest = new GrantTokenRequest({ + keySet: defaultKeySet, + ttl: 60, + resources: { + spaces: { + space1: { read: true }, + }, channels: { - '.*': { - read: true, - }, + channel1: { read: true }, }, }, - } as any); // Type assertion for VSP legacy + } as any); // Type assertion for legacy `spaces` assert.equal( mixedRequest.validate(), - "Cannot mix `users`, `spaces` and `authorizedUserId` with `uuids`, `channels`, `groups` and `authorized_uuid`" + 'Cannot mix `spaces` with `channels` — `spaces` is deprecated terminology; use `channels`' ); }); + + it('should reject mixing `authorizedUserId` with `authorized_uuid`', () => { + const mixedRequest = new GrantTokenRequest({ + keySet: defaultKeySet, + ttl: 60, + authorizedUserId: 'user-alice-042', + authorized_uuid: 'user-alice-042', + resources: { + users: { + 'user-alice-042': { get: true }, + }, + }, + }); + assert.equal( + mixedRequest.validate(), + 'Cannot mix `authorizedUserId` with `authorized_uuid` — use `authorizedUserId`' + ); + }); + + it('should allow combining DataSync `users`, `channels`, `groups`, and `dataSync`', () => { + const combinedRequest = new GrantTokenRequest({ + keySet: defaultKeySet, + ttl: 60, + authorizedUserId: 'user-alice-042', + resources: { + users: { + 'user-alice-042': { create: true, get: true, update: true, delete: true }, + }, + channels: { + 'channel-engineering-001': { get: true, update: true }, + }, + groups: { + 'group-eng': { read: true }, + }, + dataSync: { + memberships: { + 'user-alice-042:channel-engineering-001': { get: true }, + }, + }, + }, + }); + assert.equal(combinedRequest.validate(), undefined); + }); }); describe('operation', () => { @@ -622,23 +672,25 @@ describe('GrantTokenRequest', () => { }); describe('VSP legacy permissions handling', () => { - it('should handle VSP users as uuids', () => { + it('should handle VSP users as its own users scope', () => { const request = new GrantTokenRequest({ keySet: defaultKeySet, ttl: 60, resources: { users: { - user1: { get: true }, // VSP legacy - mapped to uuids + user1: { get: true }, user2: { get: true, update: true }, }, }, } as any); // Type assertion for VSP legacy - + const transportRequest = request.request(); const body = parseBodyAsString(transportRequest.body!); - - assert.equal(body.permissions.resources.uuids.user1, 32); // get - assert.equal(body.permissions.resources.uuids.user2, 96); // 32 + 64 + + // `users` is its own wire scope, distinct from the legacy App Context `uuids` scope. + assert.equal(body.permissions.resources.users.user1, 32); // get + assert.equal(body.permissions.resources.users.user2, 96); // 32 + 64 + assert.deepEqual(body.permissions.resources.uuids, {}); }); it('should handle VSP spaces as channels', () => { @@ -677,11 +729,75 @@ describe('GrantTokenRequest', () => { const transportRequest = request.request(); const body = parseBodyAsString(transportRequest.body!); - assert.equal(body.permissions.patterns.uuids['user.*'], 32); + // `users` keeps its own wire scope; `spaces` still collapses onto `channels`. + assert.equal(body.permissions.patterns.users['user.*'], 32); + assert.deepEqual(body.permissions.patterns.uuids, {}); assert.equal(body.permissions.patterns.channels['space.*'], 3); // 1 + 2 }); }); + describe('DataSync combined permissions handling', () => { + it('should serialize `users` into the users wire scope alongside channels', () => { + const request = new GrantTokenRequest({ + keySet: defaultKeySet, + ttl: 60, + authorizedUserId: 'user-alice-042', + resources: { + users: { + 'user-alice-042': { create: true, get: true, update: true, delete: true }, + }, + channels: { + 'channel-engineering-001': { get: true, update: true }, + }, + }, + }); + + const transportRequest = request.request(); + const body = parseBodyAsString(transportRequest.body!); + + // Principal resolved from authorizedUserId. + assert.equal(body.permissions.uuid, 'user-alice-042'); + // `users` maps to its own wire scope with full CRUD: 16 + 32 + 64 + 8 = 120. + assert.equal(body.permissions.resources.users['user-alice-042'], 120); + // The legacy `uuids` scope stays empty — `users` does not collapse onto it. + assert.deepEqual(body.permissions.resources.uuids, {}); + // `channels` are preserved in the same grant: 32 + 64 = 96. + assert.equal(body.permissions.resources.channels['channel-engineering-001'], 96); + }); + + it('should serialize legacy `uuids` into the uuid wire scope when used alone', () => { + const request = new GrantTokenRequest({ + keySet: defaultKeySet, + ttl: 60, + resources: { + uuids: { + 'appctx-uuid': { get: true }, // 32 + }, + }, + }); + + const transportRequest = request.request(); + const body = parseBodyAsString(transportRequest.body!); + + assert.equal(body.permissions.resources.uuids['appctx-uuid'], 32); + }); + + it('should calculate create permission bit (16) for channels', () => { + const request = new GrantTokenRequest({ + ...defaultParameters, + resources: { + channels: { + 'channel-engineering-001': { create: true }, + }, + }, + }); + + const transportRequest = request.request(); + const body = parseBodyAsString(transportRequest.body!); + assert.equal(body.permissions.resources.channels['channel-engineering-001'], 16); + }); + }); + describe('response parsing', () => { it('should parse successful grant token response', async () => { const request = new GrantTokenRequest(defaultParameters); From aa34aeb2a705e951ea9447f46f5448bd8fe98a0f Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Tue, 18 Aug 2026 09:43:32 +0530 Subject: [PATCH 26/27] re-worked update methods added JSDoc for json pointer usage --- .../endpoints/data_sync/channel/update.ts | 7 +- src/core/endpoints/data_sync/entity/update.ts | 7 +- .../endpoints/data_sync/membership/update.ts | 7 +- .../data_sync/relationship/update.ts | 9 +- src/core/endpoints/data_sync/user/update.ts | 7 +- src/core/pubnub-data-sync.ts | 93 +++- src/core/types/api/data-sync.ts | 493 ++++++++++++------ 7 files changed, 432 insertions(+), 191 deletions(-) diff --git a/src/core/endpoints/data_sync/channel/update.ts b/src/core/endpoints/data_sync/channel/update.ts index 4fef6af38..b2e55386e 100644 --- a/src/core/endpoints/data_sync/channel/update.ts +++ b/src/core/endpoints/data_sync/channel/update.ts @@ -2,9 +2,9 @@ * Update Channel REST API module. * * Partial update via JSON Patch (RFC 6902). - * 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. + * Accepts `add`/`replace`/`test` (JSON Pointer key-value pairs), `remove` + * (JSON Pointer paths), and `move`/`copy` (JSON Pointer from → path pairs), + * converting them to JSON Patch operations. Paths are sent verbatim. * * @internal */ @@ -95,7 +95,6 @@ export class UpdateChannelRequest 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 279e75d98..36c629523 100644 --- a/src/core/endpoints/data_sync/entity/update.ts +++ b/src/core/endpoints/data_sync/entity/update.ts @@ -2,9 +2,9 @@ * Update Entity REST API module. * * Partial update via JSON Patch (RFC 6902). - * 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. + * Accepts `add`/`replace`/`test` (JSON Pointer key-value pairs), `remove` + * (JSON Pointer paths), and `move`/`copy` (JSON Pointer from/path pairs), and + * converts them to JSON Patch operations. Paths are sent verbatim. * * @internal */ @@ -95,7 +95,6 @@ export class UpdateEntityRequest protected get body(): ArrayBuffer | string | undefined { const { add, replace, remove, move, copy, test } = this.parameters; - // 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 18c7ae86e..5c50cd626 100644 --- a/src/core/endpoints/data_sync/membership/update.ts +++ b/src/core/endpoints/data_sync/membership/update.ts @@ -2,9 +2,9 @@ * Update Membership REST API module. * * Partial update via JSON Patch (RFC 6902). - * 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. + * Accepts `add`/`replace`/`test` (JSON Pointer key-value pairs), `remove` + * (JSON Pointer paths), and `move`/`copy` (JSON Pointer `{ from, path }` pairs) + * and converts them to JSON Patch operations. Paths are sent verbatim. * * @internal */ @@ -95,7 +95,6 @@ export class UpdateMembershipRequest 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 4b4a9dc38..7abcc698b 100644 --- a/src/core/endpoints/data_sync/relationship/update.ts +++ b/src/core/endpoints/data_sync/relationship/update.ts @@ -2,10 +2,10 @@ * Update Relationship REST API module. * * Partial update via JSON Patch (RFC 6902). - * 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. + * Accepts `add` and `replace` (JSON Pointer key-value pairs), `remove` + * (JSON Pointer paths), `move` and `copy` (`{ from, path }` JSON Pointer pairs), + * and `test` (JSON Pointer key-value pairs) and converts them to JSON Patch + * operations. Paths are sent verbatim. * * @internal */ @@ -96,7 +96,6 @@ export class UpdateRelationshipRequest 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 90cac7e57..2cf54f59c 100644 --- a/src/core/endpoints/data_sync/user/update.ts +++ b/src/core/endpoints/data_sync/user/update.ts @@ -2,9 +2,9 @@ * Update User REST API module. * * Partial update via JSON Patch (RFC 6902). - * 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. + * Accepts `add`/`replace`/`test` (JSON Pointer key-value pairs), `remove` + * (JSON Pointer paths), and `move`/`copy` (JSON Pointer `{ from, path }` pairs) + * and converts them to JSON Patch operations. Paths are sent verbatim. * * @internal */ @@ -95,7 +95,6 @@ export class UpdateUserRequest ext protected get body(): ArrayBuffer | string | undefined { const { add, replace, remove, move, copy, test } = this.parameters; - // 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/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index 7e9eaa60c..eb78b0900 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -102,6 +102,10 @@ export default class PubNubDataSync { /** * Create a new Entity. * + * To change a field later with `updateEntity`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ @@ -113,6 +117,10 @@ export default class PubNubDataSync { /** * Create a new Entity. * + * To change a field later with `updateEntity`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * * @returns Asynchronous create entity response. @@ -122,6 +130,10 @@ export default class PubNubDataSync { /** * Create a new Entity. * + * To change a field later with `updateEntity`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * @@ -290,7 +302,7 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -303,7 +315,7 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @@ -314,7 +326,7 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -397,6 +409,11 @@ export default class PubNubDataSync { /** * Create a new Relationship. * + * To change a field later with `updateRelationship`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `class`, `entityAId`, and `entityBId` are immutable and + * cannot be patched. + * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ @@ -408,6 +425,11 @@ export default class PubNubDataSync { /** * Create a new Relationship. * + * To change a field later with `updateRelationship`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `class`, `entityAId`, and `entityBId` are immutable and + * cannot be patched. + * * @param parameters - Request configuration parameters. * * @returns Asynchronous create relationship response. @@ -419,6 +441,11 @@ export default class PubNubDataSync { /** * Create a new Relationship. * + * To change a field later with `updateRelationship`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `class`, `entityAId`, and `entityBId` are immutable and + * cannot be patched. + * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * @@ -593,7 +620,7 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -606,7 +633,7 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @@ -619,7 +646,7 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -704,6 +731,10 @@ export default class PubNubDataSync { /** * Create a new User. * + * To change a field later with `updateUser`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ @@ -715,6 +746,10 @@ export default class PubNubDataSync { /** * Create a new User. * + * To change a field later with `updateUser`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * * @returns Asynchronous create user response. @@ -724,6 +759,10 @@ export default class PubNubDataSync { /** * Create a new User. * + * To change a field later with `updateUser`, address it by its JSON Pointer: `classVersion` is + * patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * @@ -894,7 +933,7 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -907,7 +946,7 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @@ -918,7 +957,7 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -1001,6 +1040,10 @@ export default class PubNubDataSync { /** * Create a new Channel. * + * To change a field later with `updateChannel`, address it by its JSON Pointer: `classVersion` + * is patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ @@ -1012,6 +1055,10 @@ export default class PubNubDataSync { /** * Create a new Channel. * + * To change a field later with `updateChannel`, address it by its JSON Pointer: `classVersion` + * is patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * * @returns Asynchronous create channel response. @@ -1021,6 +1068,10 @@ export default class PubNubDataSync { /** * Create a new Channel. * + * To change a field later with `updateChannel`, address it by its JSON Pointer: `classVersion` + * is patched as `/entityClassVersion`, `status` as `/status`, and payload fields as + * `/payload/`. `class` and `classLevel` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * @@ -1200,7 +1251,7 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -1213,7 +1264,7 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @@ -1224,7 +1275,7 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -1307,6 +1358,10 @@ export default class PubNubDataSync { /** * Create a new Membership (associates a User with a Channel). * + * To change a field later with `updateMembership`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `userId` and `channelId` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. */ @@ -1318,6 +1373,10 @@ export default class PubNubDataSync { /** * Create a new Membership (associates a User with a Channel). * + * To change a field later with `updateMembership`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `userId` and `channelId` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * * @returns Asynchronous create membership response. @@ -1329,6 +1388,10 @@ export default class PubNubDataSync { /** * Create a new Membership (associates a User with a Channel). * + * To change a field later with `updateMembership`, address it by its JSON Pointer: + * `classVersion` is patched as `/relationshipClassVersion`, `status` as `/status`, and payload + * fields as `/payload/`. `userId` and `channelId` are immutable and cannot be patched. + * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. * @@ -1508,7 +1571,7 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -1521,7 +1584,7 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @@ -1534,7 +1597,7 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 0f6f054ac..83d6572dc 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -170,9 +170,9 @@ type DataSyncPagedResponse = { /** * JSON Patch operation as defined by RFC 6902. * - * Internal request 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 request format. Developers use `add`/`replace`/`remove`/`move`/`copy`/`test` keyed by + * JSON Pointer instead. `from` is the source location for `move`/`copy`; `value` carries the + * operand for `add`/`replace`/`test`. * * @internal */ @@ -184,29 +184,29 @@ export type JsonPatchOperation = { }; /** - * A source → destination path pair (dot notation) for JSON Patch `move` and `copy` operations. + * A source → destination path pair (JSON Pointer) for JSON Patch `move` and `copy` operations. */ export type PatchMovePath = { - /** Dot-notation source path (RFC 6902 `from`). */ + /** JSON Pointer source path, used verbatim (RFC 6902 `from`). */ from: string; - /** Dot-notation destination path (RFC 6902 `path`). */ + /** JSON Pointer destination path, used verbatim (RFC 6902 `path`). */ path: string; }; /** - * User-friendly JSON Patch input (dot notation), converted to RFC 6902 operations before sending. + * JSON Patch input keyed by JSON Pointer, converted to RFC 6902 operations before sending. * * @internal */ export type JsonPatchInput = { - /** Fields to add (dot path → value). */ + /** Fields to add (JSON Pointer → value). */ add?: Record; - /** Fields to replace (dot path → value). */ + /** Fields to replace (JSON Pointer → value). */ replace?: Record; - /** Dot-notation paths to remove. */ + /** JSON Pointer paths to remove. */ remove?: string[]; /** Source → destination path pairs to move. */ @@ -215,24 +215,18 @@ export type JsonPatchInput = { /** Source → destination path pairs to copy. */ copy?: PatchMovePath[]; - /** Fields to test (dot path → expected value). */ + /** Fields to test (JSON Pointer → expected value). */ test?: Record; }; /** - * Convert dot-notation path to JSON Pointer (RFC 6901). + * Convert user-friendly patch input to JSON Patch operations (request format). * - * "config.ttlSec" → "/config/ttlSec" - * "filterableFields.0.name" → "/filterableFields/0/name" - * - * @internal - */ -export function toJsonPointer(dotPath: string): string { - return '/' + dotPath.split('.').join('/'); -} - -/** - * Convert user-friendly dot-notation patch input to JSON Patch operations (request format). + * Paths are passed through **verbatim**: the SDK does not translate `.` to `/`, nor prefix a + * leading `/`. Callers provide the exact RFC 6901 JSON Pointer they want on the wire (e.g. + * `/payload/creditScore`). This keeps field names that themselves contain `.` addressable — + * a path such as `/payload/user.name` targets the literal key `user.name`, which dot-notation + * translation would have split into two segments. * * - Each key in `add` becomes an "add" operation. * - Each key in `replace` becomes a "replace" operation. @@ -248,38 +242,38 @@ export function toJsonPatchOperations(input: JsonPatchInput): JsonPatchOperation const ops: JsonPatchOperation[] = []; if (add) { - for (const [dotPath, value] of Object.entries(add)) { - ops.push({ op: 'add', path: toJsonPointer(dotPath), value }); + for (const [path, value] of Object.entries(add)) { + ops.push({ op: 'add', path, value }); } } if (replace) { - for (const [dotPath, value] of Object.entries(replace)) { - ops.push({ op: 'replace', path: toJsonPointer(dotPath), value }); + for (const [path, value] of Object.entries(replace)) { + ops.push({ op: 'replace', path, value }); } } if (remove) { - for (const dotPath of remove) { - ops.push({ op: 'remove', path: toJsonPointer(dotPath) }); + for (const path of remove) { + ops.push({ op: 'remove', path }); } } if (move) { for (const { from, path } of move) { - ops.push({ op: 'move', from: toJsonPointer(from), path: toJsonPointer(path) }); + ops.push({ op: 'move', from, path }); } } if (copy) { for (const { from, path } of copy) { - ops.push({ op: 'copy', from: toJsonPointer(from), path: toJsonPointer(path) }); + ops.push({ op: 'copy', from, path }); } } if (test) { - for (const [dotPath, value] of Object.entries(test)) { - ops.push({ op: 'test', path: toJsonPointer(dotPath), value }); + for (const [path, value] of Object.entries(test)) { + ops.push({ op: 'test', path, value }); } } @@ -296,20 +290,62 @@ export function toJsonPatchOperations(input: JsonPatchInput): JsonPatchOperation * 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`. + * + * Each field below documents the JSON Pointer to use when changing it later with + * `updateEntity` ({@link UpdateEntityParameters}) — the create-time parameter name and the + * patch path are not always the same. */ export type CreateEntityData = { /** * Version of the entity class schema. * - * Stored on the entity as `entityClassVersion` — use that name to address it in - * {@link UpdateEntityParameters} patch paths. + * To change this later, patch `/entityClassVersion` — the stored property name, which is what + * responses and real-time events carry. It is *not* `/data/classVersion`. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createEntity({ class: 'Customer', data: { classVersion: 1 } }); + * // later: bump the version + * await pubnub.dataSync.updateEntity({ id, replace: { '/entityClassVersion': 2 } }); + * ``` */ classVersion: number; - /** Optional lifecycle status. */ + /** + * Optional lifecycle status. + * + * To change this later, patch `/status`. + * + * @example + * ```typescript + * await pubnub.dataSync.updateEntity({ id, replace: { '/status': 'inactive' } }); + * ``` + */ status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ + /** + * User-defined JSON payload conforming to the entity class schema. + * + * To change a payload field later, patch `/payload/`; nest deeper with more segments. + * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createEntity({ + * class: 'Customer', + * data: { classVersion: 1, payload: { creditScore: 720, address: { city: 'Pune' } } }, + * }); + * // later: one top-level field, one nested field, one field whose name contains a dot + * await pubnub.dataSync.updateEntity({ + * id, + * replace: { '/payload/creditScore': 810, '/payload/address/city': 'Mumbai' }, + * add: { '/payload/user.name': 'Alice' }, + * remove: ['/payload/address/line2'], + * }); + * ``` + */ payload?: Record; }; @@ -321,7 +357,11 @@ export type CreateEntityData = { * has no place in updates. */ export type SetEntityData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * With `updateEntity` (PATCH) the same value is addressed as `/entityClassVersion`. + */ classVersion: number; /** Optional lifecycle status. */ @@ -378,9 +418,8 @@ export type CreateEntityParameters = { /** * Entity class this entity belongs to. Set at creation time and immutable afterward. * - * Stored on the entity as `entityClass` — the name it carries in responses, in real-time event - * payloads, and in {@link UpdateEntityParameters} patch paths (immutable, so never a patch - * target). + * Stored on the entity as `entityClass` — the name it carries in responses and real-time event + * payloads. Immutable, so it cannot be patched: `updateEntity` rejects `/entityClass`. */ class: string; @@ -389,7 +428,7 @@ export type CreateEntityParameters = { * * Omit to let the service apply its default. * - * Stored on the entity as `entityClassLevel`. + * Stored on the entity as `entityClassLevel`. Immutable, so it cannot be patched. */ classLevel?: ClassLevel; @@ -457,13 +496,13 @@ export type SetEntityParameters = { /** * Update Entity request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to - * JSON Patch operations. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK + * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. * * Patch paths address the entity's **stored property names** — the same keys that come back in * responses and real-time events — not the grouped parameter names used by - * {@link CreateEntityParameters}. So the class version is `entityClassVersion` (not - * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * {@link CreateEntityParameters}. So the class version is `/entityClassVersion` (not + * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. @@ -473,45 +512,45 @@ export type UpdateEntityParameters = { id: string; /** - * Fields to add, using dot-notation keys. + * Fields to add, keyed by JSON Pointer. * - * Each key is a dot-delimited path to the target field. + * Each key is a JSON Pointer to the target field, used exactly as provided. * The SDK converts these to JSON Patch "add" operations. * * @example * ```typescript * add: { - * 'payload.tags.0': 'priority', - * 'payload.profile.displayName': 'Alice', + * '/payload/tags/0': 'priority', + * '/payload/profile/displayName': 'Alice', * } * ``` */ add?: Record; /** - * Fields to replace, using dot-notation keys. + * Fields to replace, keyed by JSON Pointer. * - * Each key is a dot-delimited path to the target field. + * Each key is a JSON Pointer to the target field, used exactly as provided. * The SDK converts these to JSON Patch "replace" operations. * * @example * ```typescript * replace: { - * 'status': 'active', - * 'payload.score': 300, + * '/status': 'active', + * '/payload/score': 300, * } * ``` */ replace?: Record; /** - * Array of dot-notation field paths to remove. + * Array of JSON Pointer field paths to remove. * * The SDK converts these to JSON Patch "remove" operations. * * @example * ```typescript - * remove: ['payload.tempFlag', 'payload.legacyField'] + * remove: ['/payload/tempFlag', '/payload/legacyField'] * ``` */ remove?: string[]; @@ -519,12 +558,12 @@ export type UpdateEntityParameters = { /** * 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). + * The value at each `from` is removed and re-added at `path`. Both are JSON Pointers used + * exactly as provided (prefix with `/payload` to target payload fields). * * @example * ```typescript - * move: [{ from: 'payload.legacyName', path: 'payload.displayName' }] + * move: [{ from: '/payload/legacyName', path: '/payload/displayName' }] * ``` */ move?: PatchMovePath[]; @@ -532,25 +571,25 @@ export type UpdateEntityParameters = { /** * 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). + * The value at each `from` is duplicated to `path`. Both are JSON Pointers used exactly as + * provided (prefix with `/payload` to target payload fields). * * @example * ```typescript - * copy: [{ from: 'payload.displayName', path: 'payload.previousName' }] + * copy: [{ from: '/payload/displayName', path: '/payload/previousName' }] * ``` */ copy?: PatchMovePath[]; /** - * Fields to test (dot-notation keys → expected value; RFC 6902 "test"). + * Fields to test (JSON Pointer 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). + * exactly as provided (prefix with `/payload` for payload fields). * * @example * ```typescript - * test: { 'status': 'active' } + * test: { '/status': 'active' } * ``` */ test?: Record; @@ -609,20 +648,53 @@ export type RemoveEntityResponse = { * 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`. + * + * Each field below documents the JSON Pointer to use when changing it later with + * `updateRelationship` ({@link UpdateRelationshipParameters}) — the create-time parameter name + * and the patch path are not always the same. */ export type CreateRelationshipData = { /** * Version of the relationship class schema. * - * Stored on the relationship as `relationshipClassVersion` — use that name to address it in - * {@link UpdateRelationshipParameters} patch paths. + * To change this later, patch `/relationshipClassVersion` — the stored property name, which is + * what responses and real-time events carry. It is *not* `/data/classVersion`. + * + * @example + * ```typescript + * await pubnub.dataSync.updateRelationship({ id, replace: { '/relationshipClassVersion': 2 } }); + * ``` */ classVersion: number; - /** Optional lifecycle status. */ + /** + * Optional lifecycle status. + * + * To change this later, patch `/status`. + */ status?: string; - /** User-defined JSON payload. */ + /** + * User-defined JSON payload. + * + * To change a payload field later, patch `/payload/`; nest deeper with more segments. + * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createRelationship({ + * class: 'RequestedBy', entityAId, entityBId, + * data: { classVersion: 1, payload: { label: 'primary', linkedAt: '2026-07-06T10:00:00.000Z' } }, + * }); + * // later + * await pubnub.dataSync.updateRelationship({ + * id, + * replace: { '/payload/label': 'secondary' }, + * move: [{ from: '/payload/linkedAt', path: '/payload/linkedOn' }], + * }); + * ``` + */ payload?: Record; }; @@ -634,7 +706,11 @@ export type CreateRelationshipData = { * and therefore has no place in updates. The server rejects a PUT that omits `classVersion`. */ export type SetRelationshipData = { - /** Version of the relationship class schema. */ + /** + * Version of the relationship class schema. + * + * With `updateRelationship` (PATCH) the same value is addressed as `/relationshipClassVersion`. + */ classVersion: number; /** Optional lifecycle status. */ @@ -697,16 +773,15 @@ export type CreateRelationshipParameters = { /** * Relationship class this relationship belongs to. Set at creation time and immutable afterward. * - * Stored on the relationship as `relationshipClass` — the name it carries in responses, in - * real-time event payloads, and in {@link UpdateRelationshipParameters} patch paths (immutable, - * so never a patch target). + * Stored on the relationship as `relationshipClass` — the name it carries in responses and + * real-time event payloads. Immutable, so it cannot be patched. */ class: string; - /** First entity ID in the relationship. */ + /** First entity ID in the relationship. Immutable after creation, so it cannot be patched. */ entityAId: string; - /** Second entity ID in the relationship. */ + /** Second entity ID in the relationship. Immutable after creation, so it cannot be patched. */ entityBId: string; /** Mutable, versioned relationship data (class version, status, and payload). */ @@ -772,13 +847,13 @@ export type SetRelationshipParameters = { /** * Update Relationship request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to - * JSON Patch operations. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK + * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. * * Patch paths address the relationship's **stored property names** — the same keys that come back in * responses and real-time events — not the grouped parameter names used by * {@link CreateRelationshipParameters}. So the class version is `relationshipClassVersion` (not - * `data.classVersion`), and payload fields keep their `payload.` prefix. `relationshipClass`, + * `/data/classVersion`), and payload fields keep their `/payload` prefix. `relationshipClass`, * `entityAId`, and `entityBId` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. @@ -788,65 +863,65 @@ export type UpdateRelationshipParameters = { id: string; /** - * Fields to add, using dot-notation keys. + * Fields to add, keyed by JSON Pointer. * - * 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. + * Each key is a JSON Pointer to the target field, used exactly as provided (prefix with + * `/payload` to target payload fields). The SDK converts these to JSON Patch "add" operations. * * @example * ```typescript * add: { - * 'payload.tags.0': 'mentor', + * '/payload/tags/0': 'mentor', * } * ``` */ add?: Record; /** - * Fields to replace, using dot-notation keys. + * Fields to replace, keyed by JSON Pointer. * - * 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. + * Each key is a JSON Pointer to the target field, used exactly as provided (prefix with + * `/payload` to target payload fields). The SDK converts these to JSON Patch "replace" operations. * * @example * ```typescript * replace: { - * 'payload.role': 'admin', - * 'payload.permissions.read': true, + * '/payload/role': 'admin', + * '/payload/permissions/read': true, * } * ``` */ replace?: Record; /** - * Array of dot-notation field paths to remove. + * Array of JSON Pointer field paths to remove. * * The SDK converts these to JSON Patch "remove" operations. * * @example * ```typescript - * remove: ['payload.tempFlag', 'payload.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 + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are JSON Pointers 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`. + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are JSON Pointers 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 + * Fields to test (JSON Pointer 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). + * `/payload` for payload fields). */ test?: Record; @@ -903,20 +978,52 @@ export type RemoveRelationshipResponse = { * * 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. + * + * Each field below documents the JSON Pointer to use when changing it later with `updateUser` + * ({@link UpdateUserParameters}) — the create-time parameter name and the patch path are not + * always the same. */ export type CreateUserData = { /** * Version of the entity class schema. * - * Stored on the user as `entityClassVersion` — use that name to address it in - * {@link UpdateUserParameters} patch paths. + * To change this later, patch `/entityClassVersion` — the stored property name, which is what + * responses and real-time events carry. It is *not* `/data/classVersion`. + * + * @example + * ```typescript + * await pubnub.dataSync.updateUser({ id, replace: { '/entityClassVersion': 2 } }); + * ``` */ classVersion: number; - /** Optional lifecycle status. */ + /** + * Optional lifecycle status. + * + * To change this later, patch `/status`. + */ status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ + /** + * User-defined JSON payload conforming to the entity class schema. + * + * To change a payload field later, patch `/payload/`; nest deeper with more segments. + * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createUser({ + * data: { classVersion: 1, payload: { email: 'alice@acme.test', isActive: true } }, + * }); + * // later + * await pubnub.dataSync.updateUser({ + * id, + * replace: { '/payload/email': 'alice.v@acme.test' }, + * remove: ['/payload/isActive'], + * }); + * ``` + */ payload?: Record; }; @@ -966,8 +1073,8 @@ export type CreateUserParameters = { * * Must be `User` or one of its subclasses. Omit to let the service apply the default (`User`). * - * Stored on the user as `entityClass` — the name it carries in responses, in real-time event - * payloads, and in {@link UpdateUserParameters} patch paths (immutable, so never a patch target). + * Stored on the user as `entityClass` — the name it carries in responses and real-time event + * payloads. Immutable, so it cannot be patched: `updateUser` rejects `/entityClass`. */ class?: string; @@ -976,7 +1083,7 @@ export type CreateUserParameters = { * * Omit to let the service apply its default. * - * Stored on the user as `entityClassLevel`. + * Stored on the user as `entityClassLevel`. Immutable, so it cannot be patched. */ classLevel?: ClassLevel; @@ -991,7 +1098,11 @@ export type CreateUserParameters = { * {@link SetUserParameters}. */ export type SetUserData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * With `updateUser` (PATCH) the same value is addressed as `/entityClassVersion`. + */ classVersion: number; /** Optional lifecycle status. */ @@ -1044,13 +1155,13 @@ export type SetUserParameters = { /** * Update User request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to - * JSON Patch operations. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK + * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. * * Patch paths address the user's **stored property names** — the same keys that come back in * responses and real-time events — not the grouped parameter names used by * {@link CreateUserParameters}. So the class version is `entityClassVersion` (not - * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. @@ -1060,40 +1171,40 @@ export type UpdateUserParameters = { id: string; /** - * Fields to add, using dot-notation keys. + * Fields to add, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "add" operations. */ add?: Record; /** - * Fields to replace, using dot-notation keys. + * Fields to replace, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "replace" operations. */ replace?: Record; /** - * Array of dot-notation field paths to remove. + * Array of JSON Pointer field paths to remove (used exactly as provided). * The SDK converts these to JSON Patch "remove" operations. */ 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 + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are JSON Pointers 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`. + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are JSON Pointers 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 + * Fields to test (JSON Pointer 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). + * `/payload` for payload fields). */ test?: Record; @@ -1148,20 +1259,52 @@ export type RemoveUserResponse = { * * 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. + * + * Each field below documents the JSON Pointer to use when changing it later with `updateChannel` + * ({@link UpdateChannelParameters}) — the create-time parameter name and the patch path are not + * always the same. */ export type CreateChannelData = { /** * Version of the entity class schema. * - * Stored on the channel as `entityClassVersion` — use that name to address it in - * {@link UpdateChannelParameters} patch paths. + * To change this later, patch `/entityClassVersion` — the stored property name, which is what + * responses and real-time events carry. It is *not* `/data/classVersion`. + * + * @example + * ```typescript + * await pubnub.dataSync.updateChannel({ id, replace: { '/entityClassVersion': 2 } }); + * ``` */ classVersion: number; - /** Optional lifecycle status. */ + /** + * Optional lifecycle status. + * + * To change this later, patch `/status`. + */ status?: string; - /** User-defined JSON payload conforming to the entity class schema. */ + /** + * User-defined JSON payload conforming to the entity class schema. + * + * To change a payload field later, patch `/payload/`; nest deeper with more segments. + * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createChannel({ + * data: { classVersion: 1, payload: { name: 'engineering', memberCount: 1 } }, + * }); + * // later + * await pubnub.dataSync.updateChannel({ + * id, + * replace: { '/payload/memberCount': 42 }, + * add: { '/payload/category': 'general' }, + * }); + * ``` + */ payload?: Record; }; @@ -1172,7 +1315,11 @@ export type CreateChannelData = { * {@link SetChannelParameters}. */ export type SetChannelData = { - /** Version of the entity class schema. */ + /** + * Version of the entity class schema. + * + * With `updateChannel` (PATCH) the same value is addressed as `/entityClassVersion`. + */ classVersion: number; /** Optional lifecycle status. */ @@ -1229,9 +1376,8 @@ export type CreateChannelParameters = { * Must be `Channel` or one of its subclasses. Omit to let the service apply the default * (`Channel`). * - * Stored on the channel as `entityClass` — the name it carries in responses, in real-time event - * payloads, and in {@link UpdateChannelParameters} patch paths (immutable, so never a patch - * target). + * Stored on the channel as `entityClass` — the name it carries in responses and real-time event + * payloads. Immutable, so it cannot be patched: `updateChannel` rejects `/entityClass`. */ class?: string; @@ -1241,7 +1387,7 @@ export type CreateChannelParameters = { * * Omit to let the service apply its default. * - * Stored on the channel as `entityClassLevel`. + * Stored on the channel as `entityClassLevel`. Immutable, so it cannot be patched. */ classLevel?: ClassLevel; @@ -1291,13 +1437,13 @@ export type SetChannelParameters = { /** * Update Channel request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to - * JSON Patch operations. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK + * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. * * Patch paths address the channel's **stored property names** — the same keys that come back in * responses and real-time events — not the grouped parameter names used by * {@link CreateChannelParameters}. So the class version is `entityClassVersion` (not - * `data.classVersion`), and payload fields keep their `payload.` prefix. `entityClass` and + * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and * `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. @@ -1307,40 +1453,40 @@ export type UpdateChannelParameters = { id: string; /** - * Fields to add, using dot-notation keys. + * Fields to add, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "add" operations. */ add?: Record; /** - * Fields to replace, using dot-notation keys. + * Fields to replace, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "replace" operations. */ replace?: Record; /** - * Array of dot-notation field paths to remove. + * Array of JSON Pointer field paths to remove (used exactly as provided). * The SDK converts these to JSON Patch "remove" operations. */ 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 + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are JSON Pointers 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`. + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are JSON Pointers 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 + * Fields to test (JSON Pointer 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). + * `/payload` for payload fields). */ test?: Record; @@ -1396,20 +1542,53 @@ export type RemoveChannelResponse = { * 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`. + * + * Each field below documents the JSON Pointer to use when changing it later with + * `updateMembership` ({@link UpdateMembershipParameters}) — the create-time parameter name and + * the patch path are not always the same. */ export type CreateMembershipData = { /** * Version of the Membership relationship class. * - * Stored on the membership as `relationshipClassVersion` — use that name to address it in - * {@link UpdateMembershipParameters} patch paths. + * To change this later, patch `/relationshipClassVersion` — the stored property name, which is + * what responses and real-time events carry. It is *not* `/data/classVersion`. + * + * @example + * ```typescript + * await pubnub.dataSync.updateMembership({ id, replace: { '/relationshipClassVersion': 2 } }); + * ``` */ classVersion: number; - /** Optional lifecycle status. */ + /** + * Optional lifecycle status. + * + * To change this later, patch `/status`. + */ status?: string; - /** User-defined JSON payload. */ + /** + * User-defined JSON payload. + * + * To change a payload field later, patch `/payload/`; nest deeper with more segments. + * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * + * @example + * ```typescript + * // create + * await pubnub.dataSync.createMembership({ + * userId, channelId, + * data: { classVersion: 1, payload: { role: 'member', notificationsEnabled: true } }, + * }); + * // later + * await pubnub.dataSync.updateMembership({ + * id, + * replace: { '/payload/role': 'moderator' }, + * remove: ['/payload/notificationsEnabled'], + * }); + * ``` + */ payload?: Record; }; @@ -1421,7 +1600,11 @@ export type CreateMembershipData = { * (`SYN-0004: must not be null`), mirroring {@link SetRelationshipData}. */ export type SetMembershipData = { - /** Version of the Membership relationship class. */ + /** + * Version of the Membership relationship class. + * + * With `updateMembership` (PATCH) the same value is addressed as `/relationshipClassVersion`. + */ classVersion: number; /** Optional lifecycle status. */ @@ -1482,10 +1665,10 @@ export type CreateMembershipParameters = { */ id?: string; - /** User ID reference. */ + /** User ID reference. Immutable after creation, so it cannot be patched. */ userId: string; - /** Channel ID reference. */ + /** Channel ID reference. Immutable after creation, so it cannot be patched. */ channelId: string; /** Mutable, versioned membership data (class version, status, and payload). */ @@ -1547,13 +1730,13 @@ export type SetMembershipParameters = { /** * Update Membership request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with dot-notation field paths, which the SDK converts to - * JSON Patch operations. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK + * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. * * Patch paths address the membership's **stored property names** — the same keys that come back in * responses and real-time events — not the grouped parameter names used by * {@link CreateMembershipParameters}. So the class version is `relationshipClassVersion` (not - * `data.classVersion`), and payload fields keep their `payload.` prefix. `channelId` and `userId` + * `/data/classVersion`), and payload fields keep their `/payload` prefix. `channelId` and `userId` * are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. @@ -1563,40 +1746,40 @@ export type UpdateMembershipParameters = { id: string; /** - * Fields to add, using dot-notation keys. + * Fields to add, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "add" operations. */ add?: Record; /** - * Fields to replace, using dot-notation keys. + * Fields to replace, keyed by JSON Pointer (used exactly as provided). * The SDK converts these to JSON Patch "replace" operations. */ replace?: Record; /** - * Array of dot-notation field paths to remove. + * Array of JSON Pointer field paths to remove (used exactly as provided). * The SDK converts these to JSON Patch "remove" operations. */ 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 + * Source → destination path pairs to move (RFC 6902 "move"). Both paths are JSON Pointers 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`. + * Source → destination path pairs to copy (RFC 6902 "copy"). Both paths are JSON Pointers 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 + * Fields to test (JSON Pointer 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). + * `/payload` for payload fields). */ test?: Record; From 90efcf47227803b6f07430bb89773be3d2f41e8e Mon Sep 17 00:00:00 2001 From: Mohit Tejani Date: Wed, 19 Aug 2026 16:12:00 +0530 Subject: [PATCH 27/27] JSDoc with more details on how to use patch (update) apis with json pointers --- src/core/pubnub-data-sync.ts | 300 ++++++++++++++++++++++++++++++-- src/core/types/api/data-sync.ts | 108 +++++++----- 2 files changed, 348 insertions(+), 60 deletions(-) diff --git a/src/core/pubnub-data-sync.ts b/src/core/pubnub-data-sync.ts index eb78b0900..75fcb8bf4 100644 --- a/src/core/pubnub-data-sync.ts +++ b/src/core/pubnub-data-sync.ts @@ -302,7 +302,25 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name an entity carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateEntity({ + * id, + * replace: { '/status': 'inactive', '/payload/creditScore': 810 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -315,7 +333,25 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name an entity carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateEntity({ + * id, + * replace: { '/status': 'inactive', '/payload/creditScore': 810 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @@ -326,7 +362,25 @@ export default class PubNubDataSync { /** * Update an Entity (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name an entity carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateEntity({ + * id, + * replace: { '/status': 'inactive', '/payload/creditScore': 810 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -620,7 +674,25 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a relationship carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `relationshipClass`, `entityAId`, and `entityBId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateRelationship({ + * id, + * replace: { '/status': 'inactive', '/payload/label': 'primary' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -633,7 +705,25 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a relationship carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `relationshipClass`, `entityAId`, and `entityBId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateRelationship({ + * id, + * replace: { '/status': 'inactive', '/payload/label': 'primary' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @@ -646,7 +736,25 @@ export default class PubNubDataSync { /** * Update a Relationship (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a relationship carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `relationshipClass`, `entityAId`, and `entityBId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateRelationship({ + * id, + * replace: { '/status': 'inactive', '/payload/label': 'primary' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -933,7 +1041,25 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a user carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateUser({ + * id, + * replace: { '/status': 'inactive', '/payload/email': 'alice.v@acme.test' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -946,7 +1072,25 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a user carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateUser({ + * id, + * replace: { '/status': 'inactive', '/payload/email': 'alice.v@acme.test' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @@ -957,7 +1101,25 @@ export default class PubNubDataSync { /** * Update a User (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a user carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateUser({ + * id, + * replace: { '/status': 'inactive', '/payload/email': 'alice.v@acme.test' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -1251,7 +1413,25 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a channel carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateChannel({ + * id, + * replace: { '/status': 'inactive', '/payload/memberCount': 42 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -1264,7 +1444,25 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a channel carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateChannel({ + * id, + * replace: { '/status': 'inactive', '/payload/memberCount': 42 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @@ -1275,7 +1473,25 @@ export default class PubNubDataSync { /** * Update a Channel (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a channel carries in responses and real-time events: + * + * - `classVersion` → `/entityClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateChannel({ + * id, + * replace: { '/status': 'inactive', '/payload/memberCount': 42 }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. @@ -1571,7 +1787,25 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a membership carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `userId` and `channelId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateMembership({ + * id, + * replace: { '/status': 'inactive', '/payload/role': 'moderator' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param callback - Request completion handler callback. @@ -1584,7 +1818,25 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a membership carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `userId` and `channelId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateMembership({ + * id, + * replace: { '/status': 'inactive', '/payload/role': 'moderator' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @@ -1597,7 +1849,25 @@ export default class PubNubDataSync { /** * Update a Membership (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, sent verbatim. + * Paths are JSON Pointers (RFC 6901). Address each field by its stored property name, which + * is the name a membership carries in responses and real-time events: + * + * - `classVersion` → `/relationshipClassVersion` + * - `status` → `/status` + * - a payload field → `/payload/`; nest deeper with more segments, e.g. + * `/payload/address/city`. A field name that contains a `.` is written as-is + * (`/payload/user.name`). + * + * `userId` and `channelId` are immutable and cannot be patched. + * + * @example + * ```typescript + * await pubnub.dataSync.updateMembership({ + * id, + * replace: { '/status': 'inactive', '/payload/role': 'moderator' }, + * remove: ['/payload/legacyField'], + * }); + * ``` * * @param parameters - Request configuration parameters. * @param [callback] - Request completion handler callback. diff --git a/src/core/types/api/data-sync.ts b/src/core/types/api/data-sync.ts index 83d6572dc..d714d9a89 100644 --- a/src/core/types/api/data-sync.ts +++ b/src/core/types/api/data-sync.ts @@ -222,11 +222,9 @@ export type JsonPatchInput = { /** * Convert user-friendly patch input to JSON Patch operations (request format). * - * Paths are passed through **verbatim**: the SDK does not translate `.` to `/`, nor prefix a - * leading `/`. Callers provide the exact RFC 6901 JSON Pointer they want on the wire (e.g. - * `/payload/creditScore`). This keeps field names that themselves contain `.` addressable — - * a path such as `/payload/user.name` targets the literal key `user.name`, which dot-notation - * translation would have split into two segments. + * `path`/`from` are passed through verbatim — callers supply the exact RFC 6901 pointer. Do not + * reintroduce dot-notation translation here: splitting on `.` makes stored field names that + * contain a `.` unaddressable. * * - Each key in `add` becomes an "add" operation. * - Each key in `replace` becomes a "replace" operation. @@ -328,7 +326,7 @@ export type CreateEntityData = { * User-defined JSON payload conforming to the entity class schema. * * To change a payload field later, patch `/payload/`; nest deeper with more segments. - * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * * @example * ```typescript @@ -496,14 +494,18 @@ export type SetEntityParameters = { /** * Update Entity request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK - * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths. * - * Patch paths address the entity's **stored property names** — the same keys that come back in - * responses and real-time events — not the grouped parameter names used by - * {@link CreateEntityParameters}. So the class version is `/entityClassVersion` (not - * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and - * `entityClassLevel` are immutable and cannot be patched. + * Patch paths address the entity's **stored property names** — the same keys that come + * back in responses and real-time events — not the grouped parameter names used by + * {@link CreateEntityParameters}: + * + * - `classVersion` → `/entityClassVersion` (not `/data/classVersion`) + * - `status` → `/status` + * - a payload field → `/payload/`, e.g. `/payload/address/city` for a nested one. + * A field name that contains a `.` is written as-is (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ @@ -678,7 +680,7 @@ export type CreateRelationshipData = { * User-defined JSON payload. * * To change a payload field later, patch `/payload/`; nest deeper with more segments. - * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * * @example * ```typescript @@ -847,14 +849,18 @@ export type SetRelationshipParameters = { /** * Update Relationship request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK - * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths. + * + * Patch paths address the relationship's **stored property names** — the same keys that come + * back in responses and real-time events — not the grouped parameter names used by + * {@link CreateRelationshipParameters}: * - * Patch paths address the relationship's **stored property names** — the same keys that come back in - * responses and real-time events — not the grouped parameter names used by - * {@link CreateRelationshipParameters}. So the class version is `relationshipClassVersion` (not - * `/data/classVersion`), and payload fields keep their `/payload` prefix. `relationshipClass`, - * `entityAId`, and `entityBId` are immutable and cannot be patched. + * - `classVersion` → `/relationshipClassVersion` (not `/data/classVersion`) + * - `status` → `/status` + * - a payload field → `/payload/`, e.g. `/payload/address/city` for a nested one. + * A field name that contains a `.` is written as-is (`/payload/user.name`). + * + * `relationshipClass`, `entityAId`, and `entityBId` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ @@ -1008,7 +1014,7 @@ export type CreateUserData = { * User-defined JSON payload conforming to the entity class schema. * * To change a payload field later, patch `/payload/`; nest deeper with more segments. - * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * * @example * ```typescript @@ -1155,14 +1161,18 @@ export type SetUserParameters = { /** * Update User request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK - * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths. + * + * Patch paths address the user's **stored property names** — the same keys that come + * back in responses and real-time events — not the grouped parameter names used by + * {@link CreateUserParameters}: * - * Patch paths address the user's **stored property names** — the same keys that come back in - * responses and real-time events — not the grouped parameter names used by - * {@link CreateUserParameters}. So the class version is `entityClassVersion` (not - * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and - * `entityClassLevel` are immutable and cannot be patched. + * - `classVersion` → `/entityClassVersion` (not `/data/classVersion`) + * - `status` → `/status` + * - a payload field → `/payload/`, e.g. `/payload/address/city` for a nested one. + * A field name that contains a `.` is written as-is (`/payload/user.name`). + * + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ @@ -1289,7 +1299,7 @@ export type CreateChannelData = { * User-defined JSON payload conforming to the entity class schema. * * To change a payload field later, patch `/payload/`; nest deeper with more segments. - * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * * @example * ```typescript @@ -1437,14 +1447,18 @@ export type SetChannelParameters = { /** * Update Channel request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK - * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths. + * + * Patch paths address the channel's **stored property names** — the same keys that come + * back in responses and real-time events — not the grouped parameter names used by + * {@link CreateChannelParameters}: + * + * - `classVersion` → `/entityClassVersion` (not `/data/classVersion`) + * - `status` → `/status` + * - a payload field → `/payload/`, e.g. `/payload/address/city` for a nested one. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * - * Patch paths address the channel's **stored property names** — the same keys that come back in - * responses and real-time events — not the grouped parameter names used by - * {@link CreateChannelParameters}. So the class version is `entityClassVersion` (not - * `/data/classVersion`), and payload fields keep their `/payload` prefix. `entityClass` and - * `entityClassLevel` are immutable and cannot be patched. + * `entityClass` and `entityClassLevel` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */ @@ -1572,7 +1586,7 @@ export type CreateMembershipData = { * User-defined JSON payload. * * To change a payload field later, patch `/payload/`; nest deeper with more segments. - * Field names are used literally, so a key that itself contains `.` is addressed as-is. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * * @example * ```typescript @@ -1730,14 +1744,18 @@ export type SetMembershipParameters = { /** * Update Membership request parameters (partial update via JSON Patch RFC 6902). * - * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths, which the SDK - * sends verbatim as JSON Patch operations — no `.` → `/` translation and no leading `/` added. + * Uses `add`, `replace`, and `remove` with JSON Pointer (RFC 6901) field paths. + * + * Patch paths address the membership's **stored property names** — the same keys that come + * back in responses and real-time events — not the grouped parameter names used by + * {@link CreateMembershipParameters}: + * + * - `classVersion` → `/relationshipClassVersion` (not `/data/classVersion`) + * - `status` → `/status` + * - a payload field → `/payload/`, e.g. `/payload/address/city` for a nested one. + * A field name that contains a `.` is written as-is (`/payload/user.name`). * - * Patch paths address the membership's **stored property names** — the same keys that come back in - * responses and real-time events — not the grouped parameter names used by - * {@link CreateMembershipParameters}. So the class version is `relationshipClassVersion` (not - * `/data/classVersion`), and payload fields keep their `/payload` prefix. `channelId` and `userId` - * are immutable and cannot be patched. + * `userId` and `channelId` are immutable and cannot be patched. * * At least one of `add`, `replace`, or `remove` must be provided. */