@crowdedkingdomstudios/crowdyjs 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/MIGRATION.md +22 -0
  2. package/dist/client.d.ts +98 -5
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +74 -5
  5. package/dist/crowdy-client.d.ts +31 -0
  6. package/dist/crowdy-client.d.ts.map +1 -1
  7. package/dist/crowdy-client.js +8 -0
  8. package/dist/domains/actors.d.ts +87 -4
  9. package/dist/domains/actors.d.ts.map +1 -1
  10. package/dist/domains/actors.js +87 -4
  11. package/dist/domains/apps.d.ts +95 -41
  12. package/dist/domains/apps.d.ts.map +1 -1
  13. package/dist/domains/apps.js +80 -33
  14. package/dist/domains/auth.d.ts +139 -19
  15. package/dist/domains/auth.d.ts.map +1 -1
  16. package/dist/domains/auth.js +137 -17
  17. package/dist/domains/channels.d.ts +264 -5
  18. package/dist/domains/channels.d.ts.map +1 -1
  19. package/dist/domains/channels.js +264 -5
  20. package/dist/domains/chunks.d.ts +116 -3
  21. package/dist/domains/chunks.d.ts.map +1 -1
  22. package/dist/domains/chunks.js +116 -3
  23. package/dist/domains/gameModel.d.ts +412 -6
  24. package/dist/domains/gameModel.d.ts.map +1 -1
  25. package/dist/domains/gameModel.js +412 -6
  26. package/dist/domains/platform.d.ts +36 -20
  27. package/dist/domains/platform.d.ts.map +1 -1
  28. package/dist/domains/platform.js +29 -18
  29. package/dist/domains/serverStatus.d.ts +74 -6
  30. package/dist/domains/serverStatus.d.ts.map +1 -1
  31. package/dist/domains/serverStatus.js +74 -6
  32. package/dist/domains/state.d.ts +50 -2
  33. package/dist/domains/state.d.ts.map +1 -1
  34. package/dist/domains/state.js +50 -2
  35. package/dist/domains/teams.d.ts +263 -5
  36. package/dist/domains/teams.d.ts.map +1 -1
  37. package/dist/domains/teams.js +263 -5
  38. package/dist/domains/teleport.d.ts +30 -2
  39. package/dist/domains/teleport.d.ts.map +1 -1
  40. package/dist/domains/teleport.js +30 -2
  41. package/dist/domains/udp.d.ts +341 -5
  42. package/dist/domains/udp.d.ts.map +1 -1
  43. package/dist/domains/udp.js +341 -5
  44. package/dist/domains/users.d.ts +42 -11
  45. package/dist/domains/users.d.ts.map +1 -1
  46. package/dist/domains/users.js +41 -10
  47. package/dist/domains/voxels.d.ts +107 -2
  48. package/dist/domains/voxels.d.ts.map +1 -1
  49. package/dist/domains/voxels.js +107 -2
  50. package/dist/errors.d.ts +116 -0
  51. package/dist/errors.d.ts.map +1 -1
  52. package/dist/errors.js +100 -0
  53. package/dist/generated/graphql.d.ts +5 -1
  54. package/dist/generated/graphql.d.ts.map +1 -1
  55. package/dist/generated/graphql.js +5 -1
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -1
  59. package/dist/realtime.d.ts +226 -0
  60. package/dist/realtime.d.ts.map +1 -1
  61. package/dist/realtime.js +90 -0
  62. package/dist/session.d.ts +46 -0
  63. package/dist/session.d.ts.map +1 -1
  64. package/dist/session.js +35 -0
  65. package/dist/types.d.ts +429 -0
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +53 -0
  68. package/dist/utils.d.ts +86 -0
  69. package/dist/utils.d.ts.map +1 -1
  70. package/dist/utils.js +86 -0
  71. package/dist/world.d.ts +192 -0
  72. package/dist/world.d.ts.map +1 -1
  73. package/dist/world.js +170 -0
  74. package/package.json +1 -1
