diff --git a/.changeset/purple-rats-listen.md b/.changeset/purple-rats-listen.md new file mode 100644 index 00000000..c2734a79 --- /dev/null +++ b/.changeset/purple-rats-listen.md @@ -0,0 +1,5 @@ +--- +"@absmach/magistrala-sdk": patch +--- + +Add channel level role management diff --git a/examples/channels.ts b/examples/channels.ts index 6a7a92db..30d3c117 100644 --- a/examples/channels.ts +++ b/examples/channels.ts @@ -34,7 +34,7 @@ mySdk.channels .CreateChannels( [{ name: "" }, { name: "" }], domainId, - token, + token ) .then((response: any) => { console.log("response:", response); @@ -56,7 +56,7 @@ mySdk.channels .UpdateChannelNameAndMetadata( { id: "", name: "", metadata: { key: "value" } }, domainId, - token, + token ) .then((response: any) => { console.log("response:", response); @@ -69,7 +69,7 @@ mySdk.channels .UpdateChannelTags( { id: "", tags: ["tag1", "tag2"] }, domainId, - token, + token ) .then((response: any) => { console.log("response:", response); @@ -102,7 +102,7 @@ mySdk.channels "", ["publish"], domainId, - token, + token ) .then((response: any) => { console.log("response: ", response); @@ -117,7 +117,7 @@ mySdk.channels "", ["publish"], domainId, - token, + token ) .then((response: any) => { console.log("response: ", response); @@ -132,7 +132,7 @@ mySdk.channels ["", ""], ["publish"], domainId, - token, + token ) .then((response: any) => { console.log("response:", response); @@ -147,7 +147,7 @@ mySdk.channels ["", ""], ["publish"], domainId, - token, + token ) .then((response: any) => { console.log("response: ", response); @@ -156,7 +156,8 @@ mySdk.channels console.error(error); }); -mySdk.channels.SetChannelParentGroup(domainId, "", "", token) +mySdk.channels + .SetChannelParentGroup(domainId, "", "", token) .then((response: any) => { console.log("response: ", response); }) @@ -164,7 +165,8 @@ mySdk.channels.SetChannelParentGroup(domainId, "", "", console.error(error); }); -mySdk.channels.DeleteChannelParentGroup(domainId, "", token) +mySdk.channels + .DeleteChannelParentGroup(domainId, "", token) .then((response: any) => { console.log("response: ", response); }) @@ -180,3 +182,165 @@ mySdk.channels .catch((error) => { console.error(error); }); + +mySdk.channels + .ListChannelActions(domainId, token) + .then((response: any) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .CreateChannelRole("", "", domainId, token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .ListChannelRoles("", domainId, { offset: 0, limit: 10 }, token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .ViewChannelRole("", domainId, "", token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .UpdateChannelRole( + "", + domainId, + "", + { name: "" }, + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .DeleteChannelRole("", domainId, "", token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .AddChannelRoleActions( + "", + domainId, + "", + ["", ""], + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .ListChannelRoleActions("", domainId, "", token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .DeleteChannelRoleActions( + "", + domainId, + "", + ["", ""], + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .DeleteAllChannelRoleActions("", domainId, "", token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .AddChannelRoleMembers( + "", + domainId, + "", + ["", ""], + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .ListChannelRoleMembers( + "", + domainId, + "", + { offset: 0, limit: 10 }, + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .DeleteChannelRoleMembers( + "", + domainId, + "", + ["", ""], + token + ) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); + +mySdk.channels + .DeleteAllChannelRoleMembers("", domainId, "", token) + .then((response) => { + console.log("response: ", response); + }) + .catch((error) => { + console.error(error); + }); diff --git a/src/channels.ts b/src/channels.ts index 07c8d553..bc0ff579 100644 --- a/src/channels.ts +++ b/src/channels.ts @@ -8,12 +8,16 @@ import type { PageMetadata, Response, ChannelsPage, + Role, + RolePage, + BasicPageMeta, } from "./defs"; +import Roles from "./roles"; /** -* @class Channels -* Handles interactions with channels API, including creating, updating and managing channels. -*/ + * @class Channels + * Handles interactions with channels API, including creating, updating and managing channels. + */ export default class Channels { private readonly contentType: string; @@ -21,30 +25,29 @@ export default class Channels { private readonly channelsUrl: URL; + private readonly channelRoles: Roles; + /** * @constructor * Initializes the Channel API client. * @param {object} config - Configuration object. * @param {string} config.channelsUrl - Base URL for the channels API. */ - public constructor({ - channelsUrl, - }: { - channelsUrl:string; - }) { + public constructor({ channelsUrl }: { channelsUrl: string }) { this.channelsUrl = new URL(channelsUrl); this.contentType = "application/json"; this.channelsEndpoint = "channels"; + this.channelRoles = new Roles(); } /** - * @method CreateChannel - Creates a new channel - * @param {Channel} channel - Channel object with a containing details like name, metadata and tags. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The created channel object. - * @throws {Error} - If the channel cannot be created. - */ + * @method CreateChannel - Creates a new channel + * @param {Channel} channel - Channel object with a containing details like name, metadata and tags. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The created channel object. + * @throws {Error} - If the channel cannot be created. + */ public async CreateChannel( channel: Channel, domainId: string, @@ -78,13 +81,13 @@ export default class Channels { } /** - * @method Channel - Retrieves a channel by its id. - * @param {string} channelId - The unique ID of the channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The requested channel object. - * @throws {Error} - If the channel cannot be fetched. - */ + * @method Channel - Retrieves a channel by its id. + * @param {string} channelId - The unique ID of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The requested channel object. + * @throws {Error} - If the channel cannot be fetched. + */ public async Channel( channelId: string, domainId: string, @@ -117,13 +120,13 @@ export default class Channels { } /** - * @method CreateChannels - Creates multiple new channels. - * @param {Channel[]} channels - An array of channel objects, each containing details like name, metadata, and tags. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channelsPage - A page of channels. - * @throws {Error} - If the channels cannot be created. - */ + * @method CreateChannels - Creates multiple new channels. + * @param {Channel[]} channels - An array of channel objects, each containing details like name, metadata, and tags. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channelsPage - A page of channels. + * @throws {Error} - If the channels cannot be created. + */ public async CreateChannels( channels: Channel[], domainId: string, @@ -157,13 +160,13 @@ export default class Channels { } /** - * @method Channels - Retrieves all channels matching the provided query parameters. - * @param {PageMetadata} queryParams - Query parameters for the request. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channelsPage - A page of channels. - * @throws {Error} - If the channels cannot be fetched. - */ + * @method Channels - Retrieves all channels matching the provided query parameters. + * @param {PageMetadata} queryParams - Query parameters for the request. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channelsPage - A page of channels. + * @throws {Error} - If the channels cannot be fetched. + */ public async Channels( queryParams: PageMetadata, domainId: string, @@ -201,13 +204,13 @@ export default class Channels { } /** - * @method UpdateChannelNameAndMetadata - Updates an existing channel's metadata and name. - * @param {Channel} channel - Channel object with updated properties. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The updated channel object. - * @throws {Error} - If the channel cannot be updated. - */ + * @method UpdateChannelNameAndMetadata - Updates an existing channel's metadata and name. + * @param {Channel} channel - Channel object with updated properties. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The updated channel object. + * @throws {Error} - If the channel cannot be updated. + */ public async UpdateChannelNameAndMetadata( channel: Channel, domainId: string, @@ -241,13 +244,13 @@ export default class Channels { } /** - * @method UpdateChannelTags - Updates an existing channel's tags. - * @param {Channel} channel - Channel object with updated properties. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The updated channel object. - * @throws {Error} - If the channel tags cannot be updated. - */ + * @method UpdateChannelTags - Updates an existing channel's tags. + * @param {Channel} channel - Channel object with updated properties. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The updated channel object. + * @throws {Error} - If the channel tags cannot be updated. + */ public async UpdateChannelTags( channel: Channel, domainId: string, @@ -281,13 +284,13 @@ export default class Channels { } /** - * @method DisableChannel - Disables a spcific channel. - * @param {string} channelId - The unique ID of the channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The disabled channel object. - * @throws {Error} - If the channel cannot be disabled. - */ + * @method DisableChannel - Disables a spcific channel. + * @param {string} channelId - The unique ID of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The disabled channel object. + * @throws {Error} - If the channel cannot be disabled. + */ public async DisableChannel( channelId: string, domainId: string, @@ -320,13 +323,13 @@ export default class Channels { } /** - * @method EnableChannel - Enables a previously disabled channel. - * @param {string} channelId - The unique ID of the channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} channel - The enabled channel object. - * @throws {Error} - If the channel cannot be enabled. - */ + * @method EnableChannel - Enables a previously disabled channel. + * @param {string} channelId - The unique ID of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} channel - The enabled channel object. + * @throws {Error} - If the channel cannot be enabled. + */ public async EnableChannel( channelId: string, domainId: string, @@ -359,13 +362,13 @@ export default class Channels { } /** - * @method DeleteChannel - Deletes channel with specified id. - * @param {string} channelId - The unique ID of the channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the channel is deleted. - * @throws {Error} - If the channel cannot be deleted. - */ + * @method DeleteChannel - Deletes channel with specified id. + * @param {string} channelId - The unique ID of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the channel is deleted. + * @throws {Error} - If the channel cannot be deleted. + */ public async DeleteChannel( channelId: string, domainId: string, @@ -380,7 +383,10 @@ export default class Channels { }; try { const response = await fetch( - new URL(`${domainId}/${this.channelsEndpoint}/${channelId}`, this.channelsUrl).toString(), + new URL( + `${domainId}/${this.channelsEndpoint}/${channelId}`, + this.channelsUrl + ).toString(), options ); if (!response.ok) { @@ -398,15 +404,15 @@ export default class Channels { } /** - * @method ConnectClient - Connects multiple clients to a channel. - * @param {string[]} clientIds - An array of unique clients IDs to be connected. - * @param {string} channelId - The unique ID of the channel to which the clients will connect. - * @param {string[]}connectionTypes - Connection types can be publish, subscribe or both publish and subscribe - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the clients are connected to the channel. - * @throws {Error} - If the clients cannot be connected to the channel. - */ + * @method ConnectClient - Connects multiple clients to a channel. + * @param {string[]} clientIds - An array of unique clients IDs to be connected. + * @param {string} channelId - The unique ID of the channel to which the clients will connect. + * @param {string[]}connectionTypes - Connection types can be publish, subscribe or both publish and subscribe + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the clients are connected to the channel. + * @throws {Error} - If the clients cannot be connected to the channel. + */ public async ConnectClient( clientIds: string[], channelId: string, @@ -420,7 +426,11 @@ export default class Channels { "Content-Type": this.contentType, Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ client_ids: clientIds, channel_id: channelId, types: connectionTypes }), + body: JSON.stringify({ + client_ids: clientIds, + channel_id: channelId, + types: connectionTypes, + }), }; try { const response = await fetch( @@ -445,15 +455,15 @@ export default class Channels { } /** - * @method Connect - Connects multiple clients to multple channels. - * @param {string[]} clientIds - An array of unique clients IDs to be connected. - * @param {string[]} channelIds - An array of unique channels IDs to which the clients will connect. - * @param {string[]} connectionTypes - Connection types can be publish, subscribe or both publish and subscribe - * @param {string} domainId - The unique ID of the channel. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the clients are connected to the channels. - * @throws {Error} - If the clients cannot be connected to the channel. - */ + * @method Connect - Connects multiple clients to multple channels. + * @param {string[]} clientIds - An array of unique clients IDs to be connected. + * @param {string[]} channelIds - An array of unique channels IDs to which the clients will connect. + * @param {string[]} connectionTypes - Connection types can be publish, subscribe or both publish and subscribe + * @param {string} domainId - The unique ID of the channel. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the clients are connected to the channels. + * @throws {Error} - If the clients cannot be connected to the channel. + */ public async Connect( clientIds: string[], channelIds: string[], @@ -467,11 +477,18 @@ export default class Channels { "Content-Type": this.contentType, Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ client_ids: clientIds, channel_ids: channelIds, types: connectionTypes }), + body: JSON.stringify({ + client_ids: clientIds, + channel_ids: channelIds, + types: connectionTypes, + }), }; try { const response = await fetch( - new URL(`${domainId}/${this.channelsEndpoint}/connect`, this.channelsUrl).toString(), + new URL( + `${domainId}/${this.channelsEndpoint}/connect`, + this.channelsUrl + ).toString(), options ); if (!response.ok) { @@ -489,15 +506,15 @@ export default class Channels { } /** - * @method Disconnect - Disconnects clients from channels. - * @param {string[]} clientIds - An array of unique clients IDs to be disconnected. - * @param {string[]} channelIds - An array of unique channels IDs to which the clients will disconnect. - * @param {string[]}connectionTypes - Connection types can be publish, subscribe or both publish and subscribe. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the clients are disconnected from the channels. - * @throws {Error} - If the clients cannot be disconnected from the channels. - */ + * @method Disconnect - Disconnects clients from channels. + * @param {string[]} clientIds - An array of unique clients IDs to be disconnected. + * @param {string[]} channelIds - An array of unique channels IDs to which the clients will disconnect. + * @param {string[]}connectionTypes - Connection types can be publish, subscribe or both publish and subscribe. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the clients are disconnected from the channels. + * @throws {Error} - If the clients cannot be disconnected from the channels. + */ public async Disconnect( clientIds: string[], channelIds: string[], @@ -511,11 +528,18 @@ export default class Channels { "Content-Type": this.contentType, Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ client_ids: clientIds, channel_ids: channelIds, types: connectionTypes }), + body: JSON.stringify({ + client_ids: clientIds, + channel_ids: channelIds, + types: connectionTypes, + }), }; try { const response = await fetch( - new URL(`${domainId}/${this.channelsEndpoint}/disconnect`, this.channelsUrl).toString(), + new URL( + `${domainId}/${this.channelsEndpoint}/disconnect`, + this.channelsUrl + ).toString(), options ); if (!response.ok) { @@ -533,15 +557,15 @@ export default class Channels { } /** - * @method DisconnectClient - Disconnects clients from channel. - * @param {string[]} clientIds - An array of unique clients IDs to be disconnected. - * @param {string} channelId - The unique ID of the channel from which the clients will be disconnected. - * @param {string[]} connectionTypes - connection types can be publish, subscribe or both publish and subscribe. - * @param {string} domainId - The unique ID of the domain. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the clients are disconnected from the channel. - * @throws {Error} - If the clients cannot be disconnected from the channel. - */ + * @method DisconnectClient - Disconnects clients from channel. + * @param {string[]} clientIds - An array of unique clients IDs to be disconnected. + * @param {string} channelId - The unique ID of the channel from which the clients will be disconnected. + * @param {string[]} connectionTypes - connection types can be publish, subscribe or both publish and subscribe. + * @param {string} domainId - The unique ID of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the clients are disconnected from the channel. + * @throws {Error} - If the clients cannot be disconnected from the channel. + */ public async DisconnectClient( clientIds: string[], channelId: string, @@ -555,7 +579,11 @@ export default class Channels { "Content-Type": this.contentType, Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ client_ids: clientIds, channel_id: channelId, types: connectionTypes }), + body: JSON.stringify({ + client_ids: clientIds, + channel_id: channelId, + types: connectionTypes, + }), }; try { const response = await fetch( @@ -580,33 +608,44 @@ export default class Channels { } /** - * @method SetChannelParentGroup - Sets parent to a channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} channelId - The unique ID of the channel to be updated. - * @param {string} parentGroupId - The unique ID of the group to be set as the parent. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the parent group is successfully set for the specified channel. - * @throws {Error} - If the parent group cannot be set for the channel. - */ - public async SetChannelParentGroup(domainId: string, channelId: string, parentGroupId: string, token: string) : Promise { + * @method SetChannelParentGroup - Sets parent to a channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} channelId - The unique ID of the channel to be updated. + * @param {string} parentGroupId - The unique ID of the group to be set as the parent. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the parent group is successfully set for the specified channel. + * @throws {Error} - If the parent group cannot be set for the channel. + */ + public async SetChannelParentGroup( + domainId: string, + channelId: string, + parentGroupId: string, + token: string + ): Promise { const options: RequestInit = { method: "POST", headers: { "Content-Type": this.contentType, - Authorization: `Bearer ${token}` + Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ parent_group_id: parentGroupId }) + body: JSON.stringify({ parent_group_id: parentGroupId }), }; try { const response = await fetch( - new URL(`${domainId}/${this.channelsEndpoint}/${channelId}/parent`, this.channelsUrl).toString(), + new URL( + `${domainId}/${this.channelsEndpoint}/${channelId}/parent`, + this.channelsUrl + ).toString(), options ); if (!response.ok) { const errorRes = await response.json(); throw Errors.HandleError(errorRes.message, response.status); } - const addChannelParentsResponse: Response = { status: response.status, message: "Channel group parent added successfully" }; + const addChannelParentsResponse: Response = { + status: response.status, + message: "Channel group parent added successfully", + }; return addChannelParentsResponse; } catch (error) { throw error; @@ -614,19 +653,23 @@ export default class Channels { } /** - * @method DeleteChannelParentGroup - Removes the parent group from a specified channel. - * @param {string} domainId - The unique ID of the domain. - * @param {string} channelId - The unique ID of the channel. - * @param {string} token - Authorization token. - * @returns {Promise} response - A promise that resolves when the parent group is successfully removed from the specified channel. - * @throws {Error} - If the parent group cannot removed from the channel. - */ - public async DeleteChannelParentGroup(domainId: string, channelId: string, token: string) : Promise { + * @method DeleteChannelParentGroup - Removes the parent group from a specified channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} channelId - The unique ID of the channel. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the parent group is successfully removed from the specified channel. + * @throws {Error} - If the parent group cannot removed from the channel. + */ + public async DeleteChannelParentGroup( + domainId: string, + channelId: string, + token: string + ): Promise { const options: RequestInit = { method: "DELETE", headers: { "Content-Type": this.contentType, - Authorization: `Bearer ${token}` + Authorization: `Bearer ${token}`, }, }; try { @@ -641,10 +684,436 @@ export default class Channels { const errorRes = await response.json(); throw Errors.HandleError(errorRes.message, response.status); } - const deleteChannelParentsResponse: Response = { status: response.status, message: "Channel group parent deleted successfully" }; + const deleteChannelParentsResponse: Response = { + status: response.status, + message: "Channel group parent deleted successfully", + }; return deleteChannelParentsResponse; } catch (error) { throw error; } } + + /** + * @method ListChannelActions - Lists all actions available to a specific channel. + * @param {string} domainId - The unique identifier of the domain. + * @param {string} token - Authorization token. + * @returns {Promise} actions - A promise that resolves with an array of actions. + * @throws {Error} - If channel actions cannot be fetched. + */ + public async ListChannelActions( + domainId: string, + token: string + ): Promise { + try { + const actions: string[] = await this.channelRoles.ListAvailableActions( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + token + ); + return actions; + } catch (error) { + throw error; + } + } + + /** + * @method CreateChannelRole - Creates a new role within a specific channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleName - The name of the role to create. + * @param {string} token - Authorization token. + * @param {string[]} optionalActions - Optional actions assigned to the role. + * @param {string[]} optionalMembers - Optional members assigned to the role. + * @returns {Promise} role - A promise that resolves with the role created. + * @throws {Error} - If the role cannot be created or already exists. + */ + public async CreateChannelRole( + channelId: string, + roleName: string, + domainId: string, + token: string, + optionalActions?: string[], + optionalMembers?: string[] + ): Promise { + try { + const role: Role = await this.channelRoles.CreateRole( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleName, + token, + optionalActions, + optionalMembers + ); + return role; + } catch (error) { + throw error; + } + } + + /** + * @method ListChannelRoles - Lists all roles within a specific channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {PageMetadata} queryParams - Metadata for pagination or filters. + * @param {string} token - Authorization token. + * @returns {Promise} rolePage - A promise that resolves with a page of roles in the domain. + * @throws {Error} - If the channel is invalid or roles cannot be fetched. + */ + public async ListChannelRoles( + channelId: string, + domainId: string, + queryParams: PageMetadata, + token: string + ): Promise { + try { + const rolesPage: RolePage = await this.channelRoles.ListRoles( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + queryParams, + token + ); + return rolesPage; + } catch (error) { + throw error; + } + } + + /** + * @method ViewChannelRole - Retrieves details about a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} role - A promise that resolves with the role details. + * @throws {Error} - If the role does not exist or cannot be retrieved. + */ + public async ViewChannelRole( + channelId: string, + domainId: string, + roleId: string, + token: string + ): Promise { + try { + const role = await this.channelRoles.ViewRole( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + token + ); + return role; + } catch (error) { + throw error; + } + } + + /** + * @method UpdateChannelRole - Updates the details of a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {Role} role - The role to be updated. + * @param {string} token - Authorization token. + * @returns {Promise} role - A promise that resolves with the updated role. + * @throws {Error} - If the role cannot be updated. + */ + public async UpdateChannelRole( + channelId: string, + domainId: string, + roleId: string, + role: Role, + token: string + ): Promise { + try { + const updatedRole = await this.channelRoles.UpdateRole( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + role, + token + ); + return updatedRole; + } catch (error) { + throw error; + } + } + + /** + * @method DeleteChannelRole - Deletes a specific role from a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when the role is deleted. + * @throws {Error} - If the role cannot be deleted. + */ + public async DeleteChannelRole( + channelId: string, + domainId: string, + roleId: string, + token: string + ): Promise { + try { + const response = await this.channelRoles.DeleteRole( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method AddChannelRoleActions - Adds actions to a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @param {string[]} actions - The actions to add to the role. + * @returns {Promise} role actions- A promise that resolves with an array of actions. + * @throws {Error} - If the actions cannot be added. + */ + public async AddChannelRoleActions( + channelId: string, + domainId: string, + roleId: string, + actions: string[], + token: string + ): Promise { + try { + const response = await this.channelRoles.AddRoleActions( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + actions, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method ListChannelRoleActions - Lists all actions associated with a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} role actions - A promise that resolves with an array of actions. + * @throws {Error} - If actions cannot be retrieved. + */ + public async ListChannelRoleActions( + channelId: string, + domainId: string, + roleId: string, + token: string + ): Promise { + try { + const updatedRole = await this.channelRoles.ListRoleActions( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + token + ); + return updatedRole; + } catch (error) { + throw error; + } + } + + /** + * @method DeleteChannelRoleActions - Deletes specific actions from a role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string[]} actions - The actions to delete from the role. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when actions are deleted. + * @throws {Error} - If the actions cannot be deleted. + */ + public async DeleteChannelRoleActions( + channelId: string, + domainId: string, + roleId: string, + actions: string[], + token: string + ): Promise { + try { + const response = await this.channelRoles.DeleteRoleActions( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + actions, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method DeleteAllChannelRoleActions - Deletes all actions associated with a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when all actions are deleted. + * @throws {Error} - If the actions cannot be deleted. + */ + public async DeleteAllChannelRoleActions( + channelId: string, + domainId: string, + roleId: string, + token: string + ): Promise { + try { + const response = await this.channelRoles.DeleteAllRoleActions( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method AddChannelRoleMembers - Adds members to a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string[]} members - The IDs of the members to add. + * @param {string} token - Authorization token. + * @returns {Promise} members - A promise that resolves with an array of member ids. + * @throws {Error} - If the members cannot be added. + */ + public async AddChannelRoleMembers( + channelId: string, + domainId: string, + roleId: string, + members: string[], + token: string + ): Promise { + try { + const response = await this.channelRoles.AddRoleMembers( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + members, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method ListChannelRoleMembers - Lists all members associated with a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} members - A promise that resolves with an array of member ids. + * @throws {Error} - If members cannot be retrieved. + */ + public async ListChannelRoleMembers( + channelId: string, + domainId: string, + roleId: string, + queryParams: BasicPageMeta, + token: string + ): Promise { + try { + const updatedRole = await this.channelRoles.ListRoleMembers( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + queryParams, + token + ); + return updatedRole; + } catch (error) { + throw error; + } + } + + /** + * @method DeleteChannelRoleMembers - Deletes specific members from a role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string[]} members - The IDs of the members to delete. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when members are deleted. + * @throws {Error} - If the members cannot be deleted. + */ + public async DeleteChannelRoleMembers( + channelId: string, + domainId: string, + roleId: string, + members: string[], + token: string + ): Promise { + try { + const response = await this.channelRoles.DeleteRoleMembers( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + members, + token + ); + return response; + } catch (error) { + throw error; + } + } + + /** + * @method DeleteAllChannelRoleMembers - Deletes all members associated with a specific role in a channel. + * @param {string} channelId - The unique identifier of the channel. + * @param {string} domainId - The unique ID of the domain. + * @param {string} roleId - The unique identifier of the role. + * @param {string} token - Authorization token. + * @returns {Promise} response - A promise that resolves when all members are deleted. + * @throws {Error} - If the members cannot be deleted. + */ + public async DeleteAllChannelRoleMembers( + channelId: string, + domainId: string, + roleId: string, + token: string + ): Promise { + try { + const response = await this.channelRoles.DeleteAllRoleMembers( + this.channelsUrl, + `${domainId}/${this.channelsEndpoint}`, + channelId, + roleId, + token + ); + return response; + } catch (error) { + throw error; + } + } } diff --git a/tests/channels.test.ts b/tests/channels.test.ts index 3b1e22ff..96257eb1 100644 --- a/tests/channels.test.ts +++ b/tests/channels.test.ts @@ -4,10 +4,7 @@ import fetchMock, { enableFetchMocks } from "jest-fetch-mock"; import SDK from "../src/sdk"; -import type { - Channel, - ChannelsPage, -} from "../src/sdk"; +import type { Channel, ChannelsPage } from "../src/sdk"; enableFetchMocks(); @@ -48,6 +45,10 @@ describe("Channels", () => { "ce42d80e-9773-49b2-a8c2-6aa748597a92", ]; const connectionType = ["publish"]; + const roleName = "editor"; + const actions = ["read", "write"]; + const members = ["user1", "user2"]; + const role = { name: roleName, actions, members }; beforeEach(() => { fetchMock.resetMocks(); @@ -70,7 +71,11 @@ describe("Channels", () => { test("Create channels should create multiple channels", async () => { fetchMock.mockResponseOnce(JSON.stringify(channels)); - const response = await sdk.channels.CreateChannels(channels, domainId, token); + const response = await sdk.channels.CreateChannels( + channels, + domainId, + token + ); expect(response).toEqual(channels); }); @@ -84,28 +89,44 @@ describe("Channels", () => { test("Update channel name and metadata should update a channel's name and metadata", async () => { fetchMock.mockResponseOnce(JSON.stringify(channel)); - const response = await sdk.channels.UpdateChannelNameAndMetadata(channel, domainId, token); + const response = await sdk.channels.UpdateChannelNameAndMetadata( + channel, + domainId, + token + ); expect(response).toEqual(channel); }); test("Update channel tags should update channel's tags", async () => { fetchMock.mockResponseOnce(JSON.stringify(channel)); - const response = await sdk.channels.UpdateChannelTags(channel, domainId, token); + const response = await sdk.channels.UpdateChannelTags( + channel, + domainId, + token + ); expect(response).toEqual(channel); }); test("Enable channel should enable a channel", async () => { fetchMock.mockResponseOnce(JSON.stringify(channel)); - const response = await sdk.channels.EnableChannel(channelId, domainId, token); + const response = await sdk.channels.EnableChannel( + channelId, + domainId, + token + ); expect(response).toEqual(channel); }); test("Disable channel should disable a channel", async () => { fetchMock.mockResponseOnce(JSON.stringify(channel)); - const response = await sdk.channels.DisableChannel(channelId, domainId, token); + const response = await sdk.channels.DisableChannel( + channelId, + domainId, + token + ); expect(response).toEqual(channel); }); @@ -119,7 +140,7 @@ describe("Channels", () => { const response = await sdk.channels.DeleteChannel( channelId, domainId, - token, + token ); expect(response).toEqual(deleteResponse); }); @@ -136,7 +157,7 @@ describe("Channels", () => { channelId, connectionType, domainId, - token, + token ); expect(response).toEqual(connectClientResponse); }); @@ -153,7 +174,7 @@ describe("Channels", () => { channelId, connectionType, domainId, - token, + token ); expect(response).toEqual(DisconnectClientResponse); }); @@ -170,7 +191,7 @@ describe("Channels", () => { channelIds, connectionType, domainId, - token, + token ); expect(response).toEqual(connectResponse); }); @@ -187,7 +208,7 @@ describe("Channels", () => { channelIds, connectionType, domainId, - token, + token ); expect(response).toEqual(DisconnectResponse); }); @@ -203,7 +224,7 @@ describe("Channels", () => { domainId, channelId, groupId, - token, + token ); expect(response).toEqual(ChannelParentsResponse); }); @@ -218,8 +239,206 @@ describe("Channels", () => { const response = await sdk.channels.DeleteChannelParentGroup( domainId, channelId, - token, + token ); expect(response).toEqual(ChannelParentsResponse); }); + + test("List channel actions should return available actions", async () => { + const availableActions = ["read", "write", "delete"]; + fetchMock.mockResponseOnce( + JSON.stringify({ available_actions: availableActions }) + ); + + const response = await sdk.channels.ListChannelActions(domainId, token); + expect(response).toEqual(availableActions); + }); + + test("Create channel role should create a new role and return it", async () => { + fetchMock.mockResponseOnce(JSON.stringify(role)); + + const response = await sdk.channels.CreateChannelRole( + channelId, + roleName, + domainId, + token, + actions, + members + ); + expect(response).toEqual(role); + }); + + test("List channel roles should return a page of roles", async () => { + const rolesPage = { roles: [role], total: 1, offset: 0, limit: 10 }; + fetchMock.mockResponseOnce(JSON.stringify(rolesPage)); + + const response = await sdk.channels.ListChannelRoles( + channelId, + domainId, + { offset: 0, limit: 10 }, + token + ); + expect(response).toEqual(rolesPage); + }); + + test("View channel role should return details of a specific role", async () => { + fetchMock.mockResponseOnce(JSON.stringify(role)); + + const response = await sdk.channels.ViewChannelRole( + channelId, + domainId, + roleName, + token + ); + expect(response).toEqual(role); + }); + + test("Update channel role should update a role and return the updated role", async () => { + const updatedRole = { ...role, actions: [...role.actions, "execute"] }; + fetchMock.mockResponseOnce(JSON.stringify(updatedRole)); + + const response = await sdk.channels.UpdateChannelRole( + channelId, + domainId, + roleName, + updatedRole, + token + ); + expect(response).toEqual(updatedRole); + }); + + test("Delete channel role should delete a role", async () => { + const successResponse = { + status: 200, + message: "Role deleted successfully", + }; + fetchMock.mockResponseOnce(JSON.stringify(successResponse)); + + const response = await sdk.channels.DeleteChannelRole( + channelId, + domainId, + roleName, + token + ); + expect(response).toEqual(successResponse); + }); + + test("Add channel role actions should add actions to a role and return updated actions", async () => { + const updatedActions = [...actions, "execute"]; + fetchMock.mockResponseOnce(JSON.stringify({ actions: updatedActions })); + + const response = await sdk.channels.AddChannelRoleActions( + channelId, + domainId, + roleName, + ["execute"], + token + ); + expect(response).toEqual(updatedActions); + }); + + test("List channel role actions should return actions of a specific role", async () => { + fetchMock.mockResponseOnce(JSON.stringify({ actions })); + + const response = await sdk.channels.ListChannelRoleActions( + channelId, + domainId, + roleName, + token + ); + expect(response).toEqual(actions); + }); + + test("Delete channel role actions should remove actions from a role", async () => { + const successResponse = { + status: 200, + message: "Role actions deleted successfully", + }; + fetchMock.mockResponseOnce(JSON.stringify(successResponse)); + + const response = await sdk.channels.DeleteChannelRoleActions( + channelId, + domainId, + roleName, + ["write"], + token + ); + expect(response).toEqual(successResponse); + }); + + test("Delete all channel role actions should remove all actions from a role", async () => { + const successResponse = { + status: 200, + message: "Role actions deleted successfully", + }; + fetchMock.mockResponseOnce(JSON.stringify(successResponse)); + + const response = await sdk.channels.DeleteAllChannelRoleActions( + channelId, + domainId, + roleName, + token + ); + expect(response).toEqual(successResponse); + }); + + test("Add channel role members should add members to a role and return updated members", async () => { + const updatedMembers = [...members, "user3"]; + fetchMock.mockResponseOnce(JSON.stringify({ members: updatedMembers })); + + const response = await sdk.channels.AddChannelRoleMembers( + channelId, + domainId, + roleName, + ["user3"], + token + ); + expect(response).toEqual(updatedMembers); + }); + + test("List channel role members should return members of a specific role", async () => { + fetchMock.mockResponseOnce(JSON.stringify({ members })); + + const response = await sdk.channels.ListChannelRoleMembers( + channelId, + domainId, + roleName, + { offset: 0, limit: 10 }, + token + ); + expect(response).toEqual(members); + }); + + test("Delete channel role members should remove members from a role response", async () => { + const successResponse = { + status: 200, + message: "Role members deleted successfully", + }; + fetchMock.mockResponseOnce(JSON.stringify(successResponse)); + + const response = await sdk.channels.DeleteChannelRoleMembers( + channelId, + domainId, + roleName, + ["user1"], + token + ); + expect(response).toEqual(successResponse); + }); + + test("Delete all channel role members should remove all members from a role response", async () => { + const successResponse = { + status: 200, + message: "Role members deleted successfully", + }; + fetchMock.mockResponseOnce(JSON.stringify(successResponse)); + + const response = await sdk.channels.DeleteAllChannelRoleMembers( + channelId, + domainId, + roleName, + token + ); + expect(response).toEqual(successResponse); + }); });