@curviate/cli 0.18.0 → 0.19.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 +41 -0
- package/dist/cli.js +9 -9
- package/dist/{company-BC72KZ5G.js → company-XEEBBCRZ.js} +391 -11
- package/dist/feed-KAUDRE5K.js +127 -0
- package/dist/group-LPVVJ2JX.js +236 -0
- package/dist/{inbox-DRJ6ENXC.js → inbox-BXCWHGWP.js} +61 -3
- package/dist/notification-RYFDHM3G.js +219 -0
- package/dist/{post-N3GQDIQJ.js → post-HK6HHIKV.js} +94 -1
- package/dist/{profile-XWSRUYRW.js → profile-PES67647.js} +108 -2
- package/dist/{search-ZQUKLQ6T.js → search-O2LACGHE.js} +203 -2
- package/package.json +4 -4
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
pageDelayFromFlags,
|
|
4
|
+
streamAll
|
|
5
|
+
} from "./chunk-EEMJDJ4W.js";
|
|
6
|
+
import {
|
|
7
|
+
createClient,
|
|
8
|
+
renderError,
|
|
9
|
+
renderSuccess,
|
|
10
|
+
renderUnexpectedError,
|
|
11
|
+
resolveEffectiveConfig
|
|
12
|
+
} from "./chunk-M33MI53G.js";
|
|
13
|
+
import {
|
|
14
|
+
GLOBAL_FLAGS,
|
|
15
|
+
READ_SINGLE_FLAGS
|
|
16
|
+
} from "./chunk-TMU3CSPR.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/group.ts
|
|
19
|
+
import { defineCommand } from "citty";
|
|
20
|
+
function buildOutputStreams() {
|
|
21
|
+
return {
|
|
22
|
+
stdout: { write: (s) => process.stdout.write(s) },
|
|
23
|
+
stderr: { write: (s) => process.stderr.write(s) }
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function requireAccount(account, out) {
|
|
27
|
+
if (!account) {
|
|
28
|
+
out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
|
|
29
|
+
process.exit(2);
|
|
30
|
+
}
|
|
31
|
+
return account;
|
|
32
|
+
}
|
|
33
|
+
function rejectPreviewOnRead(preview, out) {
|
|
34
|
+
if (preview) {
|
|
35
|
+
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
36
|
+
process.exit(2);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function rejectAllOnNonPaginated(all, out) {
|
|
40
|
+
if (all) {
|
|
41
|
+
out.stderr.write("error: --all is not supported on non-paginated commands.\n");
|
|
42
|
+
process.exit(2);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function resolveOutputOpts(flags) {
|
|
46
|
+
return {
|
|
47
|
+
json: (flags.json ?? false) || !process.stdout.isTTY,
|
|
48
|
+
isTTY: process.stdout.isTTY ?? false,
|
|
49
|
+
fields: flags.fields,
|
|
50
|
+
verbose: flags.verbose ?? false
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function handleSdkError(err, outOpts, out) {
|
|
54
|
+
const { CurviateError } = await import("@curviate/sdk");
|
|
55
|
+
if (err instanceof CurviateError) {
|
|
56
|
+
const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
|
|
57
|
+
renderError(err, outOpts, out);
|
|
58
|
+
process.exit(getExitCode(err.code));
|
|
59
|
+
}
|
|
60
|
+
renderUnexpectedError(err, out);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
async function runGroupList(client, flags, out) {
|
|
64
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
65
|
+
const accountId = requireAccount(flags.account, out);
|
|
66
|
+
const ns = client.account(accountId);
|
|
67
|
+
const outOpts = resolveOutputOpts(flags);
|
|
68
|
+
const all = flags.all ?? false;
|
|
69
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
70
|
+
const params = {};
|
|
71
|
+
if (flags.target) params["profile"] = flags.target;
|
|
72
|
+
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
73
|
+
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
74
|
+
try {
|
|
75
|
+
if (all) {
|
|
76
|
+
const fn = (p) => ns.groups.list(p);
|
|
77
|
+
for await (const item of streamAll(fn, params, {
|
|
78
|
+
maxPages,
|
|
79
|
+
out,
|
|
80
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
81
|
+
})) {
|
|
82
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
const result = await ns.groups.list(params);
|
|
86
|
+
renderSuccess(result, outOpts, out);
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
await handleSdkError(err, outOpts, out);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function runGroupGet(client, flags, out) {
|
|
93
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
94
|
+
rejectAllOnNonPaginated(flags.all, out);
|
|
95
|
+
const accountId = requireAccount(flags.account, out);
|
|
96
|
+
const groupId = flags.groupId ?? "";
|
|
97
|
+
const ns = client.account(accountId);
|
|
98
|
+
const outOpts = resolveOutputOpts(flags);
|
|
99
|
+
try {
|
|
100
|
+
const result = await ns.groups.get(groupId);
|
|
101
|
+
renderSuccess(result, outOpts, out);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
await handleSdkError(err, outOpts, out);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function runGroupMembers(client, flags, out) {
|
|
107
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
108
|
+
const accountId = requireAccount(flags.account, out);
|
|
109
|
+
const groupId = flags.groupId ?? "";
|
|
110
|
+
const ns = client.account(accountId);
|
|
111
|
+
const outOpts = resolveOutputOpts(flags);
|
|
112
|
+
const all = flags.all ?? false;
|
|
113
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
114
|
+
const params = {};
|
|
115
|
+
if (flags.name) params["name"] = flags.name;
|
|
116
|
+
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
117
|
+
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
118
|
+
try {
|
|
119
|
+
if (all) {
|
|
120
|
+
const fn = (p) => ns.groups.members(groupId, p);
|
|
121
|
+
for await (const item of streamAll(fn, params, {
|
|
122
|
+
maxPages,
|
|
123
|
+
out,
|
|
124
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
125
|
+
})) {
|
|
126
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
const result = await ns.groups.members(groupId, params);
|
|
130
|
+
renderSuccess(result, outOpts, out);
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
await handleSdkError(err, outOpts, out);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
var groupListCommand = defineCommand({
|
|
137
|
+
meta: { name: "list", description: "List the groups the connected account belongs to. Pass --profile to enumerate another member's groups instead (a partial, interests-only read)." },
|
|
138
|
+
args: {
|
|
139
|
+
...GLOBAL_FLAGS,
|
|
140
|
+
target: {
|
|
141
|
+
type: "string",
|
|
142
|
+
description: "Target another LinkedIn member's groups instead of your own: a vanity slug or full /in/{vanity} URL. Omit to enumerate your own groups (a complete read)."
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
async run({ args }) {
|
|
146
|
+
const flags = args;
|
|
147
|
+
const cfg = await resolveEffectiveConfig({
|
|
148
|
+
apiKey: flags["api-key"],
|
|
149
|
+
baseUrl: flags["base-url"],
|
|
150
|
+
timeout: flags.timeout,
|
|
151
|
+
account: flags.account,
|
|
152
|
+
profile: flags.profile
|
|
153
|
+
});
|
|
154
|
+
if (!cfg.apiKey) {
|
|
155
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
156
|
+
process.exit(3);
|
|
157
|
+
}
|
|
158
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
159
|
+
const out = buildOutputStreams();
|
|
160
|
+
await runGroupList(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
var groupGetCommand = defineCommand({
|
|
164
|
+
meta: { name: "get", description: "Get one LinkedIn group's full detail: name, member count, description, admin contact, and write-feasibility gates." },
|
|
165
|
+
args: {
|
|
166
|
+
...READ_SINGLE_FLAGS,
|
|
167
|
+
groupId: { type: "positional", description: "Numeric group id, or a full group URL (e.g. https://www.linkedin.com/groups/9123014/)." }
|
|
168
|
+
},
|
|
169
|
+
async run({ args }) {
|
|
170
|
+
const flags = args;
|
|
171
|
+
const cfg = await resolveEffectiveConfig({
|
|
172
|
+
apiKey: flags["api-key"],
|
|
173
|
+
baseUrl: flags["base-url"],
|
|
174
|
+
timeout: flags.timeout,
|
|
175
|
+
account: flags.account,
|
|
176
|
+
profile: flags.profile
|
|
177
|
+
});
|
|
178
|
+
if (!cfg.apiKey) {
|
|
179
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
180
|
+
process.exit(3);
|
|
181
|
+
}
|
|
182
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
183
|
+
const out = buildOutputStreams();
|
|
184
|
+
await runGroupGet(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
var groupMembersCommand = defineCommand({
|
|
188
|
+
meta: {
|
|
189
|
+
name: "members",
|
|
190
|
+
description: "List (or search by name) a group's members: id, profile URL, name, headline, and relationship signal. Requires the connected account be a member of the group."
|
|
191
|
+
},
|
|
192
|
+
args: {
|
|
193
|
+
...GLOBAL_FLAGS,
|
|
194
|
+
groupId: { type: "positional", description: "Numeric group id, or a full group URL." },
|
|
195
|
+
name: {
|
|
196
|
+
type: "string",
|
|
197
|
+
description: "Filter the roster by member name: prefix/substring, multi-word, case-insensitive. Omit for the full roster."
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
async run({ args }) {
|
|
201
|
+
const flags = args;
|
|
202
|
+
const cfg = await resolveEffectiveConfig({
|
|
203
|
+
apiKey: flags["api-key"],
|
|
204
|
+
baseUrl: flags["base-url"],
|
|
205
|
+
timeout: flags.timeout,
|
|
206
|
+
account: flags.account,
|
|
207
|
+
profile: flags.profile
|
|
208
|
+
});
|
|
209
|
+
if (!cfg.apiKey) {
|
|
210
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
211
|
+
process.exit(3);
|
|
212
|
+
}
|
|
213
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
214
|
+
const out = buildOutputStreams();
|
|
215
|
+
await runGroupMembers(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
var groupCommand = defineCommand({
|
|
219
|
+
meta: { name: "group", description: "Read LinkedIn groups: your own membership list, one group's detail, and its member roster." },
|
|
220
|
+
subCommands: {
|
|
221
|
+
list: groupListCommand,
|
|
222
|
+
get: groupGetCommand,
|
|
223
|
+
members: groupMembersCommand
|
|
224
|
+
},
|
|
225
|
+
async run() {
|
|
226
|
+
process.stderr.write(
|
|
227
|
+
"Usage: curviate group <subcommand>\n list [--profile <target>]\n get <group_id>\n members <group_id> [--name <filter>]\n"
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
export {
|
|
232
|
+
groupCommand,
|
|
233
|
+
runGroupGet,
|
|
234
|
+
runGroupList,
|
|
235
|
+
runGroupMembers
|
|
236
|
+
};
|
|
@@ -189,6 +189,37 @@ async function runInboxMessages(client, flags, out) {
|
|
|
189
189
|
await handleSdkError(err, outOpts, out);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
+
async function runInboxSearch(client, flags, out) {
|
|
193
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
194
|
+
const accountId = requireAccount(flags.account, out);
|
|
195
|
+
const query = flags.query ?? "";
|
|
196
|
+
if (!query) {
|
|
197
|
+
out.stderr.write("error: <query> is required.\n");
|
|
198
|
+
process.exit(2);
|
|
199
|
+
}
|
|
200
|
+
const ns = client.account(accountId);
|
|
201
|
+
const outOpts = resolveOutputOpts(flags);
|
|
202
|
+
const all = flags.all ?? false;
|
|
203
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
204
|
+
const params = { query, ...buildPaginationParams(flags) };
|
|
205
|
+
try {
|
|
206
|
+
if (all) {
|
|
207
|
+
const fn = (p) => ns.messaging.searchChats(p);
|
|
208
|
+
for await (const item of streamAll(fn, params, {
|
|
209
|
+
maxPages,
|
|
210
|
+
out,
|
|
211
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
212
|
+
})) {
|
|
213
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
const result = await ns.messaging.searchChats(params);
|
|
217
|
+
renderSuccess(result, outOpts, out);
|
|
218
|
+
}
|
|
219
|
+
} catch (err) {
|
|
220
|
+
await handleSdkError(err, outOpts, out);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
192
223
|
var inboxListCommand = defineCommand({
|
|
193
224
|
meta: { name: "list", description: "List inbox chats." },
|
|
194
225
|
args: {
|
|
@@ -301,17 +332,43 @@ var inboxMessagesCommand = defineCommand({
|
|
|
301
332
|
await runInboxMessages(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
302
333
|
}
|
|
303
334
|
});
|
|
335
|
+
var inboxSearchCommand = defineCommand({
|
|
336
|
+
meta: { name: "search", description: "Free-text search the account's own inbox (matches participant names and message content)." },
|
|
337
|
+
args: {
|
|
338
|
+
...GLOBAL_FLAGS,
|
|
339
|
+
limit: { type: "string", description: "Number of items to return per page (1-100, default 20)." },
|
|
340
|
+
query: { type: "positional", description: "Search term (e.g. a name or a phrase from a message)." }
|
|
341
|
+
},
|
|
342
|
+
async run({ args }) {
|
|
343
|
+
const flags = args;
|
|
344
|
+
const cfg = await resolveEffectiveConfig({
|
|
345
|
+
apiKey: flags["api-key"],
|
|
346
|
+
baseUrl: flags["base-url"],
|
|
347
|
+
timeout: flags.timeout,
|
|
348
|
+
account: flags.account,
|
|
349
|
+
profile: flags.profile
|
|
350
|
+
});
|
|
351
|
+
if (!cfg.apiKey) {
|
|
352
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
353
|
+
process.exit(3);
|
|
354
|
+
}
|
|
355
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
356
|
+
const out = buildOutputStreams();
|
|
357
|
+
await runInboxSearch(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
304
360
|
var inboxCommand = defineCommand({
|
|
305
361
|
meta: { name: "inbox", description: "Read LinkedIn message inbox." },
|
|
306
362
|
subCommands: {
|
|
307
363
|
list: inboxListCommand,
|
|
308
364
|
get: inboxGetCommand,
|
|
309
365
|
"mark-read": inboxMarkReadCommand,
|
|
310
|
-
messages: inboxMessagesCommand
|
|
366
|
+
messages: inboxMessagesCommand,
|
|
367
|
+
search: inboxSearchCommand
|
|
311
368
|
},
|
|
312
369
|
async run() {
|
|
313
370
|
process.stderr.write(
|
|
314
|
-
"Usage: curviate inbox <subcommand>\n list\n get <chat_id>\n mark-read <chat_id>\n messages <chat_id>\n"
|
|
371
|
+
"Usage: curviate inbox <subcommand>\n list\n get <chat_id>\n mark-read <chat_id>\n messages <chat_id>\n search <query>\n"
|
|
315
372
|
);
|
|
316
373
|
}
|
|
317
374
|
});
|
|
@@ -320,5 +377,6 @@ export {
|
|
|
320
377
|
runInboxGet,
|
|
321
378
|
runInboxList,
|
|
322
379
|
runInboxMarkRead,
|
|
323
|
-
runInboxMessages
|
|
380
|
+
runInboxMessages,
|
|
381
|
+
runInboxSearch
|
|
324
382
|
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
pageDelayFromFlags,
|
|
4
|
+
streamAll
|
|
5
|
+
} from "./chunk-EEMJDJ4W.js";
|
|
6
|
+
import {
|
|
7
|
+
buildPreviewOutput
|
|
8
|
+
} from "./chunk-R3VLWLVV.js";
|
|
9
|
+
import {
|
|
10
|
+
createClient,
|
|
11
|
+
renderError,
|
|
12
|
+
renderSuccess,
|
|
13
|
+
renderUnexpectedError,
|
|
14
|
+
resolveEffectiveConfig
|
|
15
|
+
} from "./chunk-M33MI53G.js";
|
|
16
|
+
import {
|
|
17
|
+
GLOBAL_FLAGS,
|
|
18
|
+
WRITE_SINGLE_FLAGS
|
|
19
|
+
} from "./chunk-TMU3CSPR.js";
|
|
20
|
+
|
|
21
|
+
// src/commands/notification.ts
|
|
22
|
+
import { defineCommand } from "citty";
|
|
23
|
+
function buildOutputStreams() {
|
|
24
|
+
return {
|
|
25
|
+
stdout: { write: (s) => process.stdout.write(s) },
|
|
26
|
+
stderr: { write: (s) => process.stderr.write(s) }
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function requireAccount(account, out) {
|
|
30
|
+
if (!account) {
|
|
31
|
+
out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
return account;
|
|
35
|
+
}
|
|
36
|
+
function rejectPreviewOnRead(preview, out) {
|
|
37
|
+
if (preview) {
|
|
38
|
+
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
39
|
+
process.exit(2);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function resolveOutputOpts(flags) {
|
|
43
|
+
return {
|
|
44
|
+
json: (flags.json ?? false) || !process.stdout.isTTY,
|
|
45
|
+
isTTY: process.stdout.isTTY ?? false,
|
|
46
|
+
fields: flags.fields,
|
|
47
|
+
verbose: flags.verbose ?? false
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function handleSdkError(err, outOpts, out) {
|
|
51
|
+
const { CurviateError } = await import("@curviate/sdk");
|
|
52
|
+
if (err instanceof CurviateError) {
|
|
53
|
+
const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
|
|
54
|
+
renderError(err, outOpts, out);
|
|
55
|
+
process.exit(getExitCode(err.code));
|
|
56
|
+
}
|
|
57
|
+
renderUnexpectedError(err, out);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
async function runNotificationList(client, flags, out) {
|
|
61
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
62
|
+
const accountId = requireAccount(flags.account, out);
|
|
63
|
+
const ns = client.account(accountId);
|
|
64
|
+
const outOpts = resolveOutputOpts(flags);
|
|
65
|
+
const all = flags.all ?? false;
|
|
66
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
67
|
+
const params = {};
|
|
68
|
+
if (flags.filter) params["filter"] = flags.filter;
|
|
69
|
+
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
70
|
+
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
71
|
+
try {
|
|
72
|
+
if (all) {
|
|
73
|
+
const fn = (p) => ns.notifications.list(p);
|
|
74
|
+
for await (const item of streamAll(fn, params, {
|
|
75
|
+
maxPages,
|
|
76
|
+
out,
|
|
77
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
78
|
+
})) {
|
|
79
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
const result = await ns.notifications.list(params);
|
|
83
|
+
renderSuccess(result, outOpts, out);
|
|
84
|
+
}
|
|
85
|
+
} catch (err) {
|
|
86
|
+
await handleSdkError(err, outOpts, out);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function runNotificationDelete(client, flags, out) {
|
|
90
|
+
const accountId = requireAccount(flags.account, out);
|
|
91
|
+
const cardUrn = flags.cardUrn ?? "";
|
|
92
|
+
if (flags.preview) {
|
|
93
|
+
const preview = buildPreviewOutput({ method: "notifications.delete", args: { card_urn: cardUrn }, body: {}, account: accountId });
|
|
94
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const ns = client.account(accountId);
|
|
98
|
+
const outOpts = resolveOutputOpts(flags);
|
|
99
|
+
try {
|
|
100
|
+
const result = await ns.notifications.delete(cardUrn);
|
|
101
|
+
renderSuccess(result, outOpts, out);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
await handleSdkError(err, outOpts, out);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function runNotificationShowLess(client, flags, out) {
|
|
107
|
+
const accountId = requireAccount(flags.account, out);
|
|
108
|
+
const cardUrn = flags.cardUrn ?? "";
|
|
109
|
+
if (flags.preview) {
|
|
110
|
+
const preview = buildPreviewOutput({ method: "notifications.showLess", args: { card_urn: cardUrn }, body: {}, account: accountId });
|
|
111
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const ns = client.account(accountId);
|
|
115
|
+
const outOpts = resolveOutputOpts(flags);
|
|
116
|
+
try {
|
|
117
|
+
const result = await ns.notifications.showLess(cardUrn);
|
|
118
|
+
renderSuccess(result, outOpts, out);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
await handleSdkError(err, outOpts, out);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
var notificationListCommand = defineCommand({
|
|
124
|
+
meta: { name: "list", description: "List the connected account's notification cards, newest first, plus the unread badge and a poll watermark." },
|
|
125
|
+
args: {
|
|
126
|
+
...GLOBAL_FLAGS,
|
|
127
|
+
filter: {
|
|
128
|
+
type: "string",
|
|
129
|
+
description: "Which notification stream to read (default all): all | jobs | mentions | my_posts | my_posts_comments | my_posts_reactions | my_posts_reposts."
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
async run({ args }) {
|
|
133
|
+
const flags = args;
|
|
134
|
+
const cfg = await resolveEffectiveConfig({
|
|
135
|
+
apiKey: flags["api-key"],
|
|
136
|
+
baseUrl: flags["base-url"],
|
|
137
|
+
timeout: flags.timeout,
|
|
138
|
+
account: flags.account,
|
|
139
|
+
profile: flags.profile
|
|
140
|
+
});
|
|
141
|
+
if (!cfg.apiKey) {
|
|
142
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
143
|
+
process.exit(3);
|
|
144
|
+
}
|
|
145
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
146
|
+
const out = buildOutputStreams();
|
|
147
|
+
await runNotificationList(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
var notificationDeleteCommand = defineCommand({
|
|
151
|
+
meta: { name: "delete", description: "Delete one of your notification cards by its card urn. Self-action, idempotent, cannot be undone." },
|
|
152
|
+
args: {
|
|
153
|
+
...WRITE_SINGLE_FLAGS,
|
|
154
|
+
cardUrn: { type: "positional", description: "The card_urn field of a `notification list` item (not object_urn)." }
|
|
155
|
+
},
|
|
156
|
+
async run({ args }) {
|
|
157
|
+
const flags = args;
|
|
158
|
+
const cfg = await resolveEffectiveConfig({
|
|
159
|
+
apiKey: flags["api-key"],
|
|
160
|
+
baseUrl: flags["base-url"],
|
|
161
|
+
timeout: flags.timeout,
|
|
162
|
+
account: flags.account,
|
|
163
|
+
profile: flags.profile
|
|
164
|
+
});
|
|
165
|
+
if (!cfg.apiKey) {
|
|
166
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
167
|
+
process.exit(3);
|
|
168
|
+
}
|
|
169
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
170
|
+
const out = buildOutputStreams();
|
|
171
|
+
await runNotificationDelete(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
var notificationShowLessCommand = defineCommand({
|
|
175
|
+
meta: {
|
|
176
|
+
name: "show-less",
|
|
177
|
+
description: "Apply 'show less like this' to the source of one of your notification cards. For network-activity cards this removes the card, same as delete. Self-action, idempotent, cannot be undone."
|
|
178
|
+
},
|
|
179
|
+
args: {
|
|
180
|
+
...WRITE_SINGLE_FLAGS,
|
|
181
|
+
cardUrn: { type: "positional", description: "The card_urn field of a `notification list` item (not object_urn)." }
|
|
182
|
+
},
|
|
183
|
+
async run({ args }) {
|
|
184
|
+
const flags = args;
|
|
185
|
+
const cfg = await resolveEffectiveConfig({
|
|
186
|
+
apiKey: flags["api-key"],
|
|
187
|
+
baseUrl: flags["base-url"],
|
|
188
|
+
timeout: flags.timeout,
|
|
189
|
+
account: flags.account,
|
|
190
|
+
profile: flags.profile
|
|
191
|
+
});
|
|
192
|
+
if (!cfg.apiKey) {
|
|
193
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
194
|
+
process.exit(3);
|
|
195
|
+
}
|
|
196
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
197
|
+
const out = buildOutputStreams();
|
|
198
|
+
await runNotificationShowLess(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
var notificationCommand = defineCommand({
|
|
202
|
+
meta: { name: "notification", description: "Read and act on LinkedIn notification cards." },
|
|
203
|
+
subCommands: {
|
|
204
|
+
list: notificationListCommand,
|
|
205
|
+
delete: notificationDeleteCommand,
|
|
206
|
+
"show-less": notificationShowLessCommand
|
|
207
|
+
},
|
|
208
|
+
async run() {
|
|
209
|
+
process.stderr.write(
|
|
210
|
+
"Usage: curviate notification <subcommand>\n list [--filter <f>]\n delete <card_urn>\n show-less <card_urn>\n"
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
export {
|
|
215
|
+
notificationCommand,
|
|
216
|
+
runNotificationDelete,
|
|
217
|
+
runNotificationList,
|
|
218
|
+
runNotificationShowLess
|
|
219
|
+
};
|
|
@@ -208,6 +208,66 @@ async function runPostReactions(client, flags, out) {
|
|
|
208
208
|
await handleSdkError(err, outOpts, out);
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
+
async function runPostSaved(client, flags, out) {
|
|
212
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
213
|
+
const accountId = requireAccount(flags.account, out);
|
|
214
|
+
const ns = client.account(accountId);
|
|
215
|
+
const outOpts = resolveOutputOpts(flags);
|
|
216
|
+
const all = flags.all ?? false;
|
|
217
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
218
|
+
const params = buildPaginationParams(flags);
|
|
219
|
+
try {
|
|
220
|
+
if (all) {
|
|
221
|
+
const fn = (p) => ns.posts.listSaved(p);
|
|
222
|
+
for await (const item of streamAll(fn, params, {
|
|
223
|
+
maxPages,
|
|
224
|
+
out,
|
|
225
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
226
|
+
})) {
|
|
227
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
const result = await ns.posts.listSaved(params);
|
|
231
|
+
renderSuccess(result, outOpts, out);
|
|
232
|
+
}
|
|
233
|
+
} catch (err) {
|
|
234
|
+
await handleSdkError(err, outOpts, out);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function runPostSave(client, flags, out) {
|
|
238
|
+
const accountId = requireAccount(flags.account, out);
|
|
239
|
+
const postId = flags.postId ?? "";
|
|
240
|
+
if (flags.preview) {
|
|
241
|
+
const preview = buildPreviewOutput({ method: "posts.save", args: { post_id: postId }, body: {}, account: accountId });
|
|
242
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const ns = client.account(accountId);
|
|
246
|
+
const outOpts = resolveOutputOpts(flags);
|
|
247
|
+
try {
|
|
248
|
+
const result = await ns.posts.save(postId);
|
|
249
|
+
renderSuccess(result, outOpts, out);
|
|
250
|
+
} catch (err) {
|
|
251
|
+
await handleSdkError(err, outOpts, out);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async function runPostUnsave(client, flags, out) {
|
|
255
|
+
const accountId = requireAccount(flags.account, out);
|
|
256
|
+
const postId = flags.postId ?? "";
|
|
257
|
+
if (flags.preview) {
|
|
258
|
+
const preview = buildPreviewOutput({ method: "posts.unsave", args: { post_id: postId }, body: {}, account: accountId });
|
|
259
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const ns = client.account(accountId);
|
|
263
|
+
const outOpts = resolveOutputOpts(flags);
|
|
264
|
+
try {
|
|
265
|
+
const result = await ns.posts.unsave(postId);
|
|
266
|
+
renderSuccess(result, outOpts, out);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
await handleSdkError(err, outOpts, out);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
211
271
|
async function runPostDelete(client, flags, out) {
|
|
212
272
|
const accountId = requireAccount(flags.account, out);
|
|
213
273
|
const postId = flags.postId ?? "";
|
|
@@ -482,6 +542,33 @@ var postUnreactCommand = defineCommand({
|
|
|
482
542
|
await withClient(args, runPostUnreact);
|
|
483
543
|
}
|
|
484
544
|
});
|
|
545
|
+
var postSavedCommand = defineCommand({
|
|
546
|
+
meta: { name: "saved", description: "List your own saved posts (a private bookmark list, newest-saved-first). Each item is a preview (snippet capped at 140 chars)." },
|
|
547
|
+
args: { ...GLOBAL_FLAGS },
|
|
548
|
+
async run({ args }) {
|
|
549
|
+
await withClient(args, runPostSaved);
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
var postSaveCommand = defineCommand({
|
|
553
|
+
meta: { name: "save", description: "Save a post to your private bookmark list. Never notifies the author, never visible to third parties. Idempotent." },
|
|
554
|
+
args: {
|
|
555
|
+
...WRITE_SINGLE_FLAGS,
|
|
556
|
+
postId: { type: "positional", description: "Post id (urn:li:activity:N or a bare numeric id)." }
|
|
557
|
+
},
|
|
558
|
+
async run({ args }) {
|
|
559
|
+
await withClient(args, runPostSave);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
var postUnsaveCommand = defineCommand({
|
|
563
|
+
meta: { name: "unsave", description: "Remove a post from your saved-posts bookmark list. Idempotent." },
|
|
564
|
+
args: {
|
|
565
|
+
...WRITE_SINGLE_FLAGS,
|
|
566
|
+
postId: { type: "positional", description: "Post id (urn:li:activity:N or a bare numeric id)." }
|
|
567
|
+
},
|
|
568
|
+
async run({ args }) {
|
|
569
|
+
await withClient(args, runPostUnsave);
|
|
570
|
+
}
|
|
571
|
+
});
|
|
485
572
|
var postUserPostsCommand = defineCommand({
|
|
486
573
|
meta: { name: "user-posts", description: "List a member's own posts (accepts 'me'). A very recent create/delete may take a few minutes to appear or clear here (LinkedIn-side indexing); `post get <post_id>` reflects it immediately." },
|
|
487
574
|
args: {
|
|
@@ -511,12 +598,15 @@ var postCommand = defineCommand({
|
|
|
511
598
|
reactions: postReactionsCommand,
|
|
512
599
|
delete: postDeleteCommand,
|
|
513
600
|
unreact: postUnreactCommand,
|
|
601
|
+
saved: postSavedCommand,
|
|
602
|
+
save: postSaveCommand,
|
|
603
|
+
unsave: postUnsaveCommand,
|
|
514
604
|
"user-posts": postUserPostsCommand,
|
|
515
605
|
"user-reactions": postUserReactionsCommand
|
|
516
606
|
},
|
|
517
607
|
async run() {
|
|
518
608
|
process.stderr.write(
|
|
519
|
-
'Usage: curviate post <subcommand>\n get <post_id>\n create "<text>" [--attach <file>\u2026]\n react <post_id> <reaction> [--as-organization <org_id>]\n reactions <post_id>\n delete <post_id>\n unreact <post_id> <reaction>\n user-posts <user_id>\n user-reactions <user_id>\n\nComment operations moved to the `comment` command group.\n'
|
|
609
|
+
'Usage: curviate post <subcommand>\n get <post_id>\n create "<text>" [--attach <file>\u2026]\n react <post_id> <reaction> [--as-organization <org_id>]\n reactions <post_id>\n delete <post_id>\n unreact <post_id> <reaction>\n saved\n save <post_id>\n unsave <post_id>\n user-posts <user_id>\n user-reactions <user_id>\n\nComment operations moved to the `comment` command group.\n'
|
|
520
610
|
);
|
|
521
611
|
}
|
|
522
612
|
});
|
|
@@ -527,7 +617,10 @@ export {
|
|
|
527
617
|
runPostGet,
|
|
528
618
|
runPostReact,
|
|
529
619
|
runPostReactions,
|
|
620
|
+
runPostSave,
|
|
621
|
+
runPostSaved,
|
|
530
622
|
runPostUnreact,
|
|
623
|
+
runPostUnsave,
|
|
531
624
|
runPostUserPosts,
|
|
532
625
|
runPostUserReactions
|
|
533
626
|
};
|