@@ -1,23 +1,53 @@
1
+ import { ChangePasswordDocument, ConfirmEmailDocument, LoginDocument, LogoutAllDevicesDocument, LogoutDocument, RegisterDocument, RequestPasswordResetDocument, ResendConfirmationEmailDocument, ResetPasswordDocument, } from '../generated/graphql.js';
1
2
  /**
2
- * Auth sub-client. Talks to `cks-management-api` (NOT the game API) because
3
- * the management API owns the `game_tokens` table that backs every login /
4
- * register / password / email-confirm flow.
3
+ * Authentication and account-lifecycle flows exposed as `client.auth`.
4
+ *
5
+ * Targets the **management-api**: every call routes to `managementUrl` (falling
6
+ * back to the game-api endpoint only in legacy single-endpoint mode). The
7
+ * management API owns the `game_tokens` table that backs every login / register
8
+ * / password / email-confirmation flow; the `token` it returns is a
9
+ * `game_tokens` row that game-api validates against the same shared Postgres.
10
+ *
11
+ * {@link login} and {@link register} mint that session token **and** store it on
12
+ * the shared session state automatically, so every later call on *either*
13
+ * endpoint (auth, users, apps, actors, chunks, udp, ...) is authenticated
14
+ * without you threading the token through by hand. Use {@link setToken} to
15
+ * rehydrate a saved token and {@link getToken} to read the current one. `BigInt`
16
+ * ids on the returned user (e.g. `userId`, `orgId`) are decimal strings.
5
17
  *
6
- * The returned `token` is a `game_tokens` row that game-api will validate
7
- * against the same shared Postgres. Once the SDK has a token, the rest of
8
- * the sub-clients (chunks, voxels, actors, udp, ...) use it transparently
9
- * via the shared `AuthState`.
18
+ * **Public no session required:** {@link login}, {@link register},
19
+ * {@link confirmEmail}, {@link requestPasswordReset}, {@link resetPassword}, and
20
+ * {@link resendConfirmationEmail}. **Require a valid session:** {@link logout},
21
+ * {@link logoutAllDevices}, and {@link changePassword}, which otherwise throw
22
+ * {@link CrowdyGraphQLError} with `UNAUTHENTICATED` when the bearer token is
23
+ * missing, expired, or revoked.
10
24
  */
