@doist/comms-cli 1.0.0 → 1.2.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.
- package/CHANGELOG.md +12 -0
- package/dist/commands/channel/add.d.ts +3 -0
- package/dist/commands/channel/add.d.ts.map +1 -0
- package/dist/commands/channel/add.js +5 -0
- package/dist/commands/channel/add.js.map +1 -0
- package/dist/commands/channel/archive.d.ts +8 -0
- package/dist/commands/channel/archive.d.ts.map +1 -0
- package/dist/commands/channel/archive.js +37 -0
- package/dist/commands/channel/archive.js.map +1 -0
- package/dist/commands/channel/delete.d.ts +8 -0
- package/dist/commands/channel/delete.d.ts.map +1 -0
- package/dist/commands/channel/delete.js +42 -0
- package/dist/commands/channel/delete.js.map +1 -0
- package/dist/commands/channel/helpers.d.ts +8 -0
- package/dist/commands/channel/helpers.d.ts.map +1 -1
- package/dist/commands/channel/helpers.js +19 -2
- package/dist/commands/channel/helpers.js.map +1 -1
- package/dist/commands/channel/index.d.ts.map +1 -1
- package/dist/commands/channel/index.js +125 -1
- package/dist/commands/channel/index.js.map +1 -1
- package/dist/commands/channel/members.d.ts +5 -0
- package/dist/commands/channel/members.d.ts.map +1 -0
- package/dist/commands/channel/members.js +57 -0
- package/dist/commands/channel/members.js.map +1 -0
- package/dist/commands/channel/membership-helpers.d.ts +20 -0
- package/dist/commands/channel/membership-helpers.d.ts.map +1 -0
- package/dist/commands/channel/membership-helpers.js +125 -0
- package/dist/commands/channel/membership-helpers.js.map +1 -0
- package/dist/commands/channel/remove.d.ts +3 -0
- package/dist/commands/channel/remove.d.ts.map +1 -0
- package/dist/commands/channel/remove.js +5 -0
- package/dist/commands/channel/remove.js.map +1 -0
- package/dist/commands/channel/set.d.ts +7 -0
- package/dist/commands/channel/set.d.ts.map +1 -0
- package/dist/commands/channel/set.js +79 -0
- package/dist/commands/channel/set.js.map +1 -0
- package/dist/lib/api.d.ts +2 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +12 -0
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/auth-provider.d.ts.map +1 -1
- package/dist/lib/auth-provider.js +2 -0
- package/dist/lib/auth-provider.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/refs.d.ts +20 -0
- package/dist/lib/refs.d.ts.map +1 -1
- package/dist/lib/refs.js +90 -0
- package/dist/lib/refs.js.map +1 -1
- package/dist/lib/skills/content.d.ts +1 -1
- package/dist/lib/skills/content.d.ts.map +1 -1
- package/dist/lib/skills/content.js +13 -0
- package/dist/lib/skills/content.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [1.2.0](https://github.com/Doist/comms-cli/compare/v1.1.0...v1.2.0) (2026-05-27)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
- **channel:** add delete, archive, unarchive subcommands ([#8](https://github.com/Doist/comms-cli/issues/8)) ([41acfe6](https://github.com/Doist/comms-cli/commit/41acfe6cf5022bb719b9dd4b8d406ce730926867)), closes [#246](https://github.com/Doist/comms-cli/issues/246)
|
|
6
|
+
|
|
7
|
+
## [1.1.0](https://github.com/Doist/comms-cli/compare/v1.0.0...v1.1.0) (2026-05-27)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- **channel:** channel membership control (members list/add/remove/set) ([#7](https://github.com/Doist/comms-cli/issues/7)) ([2a1e473](https://github.com/Doist/comms-cli/commit/2a1e473fb356fc44ae6bb7fb48f2465a85caad76)), closes [Doist/twist-cli#244](https://github.com/Doist/twist-cli/issues/244)
|
|
12
|
+
|
|
1
13
|
## 1.0.0 (2026-05-25)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAA2B,MAAM,yBAAyB,CAAA;AAE9F,wBAAsB,iBAAiB,CACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,sBAAsB,GAChC,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/commands/channel/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAE9F,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACnC,UAAkB,EAClB,IAAc,EACd,OAA+B;IAE/B,OAAO,uBAAuB,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;AACpE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MutationOptions } from '../../lib/options.js';
|
|
2
|
+
type ArchiveChannelOptions = MutationOptions & {
|
|
3
|
+
workspace?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function archiveChannel(ref: string, options: ArchiveChannelOptions): Promise<void>;
|
|
6
|
+
export declare function unarchiveChannel(ref: string, options: ArchiveChannelOptions): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/archive.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAI3D,KAAK,qBAAqB,GAAG,eAAe,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAqCrE,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/F;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { getCommsClient } from '../../lib/api.js';
|
|
2
|
+
import { formatJson, printDryRun } from '../../lib/output.js';
|
|
3
|
+
import { resolveChannelByRef } from './helpers.js';
|
|
4
|
+
async function setArchiveState(ref, options, archive) {
|
|
5
|
+
const action = archive ? 'archive' : 'unarchive';
|
|
6
|
+
const channel = await resolveChannelByRef(ref, options.workspace);
|
|
7
|
+
if (options.dryRun) {
|
|
8
|
+
printDryRun(`${action} channel`, {
|
|
9
|
+
Channel: `${channel.name} (id:${channel.id})`,
|
|
10
|
+
'Currently archived': channel.archived ? 'yes' : 'no',
|
|
11
|
+
});
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (channel.archived !== archive) {
|
|
15
|
+
const client = await getCommsClient();
|
|
16
|
+
if (archive) {
|
|
17
|
+
await client.channels.archiveChannel(channel.id);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
await client.channels.unarchiveChannel(channel.id);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (options.json) {
|
|
24
|
+
console.log(formatJson({ id: channel.id, archived: archive }));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const verb = archive ? 'archived' : 'unarchived';
|
|
28
|
+
const noop = channel.archived === archive ? ' (already in target state)' : '';
|
|
29
|
+
console.log(`Channel "${channel.name}" (id:${channel.id}) ${verb}${noop}.`);
|
|
30
|
+
}
|
|
31
|
+
export async function archiveChannel(ref, options) {
|
|
32
|
+
await setArchiveState(ref, options, true);
|
|
33
|
+
}
|
|
34
|
+
export async function unarchiveChannel(ref, options) {
|
|
35
|
+
await setArchiveState(ref, options, false);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../../src/commands/channel/archive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIlD,KAAK,UAAU,eAAe,CAC1B,GAAW,EACX,OAA8B,EAC9B,OAAgB;IAEhB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAA;IAChD,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAEjE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,WAAW,CAAC,GAAG,MAAM,UAAU,EAAE;YAC7B,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,GAAG;YAC7C,oBAAoB,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;SACxD,CAAC,CAAA;QACF,OAAM;IACV,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAA;QACrC,IAAI,OAAO,EAAE,CAAC;YACV,MAAM,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpD,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACtD,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QAC9D,OAAM;IACV,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAA;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7E,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,KAAK,IAAI,GAAG,IAAI,GAAG,CAAC,CAAA;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,OAA8B;IAC5E,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,OAA8B;IAC9E,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MutationOptions } from '../../lib/options.js';
|
|
2
|
+
type DeleteChannelOptions = MutationOptions & {
|
|
3
|
+
yes?: boolean;
|
|
4
|
+
workspace?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function deleteChannel(ref: string, options: DeleteChannelOptions): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/delete.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAI3D,KAAK,oBAAoB,GAAG,eAAe,GAAG;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnF,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8C7F"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CommsRequestError } from '@doist/comms-sdk';
|
|
2
|
+
import { getCommsClient } from '../../lib/api.js';
|
|
3
|
+
import { CliError } from '../../lib/errors.js';
|
|
4
|
+
import { formatJson, printDryRun } from '../../lib/output.js';
|
|
5
|
+
import { resolveChannelByRef } from './helpers.js';
|
|
6
|
+
export async function deleteChannel(ref, options) {
|
|
7
|
+
if (!options.yes && !options.dryRun) {
|
|
8
|
+
if (options.json) {
|
|
9
|
+
throw new CliError('MISSING_YES_FLAG', '--yes is required to execute deletion in --json mode.');
|
|
10
|
+
}
|
|
11
|
+
console.log(`Would delete: ${ref}`);
|
|
12
|
+
console.log('Use --yes to confirm.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const channel = await resolveChannelByRef(ref, options.workspace);
|
|
16
|
+
if (options.dryRun) {
|
|
17
|
+
printDryRun('delete channel', {
|
|
18
|
+
Channel: `${channel.name} (id:${channel.id})`,
|
|
19
|
+
Visibility: channel.public ? 'public' : 'private',
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const client = await getCommsClient();
|
|
24
|
+
try {
|
|
25
|
+
await client.channels.deleteChannel(channel.id);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof CommsRequestError && error.httpStatusCode === 403) {
|
|
29
|
+
throw new CliError('FORBIDDEN', `Comms refused to delete "${channel.name}" (id:${channel.id}): 403 Forbidden.`, [
|
|
30
|
+
'Channel deletion is typically restricted to workspace admins',
|
|
31
|
+
'Ask a workspace admin to delete it, or use the Comms web UI',
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
if (options.json) {
|
|
37
|
+
console.log(formatJson({ id: channel.id, deleted: true }));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(`Channel "${channel.name}" (id:${channel.id}) deleted.`);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/commands/channel/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIlD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,OAA6B;IAC1E,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,QAAQ,CACd,kBAAkB,EAClB,uDAAuD,CAC1D,CAAA;QACL,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAA;QACnC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;QACpC,OAAM;IACV,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;IAEjE,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,WAAW,CAAC,gBAAgB,EAAE;YAC1B,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,EAAE,GAAG;YAC7C,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;SACpD,CAAC,CAAA;QACF,OAAM;IACV,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAA;IACrC,IAAI,CAAC;QACD,MAAM,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,IAAI,KAAK,YAAY,iBAAiB,IAAI,KAAK,CAAC,cAAc,KAAK,GAAG,EAAE,CAAC;YACrE,MAAM,IAAI,QAAQ,CACd,WAAW,EACX,4BAA4B,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,mBAAmB,EAC9E;gBACI,8DAA8D;gBAC9D,6DAA6D;aAChE,CACJ,CAAA;QACL,CAAC;QACD,MAAM,KAAK,CAAA;IACf,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC1D,OAAM;IACV,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,IAAI,SAAS,OAAO,CAAC,EAAE,YAAY,CAAC,CAAA;AACxE,CAAC"}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import type { Channel } from '@doist/comms-sdk';
|
|
1
2
|
export declare function validateChannelName(name: string): void;
|
|
2
3
|
export declare function resolveVisibilityOption(options: {
|
|
3
4
|
public?: boolean;
|
|
4
5
|
private?: boolean;
|
|
5
6
|
}): boolean | undefined;
|
|
6
7
|
export declare function resolveChannelWorkspaceId(workspaceRef: string | undefined): Promise<number>;
|
|
8
|
+
/**
|
|
9
|
+
* Resolve a channel for a mutation. Direct refs (`id:` or URL) are fetched by
|
|
10
|
+
* ID via `getChannel`, which is workspace-agnostic — so a channel in another
|
|
11
|
+
* workspace resolves without a `--workspace` flag. Name refs still need a
|
|
12
|
+
* workspace to disambiguate. An explicit `--workspace` forces the name path.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveChannelByRef(ref: string, workspaceRef: string | undefined): Promise<Channel>;
|
|
7
15
|
export declare function encodeCursor(offset: number): string;
|
|
8
16
|
export declare function decodeCursor(cursor: string | undefined): number;
|
|
9
17
|
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAW/C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQtD;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB,GAAG,OAAO,GAAG,SAAS,CAQtB;AAED,wBAAsB,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAMjG;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACrC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAqB/D"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getCurrentWorkspaceId } from '../../lib/api.js';
|
|
1
|
+
import { getCommsClient, getCurrentWorkspaceId } from '../../lib/api.js';
|
|
2
2
|
import { CliError } from '../../lib/errors.js';
|
|
3
|
-
import { parseRef, resolveWorkspaceRef } from '../../lib/refs.js';
|
|
3
|
+
import { getDirectChannelId, parseRef, resolveChannelRef, resolveWorkspaceRef, } from '../../lib/refs.js';
|
|
4
4
|
import { validateNonEmptyName } from '../../lib/validation.js';
|
|
5
5
|
export function validateChannelName(name) {
|
|
6
6
|
validateNonEmptyName(name, 'Channel');
|
|
@@ -26,6 +26,23 @@ export async function resolveChannelWorkspaceId(workspaceRef) {
|
|
|
26
26
|
}
|
|
27
27
|
return getCurrentWorkspaceId();
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolve a channel for a mutation. Direct refs (`id:` or URL) are fetched by
|
|
31
|
+
* ID via `getChannel`, which is workspace-agnostic — so a channel in another
|
|
32
|
+
* workspace resolves without a `--workspace` flag. Name refs still need a
|
|
33
|
+
* workspace to disambiguate. An explicit `--workspace` forces the name path.
|
|
34
|
+
*/
|
|
35
|
+
export async function resolveChannelByRef(ref, workspaceRef) {
|
|
36
|
+
if (!workspaceRef) {
|
|
37
|
+
const directId = getDirectChannelId(ref);
|
|
38
|
+
if (directId) {
|
|
39
|
+
const client = await getCommsClient();
|
|
40
|
+
return client.channels.getChannel(directId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const workspaceId = await resolveChannelWorkspaceId(workspaceRef);
|
|
44
|
+
return resolveChannelRef(ref, workspaceId);
|
|
45
|
+
}
|
|
29
46
|
export function encodeCursor(offset) {
|
|
30
47
|
return Buffer.from(JSON.stringify({ offset })).toString('base64url');
|
|
31
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/commands/channel/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/commands/channel/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAa3C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiR7D"}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { Option } from 'commander';
|
|
2
2
|
import { withCaseInsensitiveChoices } from '../../lib/completion.js';
|
|
3
|
+
import { addChannelMembers } from './add.js';
|
|
4
|
+
import { archiveChannel, unarchiveChannel } from './archive.js';
|
|
3
5
|
import { createChannel } from './create.js';
|
|
6
|
+
import { deleteChannel } from './delete.js';
|
|
4
7
|
import { listChannels } from './list.js';
|
|
8
|
+
import { listChannelMembers } from './members.js';
|
|
9
|
+
import { removeChannelMembers } from './remove.js';
|
|
10
|
+
import { setChannelMembers } from './set.js';
|
|
5
11
|
import { showChannelThreads } from './threads.js';
|
|
6
12
|
import { updateChannel } from './update.js';
|
|
7
13
|
export function registerChannelCommand(program) {
|
|
8
14
|
const channel = program
|
|
9
15
|
.command('channel')
|
|
10
16
|
.alias('channels')
|
|
11
|
-
.description('Channel operations (list, create, update, threads)');
|
|
17
|
+
.description('Channel operations (list, create, update, threads, members)');
|
|
12
18
|
channel
|
|
13
19
|
.command('list [workspace-ref]', { isDefault: true })
|
|
14
20
|
.description('List joined channels or discoverable public channels in a workspace')
|
|
@@ -74,6 +80,51 @@ Examples:
|
|
|
74
80
|
tdc channel update id:abc123 --description "Team discussions"
|
|
75
81
|
tdc channel update "Leadership" --private --json`)
|
|
76
82
|
.action(updateChannel);
|
|
83
|
+
channel
|
|
84
|
+
.command('delete <channel-ref>')
|
|
85
|
+
.description('Permanently delete a channel')
|
|
86
|
+
.option('--workspace <ref>', 'Workspace ID or name')
|
|
87
|
+
.option('--yes', 'Confirm deletion')
|
|
88
|
+
.option('--dry-run', 'Show what would happen without executing')
|
|
89
|
+
.option('--json', 'Output result as JSON')
|
|
90
|
+
.addHelpText('after', `
|
|
91
|
+
Examples:
|
|
92
|
+
tdc channel delete "Engineering" --dry-run
|
|
93
|
+
tdc channel delete "Engineering" --yes
|
|
94
|
+
tdc channel delete id:abc123 --yes --json
|
|
95
|
+
|
|
96
|
+
Notes:
|
|
97
|
+
Channel deletion is typically restricted to workspace admins.`)
|
|
98
|
+
.action(deleteChannel);
|
|
99
|
+
channel
|
|
100
|
+
.command('archive <channel-ref>')
|
|
101
|
+
.description('Archive a channel')
|
|
102
|
+
.option('--workspace <ref>', 'Workspace ID or name')
|
|
103
|
+
.option('--dry-run', 'Show what would happen without executing')
|
|
104
|
+
.option('--json', 'Output result as JSON')
|
|
105
|
+
.addHelpText('after', `
|
|
106
|
+
Examples:
|
|
107
|
+
tdc channel archive "Engineering"
|
|
108
|
+
tdc channel archive id:abc123 --json
|
|
109
|
+
|
|
110
|
+
Notes:
|
|
111
|
+
No-op if the channel is already archived.
|
|
112
|
+
Archived channels can be listed with: tdc channels --state archived`)
|
|
113
|
+
.action(archiveChannel);
|
|
114
|
+
channel
|
|
115
|
+
.command('unarchive <channel-ref>')
|
|
116
|
+
.description('Unarchive a channel')
|
|
117
|
+
.option('--workspace <ref>', 'Workspace ID or name')
|
|
118
|
+
.option('--dry-run', 'Show what would happen without executing')
|
|
119
|
+
.option('--json', 'Output result as JSON')
|
|
120
|
+
.addHelpText('after', `
|
|
121
|
+
Examples:
|
|
122
|
+
tdc channel unarchive id:abc123
|
|
123
|
+
tdc channel unarchive id:abc123 --json
|
|
124
|
+
|
|
125
|
+
Notes:
|
|
126
|
+
Name-ref resolution only finds active channels — pass id: or numeric ID for archived channels.`)
|
|
127
|
+
.action(unarchiveChannel);
|
|
77
128
|
channel
|
|
78
129
|
.command('threads <channel-ref> [workspace-ref]')
|
|
79
130
|
.description('List threads in a channel with pagination and filtering')
|
|
@@ -100,5 +151,78 @@ Notes:
|
|
|
100
151
|
Sorted newest-first by last activity. --limit, --cursor, --since, --until,
|
|
101
152
|
and --unread are applied client-side; --archive-filter is applied server-side.`)
|
|
102
153
|
.action(showChannelThreads);
|
|
154
|
+
const members = channel
|
|
155
|
+
.command('members')
|
|
156
|
+
.description('Channel membership operations (list, add, remove, set)');
|
|
157
|
+
members
|
|
158
|
+
.command('list <channel-ref>', { isDefault: true })
|
|
159
|
+
.description("List a channel's members and groups fully present in the channel")
|
|
160
|
+
.option('--json', 'Output as JSON')
|
|
161
|
+
.option('--ndjson', 'Output as newline-delimited JSON')
|
|
162
|
+
.option('--full', 'Include all fields in JSON output')
|
|
163
|
+
.addHelpText('after', `
|
|
164
|
+
Examples:
|
|
165
|
+
tdc channel members 12345
|
|
166
|
+
tdc channel members "general" --json
|
|
167
|
+
tdc channel members add 12345 alice group:Design
|
|
168
|
+
tdc channel members remove 12345 alice
|
|
169
|
+
tdc channel members set 12345 group:Squad --apply
|
|
170
|
+
|
|
171
|
+
Notes:
|
|
172
|
+
"Groups fully in channel" lists groups whose entire current membership is
|
|
173
|
+
already in the channel — a hint, not a persistent link.`)
|
|
174
|
+
.action(listChannelMembers);
|
|
175
|
+
members
|
|
176
|
+
.command('add <channel-ref> [refs...]')
|
|
177
|
+
.description('Add users and/or groups to a channel')
|
|
178
|
+
.option('--dry-run', 'Show what would change without changing')
|
|
179
|
+
.option('--json', 'Output result as JSON')
|
|
180
|
+
.option('--full', 'Include the full updated channel in JSON output')
|
|
181
|
+
.addHelpText('after', `
|
|
182
|
+
Examples:
|
|
183
|
+
tdc channel members add 12345 alice@doist.com bob@doist.com
|
|
184
|
+
tdc channel members add "general" group:Frontend
|
|
185
|
+
tdc channel members add 12345 alice group:Design id:789 --json
|
|
186
|
+
|
|
187
|
+
Notes:
|
|
188
|
+
Refs accept user identifiers (id:N, email, name) or "group:<ref>" to expand
|
|
189
|
+
a group to its current members. Group expansion is one-shot — users added
|
|
190
|
+
later to the group will not auto-join the channel.`)
|
|
191
|
+
.action(addChannelMembers);
|
|
192
|
+
members
|
|
193
|
+
.command('remove <channel-ref> [refs...]')
|
|
194
|
+
.description('Remove users and/or groups from a channel')
|
|
195
|
+
.option('--dry-run', 'Show what would change without changing')
|
|
196
|
+
.option('--json', 'Output result as JSON')
|
|
197
|
+
.option('--full', 'Include the full updated channel in JSON output')
|
|
198
|
+
.addHelpText('after', `
|
|
199
|
+
Examples:
|
|
200
|
+
tdc channel members remove 12345 alice@doist.com
|
|
201
|
+
tdc channel members remove "general" group:Frontend
|
|
202
|
+
|
|
203
|
+
Notes:
|
|
204
|
+
Refs accept user identifiers (id:N, email, name) or "group:<ref>" to expand
|
|
205
|
+
a group to its current members.`)
|
|
206
|
+
.action(removeChannelMembers);
|
|
207
|
+
members
|
|
208
|
+
.command('set <channel-ref> [refs...]')
|
|
209
|
+
.description('Replace channel membership with the resolved set of refs')
|
|
210
|
+
.option('--apply', 'Actually mutate (otherwise dry-run)')
|
|
211
|
+
.option('--include-self', 'Allow set to remove the acting user')
|
|
212
|
+
.option('--dry-run', 'Force dry-run (default behaviour)')
|
|
213
|
+
.option('--json', 'Output result as JSON')
|
|
214
|
+
.option('--full', 'Include the full updated channel in JSON output')
|
|
215
|
+
.addHelpText('after', `
|
|
216
|
+
Examples:
|
|
217
|
+
tdc channel members set 12345 group:Frontend group:Design
|
|
218
|
+
tdc channel members set "general" alice bob carol --apply
|
|
219
|
+
tdc channel members set 12345 group:Squad --apply --include-self
|
|
220
|
+
|
|
221
|
+
Notes:
|
|
222
|
+
Dry-run by default. Pass --apply to mutate.
|
|
223
|
+
Refuses to remove the acting user unless --include-self is also passed.
|
|
224
|
+
Group expansion is one-shot — users added later to a referenced group will
|
|
225
|
+
not auto-join the channel.`)
|
|
226
|
+
.action(setChannelMembers);
|
|
103
227
|
}
|
|
104
228
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACnD,MAAM,OAAO,GAAG,OAAO;SAClB,OAAO,CAAC,SAAS,CAAC;SAClB,KAAK,CAAC,UAAU,CAAC;SACjB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"members.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/members.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAKvD,wBAAsB,kBAAkB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CA4Df"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getCurrentWorkspaceId, getWorkspaceGroups } from '../../lib/api.js';
|
|
2
|
+
import { colors, formatJson, formatNdjson, pluralize } from '../../lib/output.js';
|
|
3
|
+
import { resolveChannelRef } from '../../lib/refs.js';
|
|
4
|
+
import { channelUserIds, fetchUsersByIds, groupsFullyInChannel } from './membership-helpers.js';
|
|
5
|
+
export async function listChannelMembers(channelRef, options) {
|
|
6
|
+
const workspaceId = await getCurrentWorkspaceId();
|
|
7
|
+
const [channel, groups] = await Promise.all([
|
|
8
|
+
resolveChannelRef(channelRef, workspaceId),
|
|
9
|
+
getWorkspaceGroups(workspaceId),
|
|
10
|
+
]);
|
|
11
|
+
const userIds = channelUserIds(channel);
|
|
12
|
+
const userMap = await fetchUsersByIds(workspaceId, userIds);
|
|
13
|
+
const userIdSet = new Set(userIds);
|
|
14
|
+
const fullyInChannel = groupsFullyInChannel(groups, userIdSet);
|
|
15
|
+
const members = userIds.map((id) => {
|
|
16
|
+
const user = userMap.get(id);
|
|
17
|
+
return { id, name: user?.fullName ?? null, email: user?.email ?? null };
|
|
18
|
+
});
|
|
19
|
+
const slimPayload = {
|
|
20
|
+
id: channel.id,
|
|
21
|
+
name: channel.name,
|
|
22
|
+
workspaceId: channel.workspaceId,
|
|
23
|
+
members,
|
|
24
|
+
groupsFullyInChannel: fullyInChannel.map((g) => ({
|
|
25
|
+
id: g.id,
|
|
26
|
+
name: g.name,
|
|
27
|
+
userIds: g.userIds,
|
|
28
|
+
})),
|
|
29
|
+
};
|
|
30
|
+
const fullPayload = { ...channel, members, groupsFullyInChannel: fullyInChannel };
|
|
31
|
+
if (options.json) {
|
|
32
|
+
console.log(formatJson(options.full ? fullPayload : slimPayload));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (options.ndjson) {
|
|
36
|
+
console.log(formatNdjson([options.full ? fullPayload : slimPayload]));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
console.log(colors.channel(channel.name));
|
|
40
|
+
console.log(colors.timestamp(`id:${channel.id}`));
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(`${members.length} ${pluralize(members.length, 'member')}`);
|
|
43
|
+
for (const m of members) {
|
|
44
|
+
const name = m.name ?? `user:${m.id}`;
|
|
45
|
+
const email = m.email ? colors.timestamp(`<${m.email}>`) : '';
|
|
46
|
+
const id = colors.timestamp(`id:${m.id}`);
|
|
47
|
+
console.log(` ${id} ${colors.author(name)} ${email}`.trimEnd());
|
|
48
|
+
}
|
|
49
|
+
if (fullyInChannel.length > 0) {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(`Groups fully in channel (${fullyInChannel.length}):`);
|
|
52
|
+
for (const g of fullyInChannel) {
|
|
53
|
+
console.log(` ${colors.timestamp(`id:${g.id}`)} ${g.name} ${colors.timestamp(`(${g.userIds.length} ${pluralize(g.userIds.length, 'member')})`)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=members.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"members.js","sourceRoot":"","sources":["../../../src/commands/channel/members.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAE5E,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAE/F,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,UAAkB,EAClB,OAAyC;IAEzC,MAAM,WAAW,GAAG,MAAM,qBAAqB,EAAE,CAAA;IACjD,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxC,iBAAiB,CAAC,UAAU,EAAE,WAAW,CAAC;QAC1C,kBAAkB,CAAC,WAAW,CAAC;KAClC,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAE3D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,cAAc,GAAG,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAE9D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,CAAA;IAC3E,CAAC,CAAC,CAAA;IAEF,MAAM,WAAW,GAAG;QAChB,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,OAAO;QACP,oBAAoB,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;SACrB,CAAC,CAAC;KACN,CAAA;IACD,MAAM,WAAW,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,CAAA;IAEjF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAA;QACjE,OAAM;IACV,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACrE,OAAM;IACV,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IACzC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAA;IACvE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAA;QACrC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC7D,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;IACrE,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,cAAc,CAAC,MAAM,IAAI,CAAC,CAAA;QAClE,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CACP,KAAK,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAC1I,CAAA;QACL,CAAC;IACL,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Channel, Group, WorkspaceUser } from '@doist/comms-sdk';
|
|
2
|
+
import type { MutationOptions } from '../../lib/options.js';
|
|
3
|
+
export type ChannelMutationOptions = MutationOptions;
|
|
4
|
+
export type ExpandedGroup = {
|
|
5
|
+
groupId: string;
|
|
6
|
+
groupName: string;
|
|
7
|
+
userIds: number[];
|
|
8
|
+
};
|
|
9
|
+
export declare function channelUserIds(channel: Channel): number[];
|
|
10
|
+
export declare function fetchUsersByIds(workspaceId: number, userIds: number[]): Promise<Map<number, WorkspaceUser>>;
|
|
11
|
+
export declare function logExpansion(expandedFrom: ExpandedGroup[]): void;
|
|
12
|
+
export declare function describeExpansion(expandedFrom: ExpandedGroup[]): string | undefined;
|
|
13
|
+
export declare function groupsFullyInChannel(groups: Group[], channelUserIdSet: Set<number>): Group[];
|
|
14
|
+
/**
|
|
15
|
+
* Shared add/remove mutation flow. Resolves the channel and the requested refs
|
|
16
|
+
* concurrently, diffs against current membership, then either previews
|
|
17
|
+
* (`--dry-run`) or applies the mutation and prints / emits JSON.
|
|
18
|
+
*/
|
|
19
|
+
export declare function mutateChannelMembership(channelRef: string, refs: string[], action: 'add' | 'remove', options: ChannelMutationOptions): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=membership-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"membership-helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/membership-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAOrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAI3D,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAA;AAEpD,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAErF,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAEzD;AAED,wBAAsB,eAAe,CACjC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAoBrC;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,IAAI,CAQhE;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,MAAM,GAAG,SAAS,CAKnF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAI5F;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CACzC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,KAAK,GAAG,QAAQ,EACxB,OAAO,EAAE,sBAAsB,GAChC,OAAO,CAAC,IAAI,CAAC,CAqFf"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { addUsersToChannel, getCommsClient, getCurrentWorkspaceId, removeUsersFromChannel, } from '../../lib/api.js';
|
|
2
|
+
import { colors, formatJson, pluralize, printDryRun } from '../../lib/output.js';
|
|
3
|
+
import { resolveChannelMemberRefs, resolveChannelRef } from '../../lib/refs.js';
|
|
4
|
+
export function channelUserIds(channel) {
|
|
5
|
+
return channel.userIds ?? [];
|
|
6
|
+
}
|
|
7
|
+
export async function fetchUsersByIds(workspaceId, userIds) {
|
|
8
|
+
if (userIds.length === 0)
|
|
9
|
+
return new Map();
|
|
10
|
+
const client = await getCommsClient();
|
|
11
|
+
// Per-member fetch keeps latency tied to channel size, not workspace size
|
|
12
|
+
// (mirrors groups/view); missing/unresolvable users are simply skipped.
|
|
13
|
+
const entries = await Promise.all(userIds.map(async (userId) => {
|
|
14
|
+
try {
|
|
15
|
+
const user = await client.workspaceUsers.getUserById({ workspaceId, userId });
|
|
16
|
+
return [userId, user];
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}));
|
|
22
|
+
const map = new Map();
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
if (entry)
|
|
25
|
+
map.set(entry[0], entry[1]);
|
|
26
|
+
}
|
|
27
|
+
return map;
|
|
28
|
+
}
|
|
29
|
+
export function logExpansion(expandedFrom) {
|
|
30
|
+
for (const g of expandedFrom) {
|
|
31
|
+
console.log(colors.timestamp(`Expanded group "${g.groupName}" → ${g.userIds.length} ${pluralize(g.userIds.length, 'user')}`));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function describeExpansion(expandedFrom) {
|
|
35
|
+
if (expandedFrom.length === 0)
|
|
36
|
+
return undefined;
|
|
37
|
+
return expandedFrom
|
|
38
|
+
.map((g) => `${g.groupName} (id:${g.groupId}, ${g.userIds.length} users)`)
|
|
39
|
+
.join('\n');
|
|
40
|
+
}
|
|
41
|
+
export function groupsFullyInChannel(groups, channelUserIdSet) {
|
|
42
|
+
return groups.filter((g) => g.userIds.length > 0 && g.userIds.every((id) => channelUserIdSet.has(id)));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Shared add/remove mutation flow. Resolves the channel and the requested refs
|
|
46
|
+
* concurrently, diffs against current membership, then either previews
|
|
47
|
+
* (`--dry-run`) or applies the mutation and prints / emits JSON.
|
|
48
|
+
*/
|
|
49
|
+
export async function mutateChannelMembership(channelRef, refs, action, options) {
|
|
50
|
+
const workspaceId = await getCurrentWorkspaceId();
|
|
51
|
+
const [channel, { userIds: requested, expandedFrom }] = await Promise.all([
|
|
52
|
+
resolveChannelRef(channelRef, workspaceId),
|
|
53
|
+
resolveChannelMemberRefs(refs, workspaceId),
|
|
54
|
+
]);
|
|
55
|
+
const current = new Set(channelUserIds(channel));
|
|
56
|
+
const actionable = action === 'add'
|
|
57
|
+
? requested.filter((id) => !current.has(id))
|
|
58
|
+
: requested.filter((id) => current.has(id));
|
|
59
|
+
const skipped = action === 'add'
|
|
60
|
+
? requested.filter((id) => current.has(id))
|
|
61
|
+
: requested.filter((id) => !current.has(id));
|
|
62
|
+
const actionLabel = action === 'add' ? 'add users to' : 'remove users from';
|
|
63
|
+
const skippedLabel = action === 'add' ? 'Already members' : 'Not members';
|
|
64
|
+
if (options.dryRun) {
|
|
65
|
+
printDryRun(`${actionLabel} channel`, {
|
|
66
|
+
Channel: `${channel.name} (id:${channel.id})`,
|
|
67
|
+
'Expanded from groups': describeExpansion(expandedFrom),
|
|
68
|
+
[`Users to ${action}`]: actionable.length > 0 ? actionable.join(', ') : '(none)',
|
|
69
|
+
[skippedLabel]: skipped.length > 0 ? skipped.join(', ') : undefined,
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (actionable.length > 0) {
|
|
74
|
+
if (action === 'add') {
|
|
75
|
+
await addUsersToChannel(channel.id, actionable);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
await removeUsersFromChannel(channel.id, actionable);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const newMemberCount = action === 'add'
|
|
82
|
+
? channelUserIds(channel).length + actionable.length
|
|
83
|
+
: channelUserIds(channel).length - actionable.length;
|
|
84
|
+
if (options.json) {
|
|
85
|
+
if (options.full) {
|
|
86
|
+
const client = await getCommsClient();
|
|
87
|
+
const updated = await client.channels.getChannel(channel.id);
|
|
88
|
+
console.log(formatJson(updated, 'channel', true));
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const result = {
|
|
92
|
+
id: channel.id,
|
|
93
|
+
memberCount: newMemberCount,
|
|
94
|
+
};
|
|
95
|
+
if (expandedFrom.length > 0)
|
|
96
|
+
result.expandedFrom = expandedFrom;
|
|
97
|
+
if (action === 'add') {
|
|
98
|
+
result.added = actionable;
|
|
99
|
+
result.alreadyMembers = skipped;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
result.removed = actionable;
|
|
103
|
+
result.notMembers = skipped;
|
|
104
|
+
}
|
|
105
|
+
console.log(formatJson(result));
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const pastVerb = action === 'add' ? 'Added' : 'Removed';
|
|
110
|
+
const preposition = action === 'add' ? 'to' : 'from';
|
|
111
|
+
const noneMsg = action === 'add'
|
|
112
|
+
? `No new members added to "${channel.name}" (already in channel).`
|
|
113
|
+
: `No members removed from "${channel.name}" (none of the users were in channel).`;
|
|
114
|
+
logExpansion(expandedFrom);
|
|
115
|
+
if (actionable.length === 0) {
|
|
116
|
+
console.log(noneMsg);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.log(`${pastVerb} ${actionable.length} ${pluralize(actionable.length, 'user')} ${preposition} "${channel.name}" (now ${newMemberCount} ${pluralize(newMemberCount, 'member')}).`);
|
|
120
|
+
}
|
|
121
|
+
if (skipped.length > 0) {
|
|
122
|
+
console.log(`${skippedLabel}: ${skipped.join(', ')}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=membership-helpers.js.map
|