@curviate/cli 0.18.1 → 0.20.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 +123 -0
- package/dist/{account-EGJJNBXW.js → account-2SOSCEB6.js} +26 -26
- package/dist/{chunk-TMU3CSPR.js → chunk-DW2HCRXJ.js} +1 -1
- package/dist/{chunk-M33MI53G.js → chunk-HDQUEFD2.js} +1 -1
- package/dist/chunk-HOQ7EUHJ.js +50 -0
- package/dist/{chunk-KVV6LZ7E.js → chunk-IGCQNDIG.js} +53 -17
- package/dist/cli.js +33 -33
- package/dist/{comment-VT6PO4MN.js → comment-AXDINBPS.js} +3 -3
- package/dist/{company-BVXX4FGX.js → company-BX4VDXZX.js} +398 -16
- package/dist/{config-P5CPF5WC.js → config-3O4N2XSH.js} +2 -2
- package/dist/{connect-6PU7QCOL.js → connect-KWOJKCIB.js} +36 -15
- package/dist/feed-4ROKUBG5.js +127 -0
- package/dist/group-L7TQEEFN.js +236 -0
- package/dist/{inbox-DRJ6ENXC.js → inbox-GMGZVDTQ.js} +69 -11
- package/dist/{inboxes-MTPWLP5F.js → inboxes-YVYLSM5W.js} +4 -4
- package/dist/{job-EIXBJXLW.js → job-TYBA2DUQ.js} +7 -7
- package/dist/{login-GDLWR542.js → login-W7NCDZOQ.js} +2 -2
- package/dist/{message-UWMRE2SJ.js → message-C6FV6JH6.js} +6 -3
- package/dist/notification-45XFT3S4.js +219 -0
- package/dist/{post-N3GQDIQJ.js → post-RETV3WUG.js} +102 -9
- package/dist/{profile-XWSRUYRW.js → profile-A2TWF4HB.js} +121 -15
- package/dist/{recruiter-MVPSTH2V.js → recruiter-FQAKY6Z2.js} +30 -30
- package/dist/{sales-nav-TMXWDKSE.js → sales-nav-SSJIZUNB.js} +16 -16
- package/dist/{search-ZQUKLQ6T.js → search-DH6BJFQC.js} +213 -12
- package/dist/{webhook-QFSZN3P2.js → webhook-LED6AKF3.js} +50 -19
- package/package.json +4 -4
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
nearestSubcommand
|
|
4
|
+
} from "./chunk-HOQ7EUHJ.js";
|
|
2
5
|
import {
|
|
3
6
|
slimInviteReceived,
|
|
4
7
|
slimInviteReceivedItem,
|
|
@@ -21,11 +24,11 @@ import {
|
|
|
21
24
|
renderSuccess,
|
|
22
25
|
renderUnexpectedError,
|
|
23
26
|
resolveEffectiveConfig
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-HDQUEFD2.js";
|
|
25
28
|
import {
|
|
26
29
|
GLOBAL_FLAGS,
|
|
27
30
|
WRITE_FLAGS
|
|
28
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-DW2HCRXJ.js";
|
|
29
32
|
|
|
30
33
|
// src/commands/connect.ts
|
|
31
34
|
import { defineCommand } from "citty";
|
|
@@ -256,7 +259,7 @@ async function runConnectCancel(client, flags, out) {
|
|
|
256
259
|
var connectSentCommand = defineCommand({
|
|
257
260
|
meta: {
|
|
258
261
|
name: "sent",
|
|
259
|
-
description: "Returns pending sent invitations only
|
|
262
|
+
description: "Returns pending sent invitations only. Accepted and declined invitations are not returned (LinkedIn API limitation). Use `id` with `connect cancel`; use `user.id` (native member URN; the sent-variant carries no public slug) to identify the recipient. `created_at` is the platform's own ISO-8601 timestamp (not an approximation). No total count is available; use `connect sent --all` and count client-side. A very recently sent invitation may take a few minutes to appear here (LinkedIn-side indexing)."
|
|
260
263
|
},
|
|
261
264
|
args: { ...GLOBAL_FLAGS },
|
|
262
265
|
async run({ args }) {
|
|
@@ -269,7 +272,7 @@ var connectSentCommand = defineCommand({
|
|
|
269
272
|
profile: flags.profile
|
|
270
273
|
});
|
|
271
274
|
if (!cfg.apiKey) {
|
|
272
|
-
process.stderr.write("error: no API key
|
|
275
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
273
276
|
process.exit(3);
|
|
274
277
|
}
|
|
275
278
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -280,7 +283,7 @@ var connectSentCommand = defineCommand({
|
|
|
280
283
|
var connectReceivedCommand = defineCommand({
|
|
281
284
|
meta: {
|
|
282
285
|
name: "received",
|
|
283
|
-
description: "Returns pending received invitations only
|
|
286
|
+
description: "Returns pending received invitations only. Already-handled invitations are not returned. The `user.*` fields (`public_identifier`, `display_name`, `first_name`, `last_name`) identify who sent the request. Use the `id` field with `connect accept` or `connect decline`. A very recently received invitation may take a few minutes to appear here (LinkedIn-side indexing)."
|
|
284
287
|
},
|
|
285
288
|
args: { ...GLOBAL_FLAGS },
|
|
286
289
|
async run({ args }) {
|
|
@@ -293,7 +296,7 @@ var connectReceivedCommand = defineCommand({
|
|
|
293
296
|
profile: flags.profile
|
|
294
297
|
});
|
|
295
298
|
if (!cfg.apiKey) {
|
|
296
|
-
process.stderr.write("error: no API key
|
|
299
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
297
300
|
process.exit(3);
|
|
298
301
|
}
|
|
299
302
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -307,7 +310,7 @@ var connectAcceptCommand = defineCommand({
|
|
|
307
310
|
...WRITE_FLAGS,
|
|
308
311
|
id: {
|
|
309
312
|
type: "positional",
|
|
310
|
-
description: "Invitation id to accept
|
|
313
|
+
description: "Invitation id to accept. Use the `id` field from `connect received`."
|
|
311
314
|
}
|
|
312
315
|
},
|
|
313
316
|
async run({ args }) {
|
|
@@ -320,7 +323,7 @@ var connectAcceptCommand = defineCommand({
|
|
|
320
323
|
profile: flags.profile
|
|
321
324
|
});
|
|
322
325
|
if (!cfg.apiKey) {
|
|
323
|
-
process.stderr.write("error: no API key
|
|
326
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
324
327
|
process.exit(3);
|
|
325
328
|
}
|
|
326
329
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -334,7 +337,7 @@ var connectDeclineCommand = defineCommand({
|
|
|
334
337
|
...WRITE_FLAGS,
|
|
335
338
|
id: {
|
|
336
339
|
type: "positional",
|
|
337
|
-
description: "Invitation id to decline
|
|
340
|
+
description: "Invitation id to decline. Use the `id` field from `connect received`."
|
|
338
341
|
}
|
|
339
342
|
},
|
|
340
343
|
async run({ args }) {
|
|
@@ -347,7 +350,7 @@ var connectDeclineCommand = defineCommand({
|
|
|
347
350
|
profile: flags.profile
|
|
348
351
|
});
|
|
349
352
|
if (!cfg.apiKey) {
|
|
350
|
-
process.stderr.write("error: no API key
|
|
353
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
351
354
|
process.exit(3);
|
|
352
355
|
}
|
|
353
356
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -371,7 +374,7 @@ var connectCancelCommand = defineCommand({
|
|
|
371
374
|
profile: flags.profile
|
|
372
375
|
});
|
|
373
376
|
if (!cfg.apiKey) {
|
|
374
|
-
process.stderr.write("error: no API key
|
|
377
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
375
378
|
process.exit(3);
|
|
376
379
|
}
|
|
377
380
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -379,6 +382,24 @@ var connectCancelCommand = defineCommand({
|
|
|
379
382
|
await runConnectCancel(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
380
383
|
}
|
|
381
384
|
});
|
|
385
|
+
var CONNECT_SUBCOMMANDS = ["sent", "received", "accept", "decline", "cancel"];
|
|
386
|
+
var CONNECT_USAGE = "Usage: curviate connect <id> [--note <text>]\n curviate connect sent\n curviate connect received\n curviate connect accept <invitation_id>\n curviate connect decline <invitation_id>\n curviate connect cancel <invitation_id>\n";
|
|
387
|
+
function guardBareConnectForm(id, out) {
|
|
388
|
+
const suggestion = nearestSubcommand(id, [...CONNECT_SUBCOMMANDS]);
|
|
389
|
+
if (suggestion === null) return;
|
|
390
|
+
out.stderr.write(
|
|
391
|
+
`error: \`${id}\` looks like a mistyped \`${suggestion}\` subcommand, and \`curviate connect <id>\` SENDS a connection invitation, so this is refused rather than guessed.
|
|
392
|
+
`
|
|
393
|
+
);
|
|
394
|
+
out.stderr.write(`hint: did you mean \`curviate connect ${suggestion}\`?
|
|
395
|
+
`);
|
|
396
|
+
out.stderr.write(
|
|
397
|
+
`hint: if \`${id}\` really is the profile you meant, pass the full profile URL (https://www.linkedin.com/in/${id}) or the provider id instead.
|
|
398
|
+
`
|
|
399
|
+
);
|
|
400
|
+
out.stderr.write(CONNECT_USAGE);
|
|
401
|
+
process.exit(2);
|
|
402
|
+
}
|
|
382
403
|
var connectCommand = defineCommand({
|
|
383
404
|
meta: {
|
|
384
405
|
name: "connect",
|
|
@@ -406,11 +427,10 @@ var connectCommand = defineCommand({
|
|
|
406
427
|
async run({ args }) {
|
|
407
428
|
const flags = args;
|
|
408
429
|
if (!flags.id) {
|
|
409
|
-
process.stderr.write(
|
|
410
|
-
"Usage: curviate connect <id> [--note <text>]\n curviate connect sent\n curviate connect received\n curviate connect accept <invitation_id>\n curviate connect decline <invitation_id>\n curviate connect cancel <invitation_id>\n"
|
|
411
|
-
);
|
|
430
|
+
process.stderr.write(CONNECT_USAGE);
|
|
412
431
|
process.exit(2);
|
|
413
432
|
}
|
|
433
|
+
guardBareConnectForm(flags.id, buildOutputStreams());
|
|
414
434
|
const cfg = await resolveEffectiveConfig({
|
|
415
435
|
apiKey: flags["api-key"],
|
|
416
436
|
baseUrl: flags["base-url"],
|
|
@@ -419,7 +439,7 @@ var connectCommand = defineCommand({
|
|
|
419
439
|
profile: flags.profile
|
|
420
440
|
});
|
|
421
441
|
if (!cfg.apiKey) {
|
|
422
|
-
process.stderr.write("error: no API key
|
|
442
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
423
443
|
process.exit(3);
|
|
424
444
|
}
|
|
425
445
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -429,6 +449,7 @@ var connectCommand = defineCommand({
|
|
|
429
449
|
});
|
|
430
450
|
export {
|
|
431
451
|
connectCommand,
|
|
452
|
+
guardBareConnectForm,
|
|
432
453
|
runConnectAccept,
|
|
433
454
|
runConnectCancel,
|
|
434
455
|
runConnectDecline,
|
|
@@ -0,0 +1,127 @@
|
|
|
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-HDQUEFD2.js";
|
|
13
|
+
import {
|
|
14
|
+
GLOBAL_FLAGS
|
|
15
|
+
} from "./chunk-DW2HCRXJ.js";
|
|
16
|
+
|
|
17
|
+
// src/commands/feed.ts
|
|
18
|
+
import { defineCommand } from "citty";
|
|
19
|
+
function buildOutputStreams() {
|
|
20
|
+
return {
|
|
21
|
+
stdout: { write: (s) => process.stdout.write(s) },
|
|
22
|
+
stderr: { write: (s) => process.stderr.write(s) }
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function requireAccount(account, out) {
|
|
26
|
+
if (!account) {
|
|
27
|
+
out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
|
|
28
|
+
process.exit(2);
|
|
29
|
+
}
|
|
30
|
+
return account;
|
|
31
|
+
}
|
|
32
|
+
function rejectPreviewOnRead(preview, out) {
|
|
33
|
+
if (preview) {
|
|
34
|
+
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
35
|
+
process.exit(2);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function resolveOutputOpts(flags) {
|
|
39
|
+
return {
|
|
40
|
+
json: (flags.json ?? false) || !process.stdout.isTTY,
|
|
41
|
+
isTTY: process.stdout.isTTY ?? false,
|
|
42
|
+
fields: flags.fields,
|
|
43
|
+
verbose: flags.verbose ?? false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function handleSdkError(err, outOpts, out) {
|
|
47
|
+
const { CurviateError } = await import("@curviate/sdk");
|
|
48
|
+
if (err instanceof CurviateError) {
|
|
49
|
+
const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
|
|
50
|
+
renderError(err, outOpts, out);
|
|
51
|
+
process.exit(getExitCode(err.code));
|
|
52
|
+
}
|
|
53
|
+
renderUnexpectedError(err, out);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
async function runFeedHome(client, flags, out) {
|
|
57
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
58
|
+
const accountId = requireAccount(flags.account, out);
|
|
59
|
+
const ns = client.account(accountId);
|
|
60
|
+
const outOpts = resolveOutputOpts(flags);
|
|
61
|
+
const all = flags.all ?? false;
|
|
62
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
63
|
+
const params = {};
|
|
64
|
+
if (flags.sort) params["sort"] = flags.sort;
|
|
65
|
+
if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
|
|
66
|
+
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
67
|
+
try {
|
|
68
|
+
if (all) {
|
|
69
|
+
const fn = (p) => ns.feed.home(p);
|
|
70
|
+
for await (const item of streamAll(fn, params, {
|
|
71
|
+
maxPages,
|
|
72
|
+
out,
|
|
73
|
+
pageDelayMs: pageDelayFromFlags(flags)
|
|
74
|
+
})) {
|
|
75
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
const result = await ns.feed.home(params);
|
|
79
|
+
renderSuccess(result, outOpts, out);
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
await handleSdkError(err, outOpts, out);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
var FEED_ARGS = {
|
|
86
|
+
...GLOBAL_FLAGS,
|
|
87
|
+
sort: {
|
|
88
|
+
type: "string",
|
|
89
|
+
description: "Sort order: recent (default, reverse-chronological, always available) or relevant (LinkedIn's ranked 'top' feed, shared throttled budget). Ignored when --cursor is supplied."
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var feedHomeCommand = defineCommand({
|
|
93
|
+
meta: { name: "home", description: "Read the connected account's LinkedIn home feed as agent-actionable posts." },
|
|
94
|
+
args: FEED_ARGS,
|
|
95
|
+
async run({ args }) {
|
|
96
|
+
const flags = args;
|
|
97
|
+
const cfg = await resolveEffectiveConfig({
|
|
98
|
+
apiKey: flags["api-key"],
|
|
99
|
+
baseUrl: flags["base-url"],
|
|
100
|
+
timeout: flags.timeout,
|
|
101
|
+
account: flags.account,
|
|
102
|
+
profile: flags.profile
|
|
103
|
+
});
|
|
104
|
+
if (!cfg.apiKey) {
|
|
105
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
106
|
+
process.exit(3);
|
|
107
|
+
}
|
|
108
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
109
|
+
const out = buildOutputStreams();
|
|
110
|
+
await runFeedHome(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
var feedCommand = defineCommand({
|
|
114
|
+
meta: { name: "feed", description: "Read the connected account's LinkedIn home feed as agent-actionable posts." },
|
|
115
|
+
subCommands: {
|
|
116
|
+
home: feedHomeCommand
|
|
117
|
+
},
|
|
118
|
+
async run() {
|
|
119
|
+
process.stderr.write(
|
|
120
|
+
"Usage: curviate feed <subcommand>\n home [--sort recent|relevant] [--limit] [--cursor] [--all]\n"
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
export {
|
|
125
|
+
feedCommand,
|
|
126
|
+
runFeedHome
|
|
127
|
+
};
|
|
@@ -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-HDQUEFD2.js";
|
|
13
|
+
import {
|
|
14
|
+
GLOBAL_FLAGS,
|
|
15
|
+
READ_SINGLE_FLAGS
|
|
16
|
+
} from "./chunk-DW2HCRXJ.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 --target 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, 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, 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, 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 [--target <slug>]\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
|
+
};
|
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
renderSuccess,
|
|
16
16
|
renderUnexpectedError,
|
|
17
17
|
resolveEffectiveConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-HDQUEFD2.js";
|
|
19
19
|
import {
|
|
20
20
|
GLOBAL_FLAGS,
|
|
21
21
|
READ_SINGLE_FLAGS,
|
|
22
22
|
WRITE_SINGLE_FLAGS
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-DW2HCRXJ.js";
|
|
24
24
|
|
|
25
25
|
// src/commands/inbox.ts
|
|
26
26
|
import { defineCommand } from "citty";
|
|
@@ -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: {
|
|
@@ -210,7 +241,7 @@ var inboxListCommand = defineCommand({
|
|
|
210
241
|
profile: flags.profile
|
|
211
242
|
});
|
|
212
243
|
if (!cfg.apiKey) {
|
|
213
|
-
process.stderr.write("error: no API key
|
|
244
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
214
245
|
process.exit(3);
|
|
215
246
|
}
|
|
216
247
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -235,7 +266,7 @@ var inboxGetCommand = defineCommand({
|
|
|
235
266
|
profile: flags.profile
|
|
236
267
|
});
|
|
237
268
|
if (!cfg.apiKey) {
|
|
238
|
-
process.stderr.write("error: no API key
|
|
269
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
239
270
|
process.exit(3);
|
|
240
271
|
}
|
|
241
272
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -260,7 +291,7 @@ var inboxMarkReadCommand = defineCommand({
|
|
|
260
291
|
profile: flags.profile
|
|
261
292
|
});
|
|
262
293
|
if (!cfg.apiKey) {
|
|
263
|
-
process.stderr.write("error: no API key
|
|
294
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
264
295
|
process.exit(3);
|
|
265
296
|
}
|
|
266
297
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -276,11 +307,11 @@ var inboxMessagesCommand = defineCommand({
|
|
|
276
307
|
chatId: { type: "positional", description: "Chat ID." },
|
|
277
308
|
before: {
|
|
278
309
|
type: "string",
|
|
279
|
-
description: "Return messages before this timestamp (ISO-8601, UTC
|
|
310
|
+
description: "Return messages before this timestamp (ISO-8601, UTC; Z suffix required, e.g. 2025-01-01T00:00:00Z)."
|
|
280
311
|
},
|
|
281
312
|
after: {
|
|
282
313
|
type: "string",
|
|
283
|
-
description: "Return messages after this timestamp (ISO-8601, UTC
|
|
314
|
+
description: "Return messages after this timestamp (ISO-8601, UTC; Z suffix required, e.g. 2025-01-01T00:00:00Z)."
|
|
284
315
|
}
|
|
285
316
|
},
|
|
286
317
|
async run({ args }) {
|
|
@@ -293,7 +324,7 @@ var inboxMessagesCommand = defineCommand({
|
|
|
293
324
|
profile: flags.profile
|
|
294
325
|
});
|
|
295
326
|
if (!cfg.apiKey) {
|
|
296
|
-
process.stderr.write("error: no API key
|
|
327
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
297
328
|
process.exit(3);
|
|
298
329
|
}
|
|
299
330
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -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, 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
|
};
|