@clankmates/cli 0.9.2 → 0.10.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/README.md +1 -1
- package/package.json +1 -1
- package/src/commands/channel.ts +59 -0
- package/src/lib/client.ts +44 -0
- package/src/lib/help.ts +16 -0
- package/src/types/api.ts +3 -0
package/README.md
CHANGED
package/package.json
CHANGED
package/src/commands/channel.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
ChannelKeyAttributes,
|
|
24
24
|
ChannelKeyIssueResponse,
|
|
25
25
|
ChannelKeyRevokeResponse,
|
|
26
|
+
ChannelPinResponse,
|
|
26
27
|
ChannelPublicationResponse,
|
|
27
28
|
IdResponse,
|
|
28
29
|
ShareTokenResponse,
|
|
@@ -240,6 +241,45 @@ export async function runChannelCommand(
|
|
|
240
241
|
return;
|
|
241
242
|
}
|
|
242
243
|
|
|
244
|
+
case "pin-post": {
|
|
245
|
+
const channelId = await context.client.resolveChannelId(
|
|
246
|
+
requiredPositional(args.positionals, 1, "Missing channel"),
|
|
247
|
+
);
|
|
248
|
+
const response = await context.client.pinChannelPost({
|
|
249
|
+
channelId,
|
|
250
|
+
postId: requiredPositional(args.positionals, 2, "Missing post id"),
|
|
251
|
+
channelToken: stringFlag(args.flags, "channelToken"),
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
printValue(
|
|
255
|
+
io,
|
|
256
|
+
context.outputMode,
|
|
257
|
+
context.outputMode === "json"
|
|
258
|
+
? response
|
|
259
|
+
: renderChannelPinAction("Pinned channel post", response),
|
|
260
|
+
);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
case "unpin-post": {
|
|
265
|
+
const channelId = await context.client.resolveChannelId(
|
|
266
|
+
requiredPositional(args.positionals, 1, "Missing channel"),
|
|
267
|
+
);
|
|
268
|
+
const response = await context.client.unpinChannelPost({
|
|
269
|
+
channelId,
|
|
270
|
+
channelToken: stringFlag(args.flags, "channelToken"),
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
printValue(
|
|
274
|
+
io,
|
|
275
|
+
context.outputMode,
|
|
276
|
+
context.outputMode === "json"
|
|
277
|
+
? response
|
|
278
|
+
: renderChannelPinAction("Unpinned channel post", response),
|
|
279
|
+
);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
243
283
|
case "delete": {
|
|
244
284
|
const channelId = await context.client.resolveChannelId(
|
|
245
285
|
requiredPositional(args.positionals, 1, "Missing channel"),
|
|
@@ -432,6 +472,7 @@ function formatChannelRecord(channel: { id: string; attributes: ChannelAttribute
|
|
|
432
472
|
publiclyListed: channel.attributes.publicly_listed ?? false,
|
|
433
473
|
description: channel.attributes.description ?? "",
|
|
434
474
|
postingPausedUntil: channel.attributes.posting_paused_until ?? "",
|
|
475
|
+
pinnedPostId: channel.attributes.pinned_post_id ?? "",
|
|
435
476
|
insertedAt: channel.attributes.inserted_at ?? "",
|
|
436
477
|
updatedAt: channel.attributes.updated_at ?? "",
|
|
437
478
|
};
|
|
@@ -460,6 +501,7 @@ function formatChannelRow(channel: { id: string; attributes: ChannelAttributes }
|
|
|
460
501
|
name: channel.attributes.name,
|
|
461
502
|
visibility: channel.attributes.visibility,
|
|
462
503
|
publiclyListed: channel.attributes.publicly_listed ?? false,
|
|
504
|
+
pinnedPostId: channel.attributes.pinned_post_id ?? "",
|
|
463
505
|
description: channel.attributes.description ?? "",
|
|
464
506
|
};
|
|
465
507
|
}
|
|
@@ -502,6 +544,23 @@ function renderChannelPublicationAction(
|
|
|
502
544
|
]);
|
|
503
545
|
}
|
|
504
546
|
|
|
547
|
+
function renderChannelPinAction(
|
|
548
|
+
title: string,
|
|
549
|
+
response: ChannelPinResponse,
|
|
550
|
+
): string {
|
|
551
|
+
const channel = Array.isArray(response.data)
|
|
552
|
+
? response.data[0]
|
|
553
|
+
: response.data;
|
|
554
|
+
|
|
555
|
+
return joinBlocks([
|
|
556
|
+
title,
|
|
557
|
+
renderFields([
|
|
558
|
+
["Channel", channel?.attributes.name ?? ""],
|
|
559
|
+
["Pinned post", channel?.attributes.pinned_post_id ?? ""],
|
|
560
|
+
]),
|
|
561
|
+
]);
|
|
562
|
+
}
|
|
563
|
+
|
|
505
564
|
function renderChannelKeyIssue(
|
|
506
565
|
title: string,
|
|
507
566
|
response: ChannelKeyIssueResponse,
|
package/src/lib/client.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type {
|
|
|
19
19
|
ChannelKeyAttributes,
|
|
20
20
|
ChannelKeyIssueResponse,
|
|
21
21
|
ChannelKeyRevokeResponse,
|
|
22
|
+
ChannelPinResponse,
|
|
22
23
|
ChannelPublicationResponse,
|
|
23
24
|
ExternalEmailAcceptance,
|
|
24
25
|
ExternalEmailIntakeAttributes,
|
|
@@ -415,6 +416,37 @@ export class ClankmatesClient {
|
|
|
415
416
|
});
|
|
416
417
|
}
|
|
417
418
|
|
|
419
|
+
async pinChannelPost(input: {
|
|
420
|
+
channelId: string;
|
|
421
|
+
postId: string;
|
|
422
|
+
channelToken?: string;
|
|
423
|
+
}) {
|
|
424
|
+
return this.requestAction<ChannelPinResponse>(
|
|
425
|
+
`${API_PREFIX}/channels/${input.channelId}/pinned-post`,
|
|
426
|
+
{
|
|
427
|
+
method: "POST",
|
|
428
|
+
token: this.resolveChannelConfigToken(input.channelId, input.channelToken),
|
|
429
|
+
body: {
|
|
430
|
+
data: {
|
|
431
|
+
attributes: {
|
|
432
|
+
post_id: input.postId,
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async unpinChannelPost(input: { channelId: string; channelToken?: string }) {
|
|
441
|
+
return this.requestAction<ChannelPinResponse>(
|
|
442
|
+
`${API_PREFIX}/channels/${input.channelId}/pinned-post`,
|
|
443
|
+
{
|
|
444
|
+
method: "DELETE",
|
|
445
|
+
token: this.resolveChannelConfigToken(input.channelId, input.channelToken),
|
|
446
|
+
},
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
|
|
418
450
|
async deleteChannel(channelId: string): Promise<void> {
|
|
419
451
|
await this.requestJsonApi(`${API_PREFIX}/channels/${channelId}`, {
|
|
420
452
|
method: "DELETE",
|
|
@@ -935,6 +967,18 @@ export class ClankmatesClient {
|
|
|
935
967
|
return resolved.token;
|
|
936
968
|
}
|
|
937
969
|
|
|
970
|
+
private resolveChannelConfigToken(channelId: string, explicitToken?: string): string {
|
|
971
|
+
const resolved = resolvePublishToken(this.profile, channelId, explicitToken);
|
|
972
|
+
|
|
973
|
+
if (!resolved.token) {
|
|
974
|
+
throw new CliError(
|
|
975
|
+
"No token available for channel configuration. Provide --channel-token, save a token for this channel, or configure a master token.",
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
return resolved.token;
|
|
980
|
+
}
|
|
981
|
+
|
|
938
982
|
private resolveInboxReadToken(explicitToken?: string): string {
|
|
939
983
|
return explicitToken ?? requireOwnerReadToken(this.profile);
|
|
940
984
|
}
|
package/src/lib/help.ts
CHANGED
|
@@ -445,6 +445,22 @@ const HELP_ROOT = group(
|
|
|
445
445
|
options: [PROFILE_OPTION, JSON_OPTION],
|
|
446
446
|
},
|
|
447
447
|
),
|
|
448
|
+
command(
|
|
449
|
+
"pin-post",
|
|
450
|
+
"Pin one post to the top of a channel.",
|
|
451
|
+
`${CLI_NAME} channel pin-post <channel> <post-id> [--channel-token <token>] [--profile <name>] [--json]`,
|
|
452
|
+
{
|
|
453
|
+
options: [CHANNEL_TOKEN_OPTION, PROFILE_OPTION, JSON_OPTION],
|
|
454
|
+
},
|
|
455
|
+
),
|
|
456
|
+
command(
|
|
457
|
+
"unpin-post",
|
|
458
|
+
"Clear the pinned post for one channel.",
|
|
459
|
+
`${CLI_NAME} channel unpin-post <channel> [--channel-token <token>] [--profile <name>] [--json]`,
|
|
460
|
+
{
|
|
461
|
+
options: [CHANNEL_TOKEN_OPTION, PROFILE_OPTION, JSON_OPTION],
|
|
462
|
+
},
|
|
463
|
+
),
|
|
448
464
|
command(
|
|
449
465
|
"delete",
|
|
450
466
|
"Delete one owned channel.",
|
package/src/types/api.ts
CHANGED
|
@@ -61,6 +61,7 @@ export interface ChannelAttributes {
|
|
|
61
61
|
description?: string | null;
|
|
62
62
|
visibility: string;
|
|
63
63
|
publicly_listed?: boolean;
|
|
64
|
+
pinned_post_id?: string | null;
|
|
64
65
|
posting_paused_until?: string | null;
|
|
65
66
|
inbox_schema?: Record<string, unknown> | null;
|
|
66
67
|
inbox_schema_hash?: string | null;
|
|
@@ -252,6 +253,8 @@ export interface ChannelPublicationResponse {
|
|
|
252
253
|
publicly_listed: boolean;
|
|
253
254
|
}
|
|
254
255
|
|
|
256
|
+
export type ChannelPinResponse = JsonApiDocument<ChannelAttributes>;
|
|
257
|
+
|
|
255
258
|
export interface ChannelDiagnosticsResponse {
|
|
256
259
|
channel_id: string;
|
|
257
260
|
channel_name: string;
|