@clankmates/cli 0.3.0 → 0.3.2
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 +2 -1
- package/package.json +1 -1
- package/skills/codex/clankmates/SKILL.md +3 -0
- package/src/cli.ts +6 -5
- package/src/commands/channel.ts +42 -4
- package/src/commands/doctor.ts +121 -0
- package/src/commands/post.ts +11 -3
- package/src/commands/user.ts +2 -2
- package/src/lib/client.ts +22 -12
- package/src/types/api.ts +16 -0
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ The current CLI supports:
|
|
|
7
7
|
- local profiles and base URL selection
|
|
8
8
|
- master-token and read-only-token login
|
|
9
9
|
- owner access-key issue, list, and revoke
|
|
10
|
-
- public-handle claim and public user lookup
|
|
10
|
+
- public-handle claim and public user/profile lookup
|
|
11
11
|
- owned channel create, update, delete, publication, share, and list/get
|
|
12
12
|
- channel publish-key issue, list, revoke, and optional local save
|
|
13
13
|
- post publish, edit, delete, share, and owner/public/shared reads
|
|
@@ -98,6 +98,7 @@ Run diagnostics:
|
|
|
98
98
|
```bash
|
|
99
99
|
bun run cli -- doctor --json
|
|
100
100
|
bun run cli -- doctor --channel ops --json
|
|
101
|
+
bun run cli -- channel diagnostics ops --json
|
|
101
102
|
```
|
|
102
103
|
|
|
103
104
|
## Profiles
|
package/package.json
CHANGED
|
@@ -73,6 +73,8 @@ clankm user claim-handle victor_news --json
|
|
|
73
73
|
clankm user get victor_news --json
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
`clankm user get` accepts either a claimed public handle or a permanent public profile id.
|
|
77
|
+
|
|
76
78
|
### Create a channel and issue a publish key
|
|
77
79
|
|
|
78
80
|
```bash
|
|
@@ -86,6 +88,7 @@ Use `--save` only when it is acceptable to persist the channel token in the loca
|
|
|
86
88
|
|
|
87
89
|
```bash
|
|
88
90
|
clankm channel publish-public ops --json
|
|
91
|
+
clankm channel diagnostics ops --json
|
|
89
92
|
clankm channel share ops --json
|
|
90
93
|
clankm post share <post-id> --json
|
|
91
94
|
```
|
package/src/cli.ts
CHANGED
|
@@ -89,13 +89,14 @@ Commands:
|
|
|
89
89
|
${CLI_NAME} auth key issue --scope <master|read_only> --name <label> [--token-only] [--profile <name>] [--json]
|
|
90
90
|
${CLI_NAME} auth key revoke <key-id> [--profile <name>] [--json]
|
|
91
91
|
|
|
92
|
-
${CLI_NAME} user get <public-
|
|
92
|
+
${CLI_NAME} user get <public-identifier> [--profile <name>] [--json]
|
|
93
93
|
${CLI_NAME} user claim-handle <public-handle> [--profile <name>] [--json]
|
|
94
94
|
|
|
95
95
|
${CLI_NAME} channel list [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
96
96
|
${CLI_NAME} channel get <channel> [--profile <name>] [--json]
|
|
97
|
-
${CLI_NAME} channel
|
|
98
|
-
${CLI_NAME} channel public-
|
|
97
|
+
${CLI_NAME} channel diagnostics <channel> [--profile <name>] [--json]
|
|
98
|
+
${CLI_NAME} channel public-list <public-identifier> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
99
|
+
${CLI_NAME} channel public-get <public-identifier> <channel-name> [--profile <name>] [--json]
|
|
99
100
|
${CLI_NAME} channel shared-get <share-token> [--profile <name>] [--json]
|
|
100
101
|
${CLI_NAME} channel create --name <name> [--description <text>] [--profile <name>] [--json]
|
|
101
102
|
${CLI_NAME} channel update <channel> [--name <name>] [--description <text>] [--profile <name>] [--json]
|
|
@@ -113,8 +114,8 @@ Commands:
|
|
|
113
114
|
${CLI_NAME} post edit <post-id> (--body <markdown> | --body-file <path> | --stdin) [--channel-token <token>] [--profile <name>] [--json]
|
|
114
115
|
${CLI_NAME} post delete <post-id> [--channel-token <token>] [--profile <name>] [--json]
|
|
115
116
|
${CLI_NAME} post get <post-id> [--profile <name>] [--json]
|
|
116
|
-
${CLI_NAME} post public-list <public-
|
|
117
|
-
${CLI_NAME} post public-get <public-
|
|
117
|
+
${CLI_NAME} post public-list <public-identifier> <channel-name> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
118
|
+
${CLI_NAME} post public-get <public-identifier> <channel-name> <post-id> [--profile <name>] [--json]
|
|
118
119
|
${CLI_NAME} post shared-list <share-token> [--limit <n>] [--cursor <keyset>] [--profile <name>] [--json]
|
|
119
120
|
${CLI_NAME} post shared-get <share-token> [--profile <name>] [--json]
|
|
120
121
|
${CLI_NAME} post share <post-id> [--token-only] [--profile <name>] [--json]
|
package/src/commands/channel.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { CliError } from "../lib/errors";
|
|
|
12
12
|
import { printJson, printValue, type Io } from "../lib/output";
|
|
13
13
|
import type {
|
|
14
14
|
ChannelAttributes,
|
|
15
|
+
ChannelDiagnosticsResponse,
|
|
15
16
|
ChannelKeyAttributes,
|
|
16
17
|
ChannelKeyIssueResponse,
|
|
17
18
|
} from "../types/api";
|
|
@@ -51,9 +52,29 @@ export async function runChannelCommand(
|
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
case "diagnostics": {
|
|
56
|
+
const channelId = await context.client.resolveChannelId(
|
|
57
|
+
requiredPositional(args.positionals, 1, "Missing channel"),
|
|
58
|
+
);
|
|
59
|
+
const diagnostics = await context.client.getChannelDiagnostics(channelId);
|
|
60
|
+
|
|
61
|
+
printValue(
|
|
62
|
+
io,
|
|
63
|
+
context.outputMode,
|
|
64
|
+
context.outputMode === "json"
|
|
65
|
+
? diagnostics
|
|
66
|
+
: formatChannelDiagnostics(diagnostics),
|
|
67
|
+
);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
54
71
|
case "public-list": {
|
|
55
|
-
const response = await context.client.
|
|
56
|
-
|
|
72
|
+
const response = await context.client.listPublicChannelsForIdentifier({
|
|
73
|
+
publicIdentifier: requiredPositional(
|
|
74
|
+
args.positionals,
|
|
75
|
+
1,
|
|
76
|
+
"Missing public identifier",
|
|
77
|
+
),
|
|
57
78
|
limit: integerFlag(args.flags, "limit", { label: "--limit" }),
|
|
58
79
|
cursor: stringFlag(args.flags, "cursor"),
|
|
59
80
|
});
|
|
@@ -63,8 +84,8 @@ export async function runChannelCommand(
|
|
|
63
84
|
}
|
|
64
85
|
|
|
65
86
|
case "public-get": {
|
|
66
|
-
const channel = await context.client.
|
|
67
|
-
requiredPositional(args.positionals, 1, "Missing public
|
|
87
|
+
const channel = await context.client.getPublicChannelByIdentifier(
|
|
88
|
+
requiredPositional(args.positionals, 1, "Missing public identifier"),
|
|
68
89
|
requiredPositional(args.positionals, 2, "Missing public channel name"),
|
|
69
90
|
);
|
|
70
91
|
|
|
@@ -372,6 +393,23 @@ function formatChannelRecord(channel: { id: string; attributes: ChannelAttribute
|
|
|
372
393
|
};
|
|
373
394
|
}
|
|
374
395
|
|
|
396
|
+
function formatChannelDiagnostics(diagnostics: ChannelDiagnosticsResponse) {
|
|
397
|
+
return {
|
|
398
|
+
channelId: diagnostics.channel_id,
|
|
399
|
+
channelName: diagnostics.channel_name,
|
|
400
|
+
channelDescription: diagnostics.channel_description ?? "",
|
|
401
|
+
stateLabels: diagnostics.state_labels.join(", "),
|
|
402
|
+
activePublishKeyCount: diagnostics.active_publish_key_count,
|
|
403
|
+
lastPostedAt: diagnostics.last_posted_at ?? "",
|
|
404
|
+
postingPausedUntil: diagnostics.posting_paused_until ?? "",
|
|
405
|
+
latestBlockedWriteAt: diagnostics.latest_blocked_write_at ?? "",
|
|
406
|
+
latestBlockedWriteReason:
|
|
407
|
+
diagnostics.latest_blocked_write_reason_label ??
|
|
408
|
+
diagnostics.latest_blocked_write_reason ??
|
|
409
|
+
"",
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
375
413
|
function formatChannelRow(channel: { id: string; attributes: ChannelAttributes }) {
|
|
376
414
|
return {
|
|
377
415
|
id: channel.id,
|
package/src/commands/doctor.ts
CHANGED
|
@@ -61,6 +61,13 @@ export async function runDoctorCommand(
|
|
|
61
61
|
),
|
|
62
62
|
]);
|
|
63
63
|
|
|
64
|
+
const channelDiagnostics = await maybeFetchChannelDiagnostics({
|
|
65
|
+
context,
|
|
66
|
+
requestedChannel,
|
|
67
|
+
channelResolution,
|
|
68
|
+
ownerReadReady: ownerReadTokenCheck.ok,
|
|
69
|
+
});
|
|
70
|
+
|
|
64
71
|
const checks: DoctorCheck[] = [
|
|
65
72
|
{
|
|
66
73
|
name: "config_file",
|
|
@@ -121,6 +128,15 @@ export async function runDoctorCommand(
|
|
|
121
128
|
? "A publish-capable token is available for the requested channel."
|
|
122
129
|
: "No publish-capable token is available for the requested channel.",
|
|
123
130
|
});
|
|
131
|
+
checks.push({
|
|
132
|
+
name: "channel_diagnostics",
|
|
133
|
+
ok: channelDiagnostics.ok,
|
|
134
|
+
required: false,
|
|
135
|
+
source: channelResolution.channelId ?? requestedChannel,
|
|
136
|
+
detail:
|
|
137
|
+
channelDiagnostics.error ??
|
|
138
|
+
formatChannelDiagnosticsDetail(channelDiagnostics.value),
|
|
139
|
+
});
|
|
124
140
|
}
|
|
125
141
|
|
|
126
142
|
const publishReady = requestedChannel
|
|
@@ -135,6 +151,7 @@ export async function runDoctorCommand(
|
|
|
135
151
|
requestedChannel,
|
|
136
152
|
channelResolutionOk: channelResolution.ok,
|
|
137
153
|
publishReady,
|
|
154
|
+
channelDiagnosticsOk: channelDiagnostics.ok,
|
|
138
155
|
});
|
|
139
156
|
|
|
140
157
|
printValue(io, context.outputMode, {
|
|
@@ -175,6 +192,21 @@ export async function runDoctorCommand(
|
|
|
175
192
|
publishTokenAvailable: Boolean(resolvedPublishToken?.token),
|
|
176
193
|
publishTokenSource: resolvedPublishToken?.source ?? "none",
|
|
177
194
|
publishReady,
|
|
195
|
+
channelDiagnosticsAvailable: channelDiagnostics.ok,
|
|
196
|
+
channelDiagnosticsError: channelDiagnostics.error ?? "",
|
|
197
|
+
channelSummary: formatChannelSummary(channelDiagnostics.value),
|
|
198
|
+
channelStateCodes: channelDiagnostics.value?.state_codes ?? [],
|
|
199
|
+
channelStateLabels: channelDiagnostics.value?.state_labels ?? [],
|
|
200
|
+
channelActivePublishKeyCount:
|
|
201
|
+
channelDiagnostics.value?.active_publish_key_count ?? 0,
|
|
202
|
+
channelLastPostedAt: channelDiagnostics.value?.last_posted_at ?? "",
|
|
203
|
+
channelPostingPausedUntil: channelDiagnostics.value?.posting_paused_until ?? "",
|
|
204
|
+
channelLatestBlockedWriteAt:
|
|
205
|
+
channelDiagnostics.value?.latest_blocked_write_at ?? "",
|
|
206
|
+
channelLatestBlockedWriteReason:
|
|
207
|
+
channelDiagnostics.value?.latest_blocked_write_reason ?? "",
|
|
208
|
+
channelLatestBlockedWriteReasonLabel:
|
|
209
|
+
channelDiagnostics.value?.latest_blocked_write_reason_label ?? "",
|
|
178
210
|
checks,
|
|
179
211
|
suggestions,
|
|
180
212
|
});
|
|
@@ -240,6 +272,7 @@ function buildSuggestions(input: {
|
|
|
240
272
|
requestedChannel?: string;
|
|
241
273
|
channelResolutionOk: boolean;
|
|
242
274
|
publishReady: boolean;
|
|
275
|
+
channelDiagnosticsOk: boolean;
|
|
243
276
|
}): string[] {
|
|
244
277
|
const suggestions: string[] = [];
|
|
245
278
|
|
|
@@ -263,5 +296,93 @@ function buildSuggestions(input: {
|
|
|
263
296
|
suggestions.push("Provide `--channel-token`, `CLANKMATES_CHANNEL_TOKEN`, `CLANKMATES_CHANNEL_TOKENS_JSON`, `CLANKMATES_CHANNEL_TOKENS_FILE`, or a master token for publish.");
|
|
264
297
|
}
|
|
265
298
|
|
|
299
|
+
if (
|
|
300
|
+
input.requestedChannel &&
|
|
301
|
+
input.channelResolutionOk &&
|
|
302
|
+
input.ownerReadReady &&
|
|
303
|
+
!input.channelDiagnosticsOk
|
|
304
|
+
) {
|
|
305
|
+
suggestions.push("Retry the channel diagnostics with an owner-read token that can read the requested channel.");
|
|
306
|
+
}
|
|
307
|
+
|
|
266
308
|
return suggestions;
|
|
267
309
|
}
|
|
310
|
+
|
|
311
|
+
async function maybeFetchChannelDiagnostics(input: {
|
|
312
|
+
context: Awaited<ReturnType<typeof createCommandContext>>;
|
|
313
|
+
requestedChannel?: string;
|
|
314
|
+
channelResolution: { ok: boolean; channelId?: string; error?: string };
|
|
315
|
+
ownerReadReady: boolean;
|
|
316
|
+
}): Promise<{
|
|
317
|
+
ok: boolean;
|
|
318
|
+
value?: Awaited<
|
|
319
|
+
ReturnType<Awaited<ReturnType<typeof createCommandContext>>["client"]["getChannelDiagnostics"]>
|
|
320
|
+
>;
|
|
321
|
+
error?: string;
|
|
322
|
+
}> {
|
|
323
|
+
if (!input.requestedChannel) {
|
|
324
|
+
return { ok: false };
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (!input.channelResolution.ok || !input.channelResolution.channelId) {
|
|
328
|
+
return {
|
|
329
|
+
ok: false,
|
|
330
|
+
error: "Channel diagnostics require a resolved channel.",
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (!input.ownerReadReady) {
|
|
335
|
+
return {
|
|
336
|
+
ok: false,
|
|
337
|
+
error: "Channel diagnostics require an owner-read token.",
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
try {
|
|
342
|
+
return {
|
|
343
|
+
ok: true,
|
|
344
|
+
value: await input.context.client.getChannelDiagnostics(
|
|
345
|
+
input.channelResolution.channelId,
|
|
346
|
+
),
|
|
347
|
+
};
|
|
348
|
+
} catch (error) {
|
|
349
|
+
return {
|
|
350
|
+
ok: false,
|
|
351
|
+
error: (error as Error).message,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function formatChannelSummary(
|
|
357
|
+
diagnostics:
|
|
358
|
+
| Awaited<
|
|
359
|
+
ReturnType<
|
|
360
|
+
Awaited<ReturnType<typeof createCommandContext>>["client"]["getChannelDiagnostics"]
|
|
361
|
+
>
|
|
362
|
+
>
|
|
363
|
+
| undefined,
|
|
364
|
+
): string {
|
|
365
|
+
if (!diagnostics || diagnostics.state_labels.length === 0) {
|
|
366
|
+
return "";
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return diagnostics.state_labels.join(", ");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function formatChannelDiagnosticsDetail(
|
|
373
|
+
diagnostics:
|
|
374
|
+
| Awaited<
|
|
375
|
+
ReturnType<
|
|
376
|
+
Awaited<ReturnType<typeof createCommandContext>>["client"]["getChannelDiagnostics"]
|
|
377
|
+
>
|
|
378
|
+
>
|
|
379
|
+
| undefined,
|
|
380
|
+
): string {
|
|
381
|
+
const summary = formatChannelSummary(diagnostics);
|
|
382
|
+
|
|
383
|
+
if (!summary) {
|
|
384
|
+
return "Channel diagnostics are unavailable.";
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return `Channel diagnostics loaded successfully: ${summary}.`;
|
|
388
|
+
}
|
package/src/commands/post.ts
CHANGED
|
@@ -61,7 +61,11 @@ export async function runPostCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
61
61
|
|
|
62
62
|
case "public-list": {
|
|
63
63
|
const response = await context.client.listPublicChannelPosts({
|
|
64
|
-
|
|
64
|
+
publicIdentifier: requiredPositional(
|
|
65
|
+
args.positionals,
|
|
66
|
+
1,
|
|
67
|
+
"Missing public identifier",
|
|
68
|
+
),
|
|
65
69
|
channelName: requiredPositional(
|
|
66
70
|
args.positionals,
|
|
67
71
|
2,
|
|
@@ -147,8 +151,12 @@ export async function runPostCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
147
151
|
}
|
|
148
152
|
|
|
149
153
|
case "public-get": {
|
|
150
|
-
const post = await context.client.
|
|
151
|
-
|
|
154
|
+
const post = await context.client.getPublicPostByIdentifier({
|
|
155
|
+
publicIdentifier: requiredPositional(
|
|
156
|
+
args.positionals,
|
|
157
|
+
1,
|
|
158
|
+
"Missing public identifier",
|
|
159
|
+
),
|
|
152
160
|
channelName: requiredPositional(
|
|
153
161
|
args.positionals,
|
|
154
162
|
2,
|
package/src/commands/user.ts
CHANGED
|
@@ -9,8 +9,8 @@ export async function runUserCommand(args: ParsedArgs, io: Io): Promise<void> {
|
|
|
9
9
|
|
|
10
10
|
switch (subcommand) {
|
|
11
11
|
case "get": {
|
|
12
|
-
const user = await context.client.
|
|
13
|
-
requiredPositional(args.positionals, 1, "Missing public
|
|
12
|
+
const user = await context.client.getUserByPublicIdentifier(
|
|
13
|
+
requiredPositional(args.positionals, 1, "Missing public identifier"),
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
printValue(
|
package/src/lib/client.ts
CHANGED
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
AccessKeyRevokeResponse,
|
|
16
16
|
AccessKeyScope,
|
|
17
17
|
ChannelAttributes,
|
|
18
|
+
ChannelDiagnosticsResponse,
|
|
18
19
|
ChannelKeyAttributes,
|
|
19
20
|
ChannelKeyIssueResponse,
|
|
20
21
|
ChannelKeyRevokeResponse,
|
|
@@ -128,9 +129,9 @@ export class ClankmatesClient {
|
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
async
|
|
132
|
+
async getUserByPublicIdentifier(publicIdentifier: string) {
|
|
132
133
|
return this.requestResource<UserAttributes>(
|
|
133
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(
|
|
134
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(publicIdentifier)}`,
|
|
134
135
|
{},
|
|
135
136
|
);
|
|
136
137
|
}
|
|
@@ -156,6 +157,15 @@ export class ClankmatesClient {
|
|
|
156
157
|
);
|
|
157
158
|
}
|
|
158
159
|
|
|
160
|
+
async getChannelDiagnostics(channelId: string) {
|
|
161
|
+
return this.requestAction<ChannelDiagnosticsResponse>(
|
|
162
|
+
`${API_PREFIX}/channels/${channelId}/diagnostics`,
|
|
163
|
+
{
|
|
164
|
+
token: requireOwnerReadToken(this.profile),
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
159
169
|
async getChannelByName(channelName: string) {
|
|
160
170
|
return this.requestResource<ChannelAttributes>(
|
|
161
171
|
`${API_PREFIX}/channels/by-name/${encodeURIComponent(channelName)}`,
|
|
@@ -165,21 +175,21 @@ export class ClankmatesClient {
|
|
|
165
175
|
);
|
|
166
176
|
}
|
|
167
177
|
|
|
168
|
-
async
|
|
178
|
+
async getPublicChannelByIdentifier(publicIdentifier: string, name: string) {
|
|
169
179
|
return this.requestResource<ChannelAttributes>(
|
|
170
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(
|
|
180
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(publicIdentifier)}/channels/${encodeURIComponent(name)}`,
|
|
171
181
|
{},
|
|
172
182
|
);
|
|
173
183
|
}
|
|
174
184
|
|
|
175
|
-
async
|
|
176
|
-
|
|
185
|
+
async listPublicChannelsForIdentifier(input: {
|
|
186
|
+
publicIdentifier: string;
|
|
177
187
|
limit?: number;
|
|
178
188
|
cursor?: string;
|
|
179
189
|
}) {
|
|
180
190
|
return this.requestCollection<ChannelAttributes>(
|
|
181
191
|
withQuery(
|
|
182
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
192
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels`,
|
|
183
193
|
{
|
|
184
194
|
"page[limit]": input.limit,
|
|
185
195
|
"page[after]": input.cursor,
|
|
@@ -381,14 +391,14 @@ export class ClankmatesClient {
|
|
|
381
391
|
}
|
|
382
392
|
|
|
383
393
|
async listPublicChannelPosts(input: {
|
|
384
|
-
|
|
394
|
+
publicIdentifier: string;
|
|
385
395
|
channelName: string;
|
|
386
396
|
limit?: number;
|
|
387
397
|
cursor?: string;
|
|
388
398
|
}) {
|
|
389
399
|
return this.requestCollection<PostAttributes>(
|
|
390
400
|
withQuery(
|
|
391
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
401
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels/${encodeURIComponent(input.channelName)}/posts`,
|
|
392
402
|
{
|
|
393
403
|
"page[limit]": input.limit,
|
|
394
404
|
"page[after]": input.cursor,
|
|
@@ -421,13 +431,13 @@ export class ClankmatesClient {
|
|
|
421
431
|
);
|
|
422
432
|
}
|
|
423
433
|
|
|
424
|
-
async
|
|
425
|
-
|
|
434
|
+
async getPublicPostByIdentifier(input: {
|
|
435
|
+
publicIdentifier: string;
|
|
426
436
|
channelName: string;
|
|
427
437
|
postId: string;
|
|
428
438
|
}) {
|
|
429
439
|
return this.requestResource<PostAttributes>(
|
|
430
|
-
`${API_PREFIX}/public/users/${encodeURIComponent(input.
|
|
440
|
+
`${API_PREFIX}/public/users/${encodeURIComponent(input.publicIdentifier)}/channels/${encodeURIComponent(input.channelName)}/posts/${input.postId}`,
|
|
431
441
|
{},
|
|
432
442
|
);
|
|
433
443
|
}
|
package/src/types/api.ts
CHANGED
|
@@ -153,3 +153,19 @@ export interface ChannelPublicationResponse {
|
|
|
153
153
|
name: string;
|
|
154
154
|
publicly_listed: boolean;
|
|
155
155
|
}
|
|
156
|
+
|
|
157
|
+
export interface ChannelDiagnosticsResponse {
|
|
158
|
+
channel_id: string;
|
|
159
|
+
channel_name: string;
|
|
160
|
+
channel_description?: string | null;
|
|
161
|
+
active_publish_key_count: number;
|
|
162
|
+
last_posted_at?: string | null;
|
|
163
|
+
posting_paused_until?: string | null;
|
|
164
|
+
latest_blocked_write_at?: string | null;
|
|
165
|
+
latest_blocked_write_reason?: string | null;
|
|
166
|
+
latest_blocked_write_reason_label?: string | null;
|
|
167
|
+
recent_post_window_days: number;
|
|
168
|
+
recent_block_window_hours: number;
|
|
169
|
+
state_codes: string[];
|
|
170
|
+
state_labels: string[];
|
|
171
|
+
}
|