11
- import { ChangePasswordDocument, ConfirmEmailDocument, LoginDocument, LogoutAllDevicesDocument, LogoutDocument, RegisterDocument, RequestPasswordResetDocument, ResendConfirmationEmailDocument, ResetPasswordDocument, } from '../generated/graphql.js';
12
25
  export class AuthAPI {
13
26
  constructor(graphql, session) {
14
27
  this.graphql = graphql;
15
28
  this.session = session;
16
29
  }
17
30
  /**
18
- * Log in and persist the resulting `game_tokens` bearer token via the
19
- * shared `AuthState`. All subsequent SDK calls (game-api or
20
- * management-api) include it automatically.
31
+ * Authenticate with email + password and start a new session. **Public** no
32
+ * existing session required.
33
+ *
34
+ * On success the returned `token` is minted **and** stored on the shared
35
+ * session state, so subsequent calls on any sub-client (management-api or
36
+ * game-api) carry it automatically — no need to call {@link setToken}.
37
+ *
38
+ * @param input - Credentials ({@link LoginUserInput}): `email` and `password`
39
+ * (min 8 characters).
40
+ * @returns An {@link AuthResponse}: the opaque session `token` (sent as
41
+ * `Authorization: Bearer <token>`), `gameTokenId` (the session row id, a
42
+ * string), and the authenticated `user`.
43
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` on invalid credentials, or
44
+ * `BAD_USER_INPUT` on malformed input.
45
+ * @example
46
+ * ```ts
47
+ * const { user } = await client.auth.login({ email, password });
48
+ * // the session token is now stored; later calls are authenticated for you
49
+ * await client.users.me();
50
+ * ```
21
51
  */
22
52
  async login(input) {
23
53
  const data = await this.graphql.request(LoginDocument, { input });
@@ -26,7 +56,21 @@ export class AuthAPI {
26
56
  }
27
57
  return data.login;
28
58
  }
29
- /** Register a new user. Same token-persistence behaviour as `login`. */
59
+ /**
60
+ * Create a new (initially unconfirmed) account, send a confirmation email, and
61
+ * return a session for immediate login. **Public** — no existing session
62
+ * required. Same token-persistence behaviour as {@link login}: the new `token`
63
+ * is stored on the shared session state automatically.
64
+ *
65
+ * @param input - New-account details ({@link RegisterUserInput}): `email`
66
+ * (where the confirmation email is sent), `password` (min 8 characters), and
67
+ * an optional initial `gamertag` (min 3 characters; can also be set later via
68
+ * `client.users.updateGamertag`).
69
+ * @returns An {@link AuthResponse} (session `token`, `gameTokenId`, and the new
70
+ * `user`).
71
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` if the email already exists or
72
+ * the input is invalid.
73
+ */
30
74
  async register(input) {
31
75
  const data = await this.graphql.request(RegisterDocument, { input });
32
76
  if (data.register?.token) {
@@ -35,41 +79,106 @@ export class AuthAPI {
35
79
  return data.register;
36
80
  }
37
81
  /**
38
- * Single-device logout. Clears the in-memory token after a successful
39
- * server-side revoke so other sub-clients don't keep using it.
82
+ * Single-device logout: revoke the `game_tokens` row that authenticated this
83
+ * request; other devices/tokens are unaffected. After a successful server-side
84
+ * revoke the in-memory token is cleared from the shared session state so the
85
+ * other sub-clients stop using it. Requires a valid session.
86
+ *
87
+ * @returns `true` if a token was revoked, or `false` if the request carried no
88
+ * game token.
89
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` if the session is invalid.
40
90
  */
41
91
  async logout() {
42
92
  const data = await this.graphql.request(LogoutDocument);
43
93
  this.session.setToken(null);
44
94
  return data.logout;
45
95
  }
46
- /** Revoke every `game_tokens` row for the current user. */
96
+ /**
97
+ * Revoke **every** active session for the authenticated user (deletes all
98
+ * their `game_tokens` rows and records revocations). Requires a valid session;
99
+ * use {@link logout} to end only the current one.
100
+ *
101
+ * Note: unlike {@link logout}, this does not clear the SDK's in-memory token —
102
+ * call {@link setToken}`(null)` afterwards if you also want to drop it locally.
103
+ *
104
+ * @returns `true` on success.
105
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` if the session is invalid.
106
+ */
47
107
  async logoutAllDevices() {
48
108
  const data = await this.graphql.request(LogoutAllDevicesDocument);
49
109
  return data.logoutAllDevices;
50
110
  }
111
+ /**
112
+ * Confirm a user's email address using the token from the confirmation email.
113
+ * **Public** — the token itself authorizes the call.
114
+ *
115
+ * @param token - The confirmation token from the emailed link.
116
+ * @returns `true` on success, or `false` if the token is invalid or expired.
117
+ * @throws {CrowdyGraphQLError} on transport/validation failures (invalid or
118
+ * expired tokens resolve to `false` rather than throwing).
119
+ */
51
120
  async confirmEmail(token) {
52
121
  const data = await this.graphql.request(ConfirmEmailDocument, { token });
53
122
  return data.confirmEmail;
54
123
  }
124
+ /**
125
+ * Start the password-reset flow by emailing a reset link to the address.
126
+ * **Public**. Always returns `true` regardless of whether the email exists or
127
+ * is confirmed, to prevent account enumeration.
128
+ *
129
+ * @param email - Email address to send the password-reset link to.
130
+ * @returns `true` (always, even when no such account exists).
131
+ * @throws {CrowdyGraphQLError} on transport/validation failures.
132
+ */
55
133
  async requestPasswordReset(email) {
56
134
  const data = await this.graphql.request(RequestPasswordResetDocument, {
57
135
  email,
58
136
  });
59
137
  return data.requestPasswordReset;
60
138
  }
139
+ /**
140
+ * Complete a password reset using the reset token and a new password.
141
+ * **Public** — the reset token authorizes the call. Existing sessions are
142
+ * **not** revoked.
143
+ *
144
+ * @param input - {@link ResetPasswordInput}: the `token` from the emailed reset
145
+ * link and the `newPassword` to set (min 8 characters).
146
+ * @returns `true` on success.
147
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` if the token is invalid or
148
+ * expired.
149
+ */
61
150
  async resetPassword(input) {
62
151
  const data = await this.graphql.request(ResetPasswordDocument, {
63
152
  input,
64
153
  });
65
154
  return data.resetPassword;
66
155
  }
156
+ /**
157
+ * Re-send the email-confirmation link. **Public**. Always returns `true`
158
+ * regardless of whether the account exists or is already confirmed (prevents
159
+ * enumeration); the email is only actually sent for existing unconfirmed
160
+ * accounts.
161
+ *
162
+ * @param email - Email address of the account to re-send confirmation to.
163
+ * @returns `true` (always).
164
+ * @throws {CrowdyGraphQLError} on transport/validation failures.
165
+ */
67
166
  async resendConfirmationEmail(email) {
68
167
  const data = await this.graphql.request(ResendConfirmationEmailDocument, {
69
168
  email,
70
169
  });
71
170
  return data.resendConfirmationEmail;
72
171
  }
172
+ /**
173
+ * Change the authenticated user's password after verifying the current one.
174
+ * Requires a valid session. Existing sessions are **not** revoked.
175
+ *
176
+ * @param currentPassword - The user's current password, for verification.
177
+ * @param newPassword - The new password to set (min 8 characters).
178
+ * @returns `true` on success.
179
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` without a valid session, or
180
+ * `BAD_USER_INPUT` if the current password is wrong.
181
+ */
73
182
  async changePassword(currentPassword, newPassword) {
74
183
  const data = await this.graphql.request(ChangePasswordDocument, {
75
184
  currentPassword,
@@ -77,11 +186,22 @@ export class AuthAPI {
77
186
  });
78
187
  return data.changePassword;
79
188
  }
80
- /** Imperatively replace the in-memory bearer token (e.g. on rehydrate). */
189
+ /**
190
+ * Imperatively replace the in-memory bearer token on the shared session state
191
+ * (e.g. to rehydrate a token persisted to disk). Affects every sub-client.
192
+ * Local only — performs no network call. Pass `null` to clear it.
193
+ *
194
+ * @param token - The bearer token to use, or `null` to clear the session.
195
+ */
81
196
  setToken(token) {
82
197
  this.session.setToken(token);
83
198
  }
84
- /** Read the current bearer token. */
199
+ /**
200
+ * Read the current in-memory bearer token from the shared session state. Local
201
+ * only — performs no network call.
202
+ *
203
+ * @returns The current bearer token, or `null` if none is set.
204
+ */
85
205
  getToken() {
86
206
  return this.session.getToken();
87
207
  }
@@ -1,34 +1,293 @@
1
1
  import type { GraphQLClient } from '../client.js';
2
2
  import { type MyChannelsQuery, type MyChannelsQueryVariables, type ChannelsQuery, type ChannelsQueryVariables, type ChannelQuery, type ChannelQueryVariables, type ChannelMembersQuery, type ChannelMembersQueryVariables, type ChannelRolesQuery, type ChannelRolesQueryVariables, type ChannelPolicyQuery, type ChannelPolicyQueryVariables, type SetChannelPolicyMutation, type SetChannelPolicyMutationVariables, type CreateChannelMutation, type CreateChannelMutationVariables, type UpdateChannelMutation, type UpdateChannelMutationVariables, type DeleteChannelMutationVariables, type JoinChannelMutation, type JoinChannelMutationVariables, type RequestToJoinChannelMutation, type RequestToJoinChannelMutationVariables, type LeaveChannelMutationVariables, type AddChannelMemberMutation, type AddChannelMemberMutationVariables, type RemoveChannelMemberMutationVariables, type SetChannelMemberRolesMutation, type SetChannelMemberRolesMutationVariables, type CreateChannelRoleMutation, type CreateChannelRoleMutationVariables, type UpdateChannelRoleMutation, type UpdateChannelRoleMutationVariables, type DeleteChannelRoleMutationVariables } from '../generated/graphql.js';
3
3
  /**
4
- * Channels: app-scoped player groups with role-gated messaging, built on the
5
- * same generic groups subsystem as Teams (group_type='channel'). Channel
6
- * CRUD/membership runs over the game-api GraphQL endpoint; publishing and
7
- * receiving channel messages happens over the realtime UDP path (`client.udp`).
4
+ * Channels: app-scoped, location-independent pub/sub messaging groups on the
5
+ * **game-api**. Exposed as `client.channels`.
8
6
  *
9
- * Exposed as `client.channels`.
7
+ * A channel is a named subscriber set with role-gated messaging, built on the
8
+ * same generic groups subsystem as Teams (`group_type='channel'`). The methods
9
+ * here manage a channel's lifecycle and configuration — creating channels,
10
+ * listing/fetching them, managing membership (join/leave/add/remove), roles,
11
+ * and the per-app channel policy — all over the game-api GraphQL endpoint.
12
+ *
13
+ * Realtime message delivery is a **separate** path: publish to a channel with
14
+ * `client.udp.sendChannelMessage(...)` over UDP. That call requires the
15
+ * channel's `send_messages` permission and fans the payload out to every
16
+ * active member (as a `ChannelMessageNotification` on `client.udp`
17
+ * notifications) rather than chunk-routing it. The methods on this class never
18
+ * carry message payloads — they only manage who belongs to a channel and what
19
+ * each member may do.
20
+ *
21
+ * `BigInt` ids (`appId`, `groupId`, `userId`, `groupRoleId`) are sent and
22
+ * received as decimal strings.
23
+ *
24
+ * Every method requires an authenticated session (a Bearer token set via
25
+ * `client.auth.login()` or `client.setToken()`) and the caller must be
26
+ * entitled to the target app; membership/role/policy mutations additionally
27
+ * require a specific channel permission (e.g. `manage_group`, `manage_members`,
28
+ * `manage_roles`) or app-admin (`manage_apps`). Failures throw
29
+ * {@link CrowdyGraphQLError} carrying a stable `extensions.code` such as
30
+ * `UNAUTHENTICATED`, `SCOPE_MISSING`, or `FORBIDDEN`.
10
31
  */
11
32
  export declare class ChannelsAPI {
12
33
  private gql;
13
34
  constructor(gql: GraphQLClient);
35
+ /**
36
+ * List the caller's own channels in an app, each with the caller's roles and
37
+ * effective channel permissions (e.g. whether they hold `send_messages`). Use
38
+ * this to discover which channels the current user can read and post in.
39
+ *
40
+ * @param appId - The app (tenant) to list the caller's channels within, as a
41
+ * decimal `BigInt` string.
42
+ * @returns One {@link GroupMembership} per channel the caller belongs to
43
+ * (the channel {@link Group}, the caller's {@link GroupRole}s, their
44
+ * effective permission keys, and the join time).
45
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` if there is no valid token,
46
+ * or `SCOPE_MISSING` / `FORBIDDEN` if the caller isn't entitled to the app.
47
+ */
14
48
  mine(appId: MyChannelsQueryVariables['appId']): Promise<MyChannelsQuery['myChannels']>;
49
+ /**
50
+ * List all active channels in an app — not just the caller's. Use
51
+ * {@link mine} instead when you only want the channels the caller belongs to.
52
+ *
53
+ * @param appId - The app (tenant) whose channels to list, as a decimal
54
+ * `BigInt` string.
55
+ * @returns Every active channel in the app as {@link Group} records.
56
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`, or `SCOPE_MISSING` /
57
+ * `FORBIDDEN` if the caller isn't entitled to the app.
58
+ */
15
59
  list(appId: ChannelsQueryVariables['appId']): Promise<ChannelsQuery['channels']>;
60
+ /**
61
+ * Fetch a single channel by its group id.
62
+ *
63
+ * @param groupId - The channel's group id, as a decimal `BigInt` string.
64
+ * @returns The channel as a {@link Group}.
65
+ * @throws {CrowdyGraphQLError} if the id does not resolve to a channel (e.g.
66
+ * it is a team, or does not exist), or `UNAUTHENTICATED` / `FORBIDDEN` if
67
+ * the caller isn't entitled to the app.
68
+ */
16
69
  get(groupId: ChannelQueryVariables['groupId']): Promise<ChannelQuery['channel']>;
70
+ /**
71
+ * List a channel's members — its subscriber set, including pending join
72
+ * requests — each with their membership status and roles.
73
+ *
74
+ * @param groupId - The channel whose members to list, as a decimal `BigInt`
75
+ * string.
76
+ * @returns The channel's members as {@link GroupMember} records.
77
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `FORBIDDEN` if the caller
78
+ * isn't entitled to the channel's app.
79
+ */
17
80
  members(groupId: ChannelMembersQueryVariables['groupId']): Promise<ChannelMembersQuery['channelMembers']>;
81
+ /**
82
+ * List a channel's roles, including the system `leader` role and any default
83
+ * `member` role (which typically grants `send_messages`).
84
+ *
85
+ * @param groupId - The channel whose roles to list, as a decimal `BigInt`
86
+ * string.
87
+ * @returns The channel's roles as {@link GroupRole} records, each with its
88
+ * granted permission keys.
89
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `FORBIDDEN` if the caller
90
+ * isn't entitled to the channel's app.
91
+ */
18
92
  roles(groupId: ChannelRolesQueryVariables['groupId']): Promise<ChannelRolesQuery['channelRoles']>;
93
+ /**
94
+ * Read an app's current channel policy: who may create channels and the
95
+ * default membership policy applied to new channels. Falls back to app
96
+ * defaults when unset.
97
+ *
98
+ * @param appId - The app (tenant) whose channel policy to read, as a decimal
99
+ * `BigInt` string.
100
+ * @returns The effective {@link AppGroupPolicy} for channels in the app
101
+ * (creation policy, default membership policy, and any member/group caps).
102
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED` / `FORBIDDEN` if the caller
103
+ * isn't entitled to the app.
104
+ */
19
105
  policy(appId: ChannelPolicyQueryVariables['appId']): Promise<ChannelPolicyQuery['channelPolicy']>;
106
+ /**
107
+ * Create a channel in an app. Whether the caller may create one is governed
108
+ * by the per-app channel creation policy (`admin` | `member` | `anyone`).
109
+ * The caller becomes the owner with a system `leader` role. When
110
+ * `input.membersCanSend` is true (the default) a default `member` role
111
+ * granting `send_messages` is created and auto-assigned to joiners (an open
112
+ * chat channel); when false, only roles you explicitly grant may post (an
113
+ * announce / read-only channel).
114
+ *
115
+ * @param input - {@link CreateChannelInput}: the owning `appId`, the channel
116
+ * `name` (max 128 chars, unique per app + type), and optional
117
+ * `description`, `membershipPolicy` (`open` | `request` | `invite` |
118
+ * `admin`; defaults to the app policy), and `membersCanSend` flag.
119
+ * @returns The newly created channel as a {@link Group}.
120
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` (e.g. name too long or a
121
+ * duplicate name), `FORBIDDEN` if the channel policy disallows creation, or
122
+ * `UNAUTHENTICATED`.
123
+ */
20
124
  create(input: CreateChannelMutationVariables['input']): Promise<CreateChannelMutation['createChannel']>;
125
+ /**
126
+ * Update a channel's name, description, and/or membership policy. Only the
127
+ * fields present on `input` change; omitted fields are left as-is. Requires
128
+ * the `manage_group` channel permission (app admins bypass).
129
+ *
130
+ * @param input - {@link UpdateChannelInput}: the `groupId` plus the fields to
131
+ * change — `name` (max 128 chars), `description`, and/or `membershipPolicy`
132
+ * (`open` | `request` | `invite` | `admin`).
133
+ * @returns The updated channel as a {@link Group}.
134
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
135
+ * lacks `manage_group`, `BAD_USER_INPUT` on a validation failure, or
136
+ * `UNAUTHENTICATED`.
137
+ */
21
138
  update(input: UpdateChannelMutationVariables['input']): Promise<UpdateChannelMutation['updateChannel']>;
139
+ /**
140
+ * Delete a channel. Requires the `manage_group` channel permission (app
141
+ * admins bypass). **Destructive**: cascades to the channel's members and
142
+ * roles and notifies Buddy servers to tear down message routing for the
143
+ * channel.
144
+ *
145
+ * @param groupId - The channel to delete, as a decimal `BigInt` string.
146
+ * @returns `true` on success.
147
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
148
+ * lacks `manage_group`, or `UNAUTHENTICATED`.
149
+ */
22
150
  remove(groupId: DeleteChannelMutationVariables['groupId']): Promise<boolean>;
151
+ /**
152
+ * Set who may create channels in an app and the default membership policy
153
+ * for new channels. Requires app-admin (`manage_apps`). Affects future
154
+ * channel creation only — existing channels are unchanged.
155
+ *
156
+ * @param input - {@link SetChannelPolicyInput}: the `appId`, the
157
+ * `creationPolicy` (`admin` | `member` | `anyone`), the
158
+ * `defaultMembershipPolicy` (`open` | `request` | `invite` | `admin`), and
159
+ * optional `maxMembers` / `maxGroupsPerUser` caps (`null` = unlimited).
160
+ * @returns The updated {@link AppGroupPolicy}.
161
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
162
+ * isn't app-admin, `BAD_USER_INPUT` on an invalid policy value, or
163
+ * `UNAUTHENTICATED`.
164
+ */
23
165
  setPolicy(input: SetChannelPolicyMutationVariables['input']): Promise<SetChannelPolicyMutation['setChannelPolicy']>;
166
+ /**
167
+ * Join a channel as the caller (subscribe to it). Honors the channel's
168
+ * membership policy: `open` → active immediately; `request` → pending until
169
+ * a manager approves; `invite` / `admin` → rejected. On becoming active,
170
+ * Buddy is notified with the caller's effective send permission so message
171
+ * routing starts.
172
+ *
173
+ * @param groupId - The channel to join, as a decimal `BigInt` string.
174
+ * @returns The caller's {@link GroupMember} record; its `status` reflects
175
+ * `active` vs. `pending`.
176
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` if the membership policy rejects
177
+ * the join, or `UNAUTHENTICATED`.
178
+ */
24
179
  join(groupId: JoinChannelMutationVariables['groupId']): Promise<JoinChannelMutation['joinChannel']>;
180
+ /**
181
+ * Request to join a request-only channel, creating a pending membership a
182
+ * manager can later approve via {@link addMember}. Behaves identically to
183
+ * {@link join}; it exists as a clearer name for request-policy UIs.
184
+ *
185
+ * @param groupId - The request-only channel to request to join, as a decimal
186
+ * `BigInt` string.
187
+ * @returns The caller's pending {@link GroupMember} record.
188
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` if the membership policy rejects
189
+ * the request, or `UNAUTHENTICATED`.
190
+ */
25
191
  requestToJoin(groupId: RequestToJoinChannelMutationVariables['groupId']): Promise<RequestToJoinChannelMutation['requestToJoinChannel']>;
192
+ /**
193
+ * Leave a channel (unsubscribe the caller). Notifies Buddy to stop routing
194
+ * messages to the caller.
195
+ *
196
+ * @param groupId - The channel to leave, as a decimal `BigInt` string.
197
+ * @returns `true` if a membership was removed (`false` if the caller wasn't
198
+ * a member).
199
+ * @throws {CrowdyGraphQLError} `UNAUTHENTICATED`.
200
+ */
26
201
  leave(groupId: LeaveChannelMutationVariables['groupId']): Promise<boolean>;
202
+ /**
203
+ * Add a user to a channel, or approve their pending join request (upserts
204
+ * the membership to `active`). Requires the `manage_members` channel
205
+ * permission (app admins bypass). Auto-assigns the channel's default role if
206
+ * configured and notifies Buddy with the member's effective send permission.
207
+ *
208
+ * @param groupId - The channel to add the user to, as a decimal `BigInt`
209
+ * string.
210
+ * @param userId - The user to add or approve, as a decimal `BigInt` string.
211
+ * @returns The added/approved {@link GroupMember} record.
212
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
213
+ * lacks `manage_members`, or `UNAUTHENTICATED`.
214
+ */
27
215
  addMember(groupId: AddChannelMemberMutationVariables['groupId'], userId: AddChannelMemberMutationVariables['userId']): Promise<AddChannelMemberMutation['addChannelMember']>;
216
+ /**
217
+ * Remove a member from a channel. Requires the `manage_members` channel
218
+ * permission, except that any member may remove themselves (pass their own
219
+ * `userId`). Notifies Buddy to stop routing messages to the removed member.
220
+ *
221
+ * @param groupId - The channel to remove the user from, as a decimal
222
+ * `BigInt` string.
223
+ * @param userId - The user to remove; may be the caller's own id to
224
+ * self-remove. Decimal `BigInt` string.
225
+ * @returns `true` if a membership was removed.
226
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` when removing
227
+ * another member without `manage_members`, or `UNAUTHENTICATED`.
228
+ */
28
229
  removeMember(groupId: RemoveChannelMemberMutationVariables['groupId'], userId: RemoveChannelMemberMutationVariables['userId']): Promise<boolean>;
230
+ /**
231
+ * Replace a member's channel roles with the given set. This is **not
232
+ * additive** — roles not listed are removed. Requires the `manage_roles`
233
+ * channel permission (app admins bypass). Re-pushes the member's effective
234
+ * send permission to Buddy so their ability to post updates immediately.
235
+ *
236
+ * @param input - {@link SetMemberRolesInput}: the `groupId`, the target
237
+ * `userId`, and `roleIds` — the complete set of channel role ids the member
238
+ * should have (ids that are unknown or belong to another group are
239
+ * ignored).
240
+ * @returns The updated {@link GroupMember} record with its new roles.
241
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
242
+ * lacks `manage_roles`, or `UNAUTHENTICATED`.
243
+ */
29
244
  setMemberRoles(input: SetChannelMemberRolesMutationVariables['input']): Promise<SetChannelMemberRolesMutation['setChannelMemberRoles']>;
245
+ /**
246
+ * Create a custom (non-system) channel role granting the given channel
247
+ * permission keys (e.g. `send_messages` for posting rights). Requires the
248
+ * `manage_roles` channel permission (app admins bypass).
249
+ *
250
+ * @param input - {@link CreateGroupRoleInput}: the `groupId`, the `roleName`
251
+ * (max 128 chars, unique within the channel), the `permissions` keys to
252
+ * grant (e.g. `send_messages`, `manage_members`; each max 64 chars,
253
+ * defaults to none), and an optional `rank` (higher = more senior;
254
+ * defaults to 0).
255
+ * @returns The created {@link GroupRole}.
256
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` on an invalid/duplicate name
257
+ * or unknown permission key, `FORBIDDEN` / `SCOPE_MISSING` if the caller
258
+ * lacks `manage_roles`, or `UNAUTHENTICATED`.
259
+ */
30
260
  createRole(input: CreateChannelRoleMutationVariables['input']): Promise<CreateChannelRoleMutation['createChannelRole']>;
261
+ /**
262
+ * Update a channel role's name, rank, and/or permission keys (system roles
263
+ * cannot be renamed or re-ranked). When `input.permissions` is supplied it
264
+ * **replaces** the role's existing keys. Requires the `manage_roles` channel
265
+ * permission (app admins bypass).
266
+ *
267
+ * Note: changing `send_messages` here does not re-push to Buddy until each
268
+ * affected member's roles are re-applied via {@link setMemberRoles}.
269
+ *
270
+ * @param input - {@link UpdateGroupRoleInput}: the `groupRoleId` plus the
271
+ * fields to change (`roleName`, `permissions`, `rank`); omitted fields are
272
+ * left unchanged.
273
+ * @returns The updated {@link GroupRole}.
274
+ * @throws {CrowdyGraphQLError} `BAD_USER_INPUT` on a validation failure,
275
+ * `FORBIDDEN` / `SCOPE_MISSING` if the caller lacks `manage_roles`, or
276
+ * `UNAUTHENTICATED`.
277
+ */
31
278
  updateRole(input: UpdateChannelRoleMutationVariables['input']): Promise<UpdateChannelRoleMutation['updateChannelRole']>;
279
+ /**
280
+ * Delete a non-system channel role. Requires the `manage_roles` channel
281
+ * permission (app admins bypass). The system `leader` role cannot be
282
+ * deleted. **Destructive**: removes the role from any members that held it.
283
+ *
284
+ * @param groupRoleId - The channel role to delete (must be a non-system
285
+ * role), as a decimal `BigInt` string.
286
+ * @returns `true` if a role was deleted.
287
+ * @throws {CrowdyGraphQLError} `FORBIDDEN` / `SCOPE_MISSING` if the caller
288
+ * lacks `manage_roles`, `BAD_USER_INPUT` if targeting a system role, or
289
+ * `UNAUTHENTICATED`.
290
+ */
32
291
  deleteRole(groupRoleId: DeleteChannelRoleMutationVariables['groupRoleId']): Promise<boolean>;
33
292
  }
34
293
  //# sourceMappingURL=channels.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/domains/channels.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/domains/channels.ts"],"names":[],"mappings":"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"}