@curviate/cli 0.1.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 +22 -0
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/account-YOW2MCZS.js +639 -0
- package/dist/chunk-2NCPJJPC.js +140 -0
- package/dist/chunk-6JNCLLNY.js +195 -0
- package/dist/chunk-BNUTM6KD.js +33 -0
- package/dist/chunk-Q43HZUN3.js +29 -0
- package/dist/chunk-R3VLWLVV.js +23 -0
- package/dist/chunk-SND3NHCT.js +46 -0
- package/dist/chunk-UWO2D4HW.js +34 -0
- package/dist/cli.js +159 -0
- package/dist/company-IKVDW7MX.js +82 -0
- package/dist/config-4JOXBFYX.js +262 -0
- package/dist/connect-HLDHFBGX.js +348 -0
- package/dist/exit-codes-NFIR57ZA.js +57 -0
- package/dist/inbox-JBLYJMV2.js +294 -0
- package/dist/login-VWJEBBFU.js +122 -0
- package/dist/message-IK7VGB63.js +566 -0
- package/dist/post-EAAGVR5D.js +496 -0
- package/dist/profile-WXA3NC7D.js +352 -0
- package/dist/recruiter-TGCV36EH.js +984 -0
- package/dist/sales-nav-XGFO5I6F.js +488 -0
- package/dist/search-LHPTHPWH.js +354 -0
- package/dist/webhook-QM5LGAUF.js +445 -0
- package/package.json +54 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildPreviewOutput
|
|
4
|
+
} from "./chunk-R3VLWLVV.js";
|
|
5
|
+
import {
|
|
6
|
+
streamAll
|
|
7
|
+
} from "./chunk-SND3NHCT.js";
|
|
8
|
+
import {
|
|
9
|
+
createClient,
|
|
10
|
+
renderError,
|
|
11
|
+
renderSuccess,
|
|
12
|
+
renderUnexpectedError,
|
|
13
|
+
resolveEffectiveConfig
|
|
14
|
+
} from "./chunk-2NCPJJPC.js";
|
|
15
|
+
import {
|
|
16
|
+
GLOBAL_FLAGS
|
|
17
|
+
} from "./chunk-6JNCLLNY.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/account.ts
|
|
20
|
+
import { defineCommand } from "citty";
|
|
21
|
+
function rejectPreviewOnRead(preview, out) {
|
|
22
|
+
if (preview) {
|
|
23
|
+
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
24
|
+
process.exit(2);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function rejectAllOnNonPaginated(all, out) {
|
|
28
|
+
if (all) {
|
|
29
|
+
out.stderr.write("error: --all is not supported on non-paginated commands.\n");
|
|
30
|
+
process.exit(2);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function buildOutputStreams() {
|
|
34
|
+
return {
|
|
35
|
+
stdout: { write: (s) => process.stdout.write(s) },
|
|
36
|
+
stderr: { write: (s) => process.stderr.write(s) }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function resolveOutputOpts(flags) {
|
|
40
|
+
return {
|
|
41
|
+
json: (flags.json ?? false) || !process.stdout.isTTY,
|
|
42
|
+
isTTY: process.stdout.isTTY ?? false,
|
|
43
|
+
fields: flags.fields
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function handleError(err, outOpts, out) {
|
|
47
|
+
const { CurviateError } = await import("@curviate/sdk");
|
|
48
|
+
if (err instanceof CurviateError) {
|
|
49
|
+
const { getExitCode } = await import("./exit-codes-NFIR57ZA.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 runAccountList(client, flags, out) {
|
|
57
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
58
|
+
const outOpts = resolveOutputOpts(flags);
|
|
59
|
+
const all = flags.all ?? false;
|
|
60
|
+
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
61
|
+
const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
|
|
62
|
+
const cursor = flags.cursor;
|
|
63
|
+
const params = {};
|
|
64
|
+
if (limit !== void 0) params["limit"] = limit;
|
|
65
|
+
if (cursor) params["cursor"] = cursor;
|
|
66
|
+
try {
|
|
67
|
+
if (all) {
|
|
68
|
+
const fn = (p) => client.accounts.list(p);
|
|
69
|
+
for await (const item of streamAll(fn, params, {
|
|
70
|
+
maxPages,
|
|
71
|
+
onTruncated: (msg) => out.stderr.write(msg + "\n")
|
|
72
|
+
})) {
|
|
73
|
+
out.stdout.write(JSON.stringify(item) + "\n");
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
const result = await client.accounts.list(params);
|
|
77
|
+
renderSuccess(result, outOpts, out);
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
await handleError(err, outOpts, out);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function runAccountGet(client, flags, out) {
|
|
84
|
+
rejectPreviewOnRead(flags.preview, out);
|
|
85
|
+
rejectAllOnNonPaginated(flags.all, out);
|
|
86
|
+
const accountId = flags["account-id"] ?? "";
|
|
87
|
+
const outOpts = resolveOutputOpts(flags);
|
|
88
|
+
try {
|
|
89
|
+
const result = await client.accounts.get(accountId);
|
|
90
|
+
renderSuccess(result, outOpts, out);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
await handleError(err, outOpts, out);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function buildAuthBody(flags) {
|
|
96
|
+
const body = {};
|
|
97
|
+
if (flags["auth-method"]) body["auth_method"] = flags["auth-method"];
|
|
98
|
+
if (flags["user-agent"]) body["user_agent"] = flags["user-agent"];
|
|
99
|
+
if (flags["recruiter-contract-id"]) body["recruiter_contract_id"] = flags["recruiter-contract-id"];
|
|
100
|
+
if (flags["auth-method"] === "credentials" && (flags.email || flags.password)) {
|
|
101
|
+
body["credentials"] = {
|
|
102
|
+
...flags.email ? { email: flags.email } : {},
|
|
103
|
+
...flags.password ? { password: flags.password } : {}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (flags["auth-method"] === "cookie" && (flags["li-at"] || flags["li-a"])) {
|
|
107
|
+
body["cookie"] = {
|
|
108
|
+
...flags["li-at"] ? { li_at: flags["li-at"] } : {},
|
|
109
|
+
...flags["li-a"] ? { li_a: flags["li-a"] } : {}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (flags.country) body["country"] = flags.country;
|
|
113
|
+
if (flags.ip) body["ip"] = flags.ip;
|
|
114
|
+
if (flags["proxy-host"]) {
|
|
115
|
+
body["proxy"] = {
|
|
116
|
+
protocol: flags["proxy-protocol"] ?? "http",
|
|
117
|
+
host: flags["proxy-host"],
|
|
118
|
+
port: flags["proxy-port"] ? parseInt(flags["proxy-port"], 10) : 80,
|
|
119
|
+
...flags["proxy-username"] ? { username: flags["proxy-username"] } : {},
|
|
120
|
+
...flags["proxy-password"] ? { password: flags["proxy-password"] } : {}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return body;
|
|
124
|
+
}
|
|
125
|
+
async function runAccountLink(client, flags, out) {
|
|
126
|
+
if (!flags["seat-id"]) {
|
|
127
|
+
out.stderr.write("error: --seat-id is required for account link.\n");
|
|
128
|
+
process.exit(2);
|
|
129
|
+
}
|
|
130
|
+
if (!flags["auth-method"]) {
|
|
131
|
+
out.stderr.write("error: --auth-method is required for account link (credentials | cookie).\n");
|
|
132
|
+
process.exit(2);
|
|
133
|
+
}
|
|
134
|
+
const body = {
|
|
135
|
+
seat_id: flags["seat-id"],
|
|
136
|
+
...buildAuthBody(flags)
|
|
137
|
+
};
|
|
138
|
+
const outOpts = resolveOutputOpts(flags);
|
|
139
|
+
if (flags.preview) {
|
|
140
|
+
const preview = buildPreviewOutput({ method: "accounts.link", args: {}, body });
|
|
141
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const result = await client.accounts.link(body);
|
|
146
|
+
renderSuccess(result, outOpts, out);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
await handleError(err, outOpts, out);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function runAccountConnectLink(client, flags, out) {
|
|
152
|
+
const body = {};
|
|
153
|
+
if (flags["seat-id"]) body["seat_id"] = flags["seat-id"];
|
|
154
|
+
if (flags["account-id"]) body["account_id"] = flags["account-id"];
|
|
155
|
+
if (flags.purpose) body["purpose"] = flags.purpose;
|
|
156
|
+
if (flags["expires-in-seconds"]) body["expires_in_seconds"] = parseInt(flags["expires-in-seconds"], 10);
|
|
157
|
+
if (flags["redirect-url"]) body["redirect_url"] = flags["redirect-url"];
|
|
158
|
+
const outOpts = resolveOutputOpts(flags);
|
|
159
|
+
if (flags.preview) {
|
|
160
|
+
const preview = buildPreviewOutput({ method: "accounts.createConnectLink", args: {}, body });
|
|
161
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const result = await client.accounts.createConnectLink(body);
|
|
166
|
+
renderSuccess(result, outOpts, out);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
await handleError(err, outOpts, out);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function runAccountReconnect(client, flags, out) {
|
|
172
|
+
if (!flags["auth-method"]) {
|
|
173
|
+
out.stderr.write("error: --auth-method is required for account reconnect (credentials | cookie).\n");
|
|
174
|
+
process.exit(2);
|
|
175
|
+
}
|
|
176
|
+
const accountId = flags["account-id"] ?? "";
|
|
177
|
+
const body = buildAuthBody(flags);
|
|
178
|
+
const outOpts = resolveOutputOpts(flags);
|
|
179
|
+
if (flags.preview) {
|
|
180
|
+
const preview = buildPreviewOutput({
|
|
181
|
+
method: "accounts.reconnect",
|
|
182
|
+
args: { accountId },
|
|
183
|
+
body
|
|
184
|
+
});
|
|
185
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
const result = await client.accounts.reconnect(accountId, body);
|
|
190
|
+
renderSuccess(result, outOpts, out);
|
|
191
|
+
} catch (err) {
|
|
192
|
+
await handleError(err, outOpts, out);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async function runAccountRefresh(client, flags, out) {
|
|
196
|
+
const accountId = flags["account-id"] ?? "";
|
|
197
|
+
const outOpts = resolveOutputOpts(flags);
|
|
198
|
+
if (flags.preview) {
|
|
199
|
+
const preview = buildPreviewOutput({
|
|
200
|
+
method: "accounts.refresh",
|
|
201
|
+
args: { accountId },
|
|
202
|
+
body: {}
|
|
203
|
+
});
|
|
204
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const result = await client.accounts.refresh(accountId);
|
|
209
|
+
renderSuccess(result, outOpts, out);
|
|
210
|
+
} catch (err) {
|
|
211
|
+
await handleError(err, outOpts, out);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async function runAccountUpdate(client, flags, out) {
|
|
215
|
+
const accountId = flags["account-id"] ?? "";
|
|
216
|
+
const body = {};
|
|
217
|
+
if (flags.country) body["country"] = flags.country;
|
|
218
|
+
if (flags.ip) body["ip"] = flags.ip;
|
|
219
|
+
if (flags["proxy-host"]) {
|
|
220
|
+
body["proxy"] = {
|
|
221
|
+
protocol: flags["proxy-protocol"] ?? "http",
|
|
222
|
+
host: flags["proxy-host"],
|
|
223
|
+
port: flags["proxy-port"] ? parseInt(flags["proxy-port"], 10) : 80,
|
|
224
|
+
...flags["proxy-username"] ? { username: flags["proxy-username"] } : {},
|
|
225
|
+
...flags["proxy-password"] ? { password: flags["proxy-password"] } : {}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const outOpts = resolveOutputOpts(flags);
|
|
229
|
+
if (flags.preview) {
|
|
230
|
+
const preview = buildPreviewOutput({
|
|
231
|
+
method: "accounts.update",
|
|
232
|
+
args: { accountId },
|
|
233
|
+
body
|
|
234
|
+
});
|
|
235
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
const result = await client.accounts.update(accountId, body);
|
|
240
|
+
renderSuccess(result, outOpts, out);
|
|
241
|
+
} catch (err) {
|
|
242
|
+
await handleError(err, outOpts, out);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async function runAccountDisconnect(client, flags, out) {
|
|
246
|
+
const accountId = flags["account-id"] ?? "";
|
|
247
|
+
const outOpts = resolveOutputOpts(flags);
|
|
248
|
+
if (flags.preview) {
|
|
249
|
+
const preview = buildPreviewOutput({
|
|
250
|
+
method: "accounts.disconnect",
|
|
251
|
+
args: { accountId },
|
|
252
|
+
body: {}
|
|
253
|
+
});
|
|
254
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
const result = await client.accounts.disconnect(accountId);
|
|
259
|
+
renderSuccess(result, outOpts, out);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
await handleError(err, outOpts, out);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function runAccountCheckpointSubmit(client, flags, out) {
|
|
265
|
+
if (!flags.checkpoint) {
|
|
266
|
+
out.stderr.write("error: --checkpoint is required (the provisional account_id from the 202 response).\n");
|
|
267
|
+
process.exit(2);
|
|
268
|
+
}
|
|
269
|
+
if (!flags.code) {
|
|
270
|
+
out.stderr.write("error: --code is required (the OTP / 2FA code).\n");
|
|
271
|
+
process.exit(2);
|
|
272
|
+
}
|
|
273
|
+
const body = {
|
|
274
|
+
account_id: flags.checkpoint,
|
|
275
|
+
code: flags.code
|
|
276
|
+
};
|
|
277
|
+
const outOpts = resolveOutputOpts(flags);
|
|
278
|
+
if (flags.preview) {
|
|
279
|
+
const preview = buildPreviewOutput({
|
|
280
|
+
method: "accounts.submitCheckpoint",
|
|
281
|
+
args: {},
|
|
282
|
+
body
|
|
283
|
+
});
|
|
284
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const result = await client.accounts.submitCheckpoint(body);
|
|
289
|
+
renderSuccess(result, outOpts, out);
|
|
290
|
+
} catch (err) {
|
|
291
|
+
await handleError(err, outOpts, out);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async function runAccountCheckpointPoll(client, flags, out) {
|
|
295
|
+
if (!flags.checkpoint) {
|
|
296
|
+
out.stderr.write("error: --checkpoint is required (the provisional account_id from the 202 response).\n");
|
|
297
|
+
process.exit(2);
|
|
298
|
+
}
|
|
299
|
+
const body = {
|
|
300
|
+
account_id: flags.checkpoint
|
|
301
|
+
};
|
|
302
|
+
const outOpts = resolveOutputOpts(flags);
|
|
303
|
+
if (flags.preview) {
|
|
304
|
+
const preview = buildPreviewOutput({
|
|
305
|
+
method: "accounts.pollCheckpoint",
|
|
306
|
+
args: {},
|
|
307
|
+
body
|
|
308
|
+
});
|
|
309
|
+
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
try {
|
|
313
|
+
const result = await client.accounts.pollCheckpoint(body);
|
|
314
|
+
renderSuccess(result, outOpts, out);
|
|
315
|
+
} catch (err) {
|
|
316
|
+
await handleError(err, outOpts, out);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
var accountListCommand = defineCommand({
|
|
320
|
+
meta: { name: "list", description: "List connected LinkedIn accounts." },
|
|
321
|
+
args: { ...GLOBAL_FLAGS },
|
|
322
|
+
async run({ args }) {
|
|
323
|
+
const flags = args;
|
|
324
|
+
const cfg = await resolveEffectiveConfig({
|
|
325
|
+
apiKey: flags["api-key"],
|
|
326
|
+
baseUrl: flags["base-url"],
|
|
327
|
+
timeout: flags.timeout,
|
|
328
|
+
profile: flags.profile
|
|
329
|
+
});
|
|
330
|
+
if (!cfg.apiKey) {
|
|
331
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
332
|
+
process.exit(3);
|
|
333
|
+
}
|
|
334
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
335
|
+
const out = buildOutputStreams();
|
|
336
|
+
await runAccountList(client, flags, out);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
var accountGetCommand = defineCommand({
|
|
340
|
+
meta: { name: "get", description: "Get a connected LinkedIn account." },
|
|
341
|
+
args: {
|
|
342
|
+
...GLOBAL_FLAGS,
|
|
343
|
+
"account-id": { type: "positional", description: "Account id (acc_\u2026)." }
|
|
344
|
+
},
|
|
345
|
+
async run({ args }) {
|
|
346
|
+
const flags = args;
|
|
347
|
+
const cfg = await resolveEffectiveConfig({
|
|
348
|
+
apiKey: flags["api-key"],
|
|
349
|
+
baseUrl: flags["base-url"],
|
|
350
|
+
timeout: flags.timeout,
|
|
351
|
+
profile: flags.profile
|
|
352
|
+
});
|
|
353
|
+
if (!cfg.apiKey) {
|
|
354
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
355
|
+
process.exit(3);
|
|
356
|
+
}
|
|
357
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
358
|
+
const out = buildOutputStreams();
|
|
359
|
+
await runAccountGet(client, flags, out);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
var accountLinkCommand = defineCommand({
|
|
363
|
+
meta: { name: "link", description: "Connect a LinkedIn account to an empty seat." },
|
|
364
|
+
args: {
|
|
365
|
+
...GLOBAL_FLAGS,
|
|
366
|
+
"seat-id": { type: "string", description: "Empty seat to bind the account to.", required: true },
|
|
367
|
+
"auth-method": { type: "string", description: "Authentication method: credentials | cookie.", required: true },
|
|
368
|
+
email: { type: "string", description: "LinkedIn email (credentials method)." },
|
|
369
|
+
password: { type: "string", description: "LinkedIn password (credentials method)." },
|
|
370
|
+
"li-at": { type: "string", description: "LinkedIn session cookie li_at (cookie method)." },
|
|
371
|
+
"li-a": { type: "string", description: "Optional premium session cookie li_a (cookie method)." },
|
|
372
|
+
country: { type: "string", description: "Proxy location hint (ISO 3166-1 alpha-2)." },
|
|
373
|
+
ip: { type: "string", description: "IP to infer the managed proxy location." },
|
|
374
|
+
"proxy-protocol": { type: "string", description: "Proxy protocol: http | https | socks5." },
|
|
375
|
+
"proxy-host": { type: "string", description: "Proxy host or IP." },
|
|
376
|
+
"proxy-port": { type: "string", description: "Proxy port." },
|
|
377
|
+
"proxy-username": { type: "string", description: "Proxy auth username." },
|
|
378
|
+
"proxy-password": { type: "string", description: "Proxy auth password." },
|
|
379
|
+
"user-agent": { type: "string", description: "Browser User-Agent to pin for this account." },
|
|
380
|
+
"recruiter-contract-id": { type: "string", description: "Recruiter contract to bind to (Recruiter tier only)." }
|
|
381
|
+
},
|
|
382
|
+
async run({ args }) {
|
|
383
|
+
const flags = args;
|
|
384
|
+
const cfg = await resolveEffectiveConfig({
|
|
385
|
+
apiKey: flags["api-key"],
|
|
386
|
+
baseUrl: flags["base-url"],
|
|
387
|
+
timeout: flags.timeout,
|
|
388
|
+
profile: flags.profile
|
|
389
|
+
});
|
|
390
|
+
if (!cfg.apiKey) {
|
|
391
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
392
|
+
process.exit(3);
|
|
393
|
+
}
|
|
394
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
395
|
+
const out = buildOutputStreams();
|
|
396
|
+
await runAccountLink(client, flags, out);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
var accountConnectLinkCommand = defineCommand({
|
|
400
|
+
meta: { name: "connect-link", description: "Generate a one-time hosted account connection URL." },
|
|
401
|
+
args: {
|
|
402
|
+
...GLOBAL_FLAGS,
|
|
403
|
+
"seat-id": { type: "string", description: "Target seat (required when purpose=create)." },
|
|
404
|
+
"account-id": { type: "string", description: "Account to reconnect (required when purpose=reconnect)." },
|
|
405
|
+
purpose: { type: "string", description: "create | reconnect (default: create)." },
|
|
406
|
+
"expires-in-seconds": { type: "string", description: "Link expiry in seconds (60\u20133600, default 900)." },
|
|
407
|
+
"redirect-url": { type: "string", description: "Browser return URL after the hosted flow." }
|
|
408
|
+
},
|
|
409
|
+
async run({ args }) {
|
|
410
|
+
const flags = args;
|
|
411
|
+
const cfg = await resolveEffectiveConfig({
|
|
412
|
+
apiKey: flags["api-key"],
|
|
413
|
+
baseUrl: flags["base-url"],
|
|
414
|
+
timeout: flags.timeout,
|
|
415
|
+
profile: flags.profile
|
|
416
|
+
});
|
|
417
|
+
if (!cfg.apiKey) {
|
|
418
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
419
|
+
process.exit(3);
|
|
420
|
+
}
|
|
421
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
422
|
+
const out = buildOutputStreams();
|
|
423
|
+
await runAccountConnectLink(client, flags, out);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
var accountReconnectCommand = defineCommand({
|
|
427
|
+
meta: { name: "reconnect", description: "Re-authorize a disconnected account in place." },
|
|
428
|
+
args: {
|
|
429
|
+
...GLOBAL_FLAGS,
|
|
430
|
+
"account-id": { type: "positional", description: "Account id (acc_\u2026)." },
|
|
431
|
+
"auth-method": { type: "string", description: "Authentication method: credentials | cookie.", required: true },
|
|
432
|
+
email: { type: "string", description: "LinkedIn email (credentials method)." },
|
|
433
|
+
password: { type: "string", description: "LinkedIn password (credentials method)." },
|
|
434
|
+
"li-at": { type: "string", description: "LinkedIn session cookie li_at (cookie method)." },
|
|
435
|
+
"li-a": { type: "string", description: "Optional premium session cookie li_a (cookie method)." },
|
|
436
|
+
country: { type: "string", description: "Proxy location hint (ISO 3166-1 alpha-2)." },
|
|
437
|
+
ip: { type: "string", description: "IP to infer the managed proxy location." },
|
|
438
|
+
"proxy-protocol": { type: "string", description: "Proxy protocol: http | https | socks5." },
|
|
439
|
+
"proxy-host": { type: "string", description: "Proxy host or IP." },
|
|
440
|
+
"proxy-port": { type: "string", description: "Proxy port." },
|
|
441
|
+
"proxy-username": { type: "string", description: "Proxy auth username." },
|
|
442
|
+
"proxy-password": { type: "string", description: "Proxy auth password." },
|
|
443
|
+
"user-agent": { type: "string", description: "Browser User-Agent to pin." },
|
|
444
|
+
"recruiter-contract-id": { type: "string", description: "Recruiter contract id (Recruiter tier only)." }
|
|
445
|
+
},
|
|
446
|
+
async run({ args }) {
|
|
447
|
+
const flags = args;
|
|
448
|
+
const cfg = await resolveEffectiveConfig({
|
|
449
|
+
apiKey: flags["api-key"],
|
|
450
|
+
baseUrl: flags["base-url"],
|
|
451
|
+
timeout: flags.timeout,
|
|
452
|
+
profile: flags.profile
|
|
453
|
+
});
|
|
454
|
+
if (!cfg.apiKey) {
|
|
455
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
456
|
+
process.exit(3);
|
|
457
|
+
}
|
|
458
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
459
|
+
const out = buildOutputStreams();
|
|
460
|
+
await runAccountReconnect(client, flags, out);
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
var accountRefreshCommand = defineCommand({
|
|
464
|
+
meta: { name: "refresh", description: "Refresh an account's synced data sources." },
|
|
465
|
+
args: {
|
|
466
|
+
...GLOBAL_FLAGS,
|
|
467
|
+
"account-id": { type: "positional", description: "Account id (acc_\u2026)." }
|
|
468
|
+
},
|
|
469
|
+
async run({ args }) {
|
|
470
|
+
const flags = args;
|
|
471
|
+
const cfg = await resolveEffectiveConfig({
|
|
472
|
+
apiKey: flags["api-key"],
|
|
473
|
+
baseUrl: flags["base-url"],
|
|
474
|
+
timeout: flags.timeout,
|
|
475
|
+
profile: flags.profile
|
|
476
|
+
});
|
|
477
|
+
if (!cfg.apiKey) {
|
|
478
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
479
|
+
process.exit(3);
|
|
480
|
+
}
|
|
481
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
482
|
+
const out = buildOutputStreams();
|
|
483
|
+
await runAccountRefresh(client, flags, out);
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
var accountUpdateCommand = defineCommand({
|
|
487
|
+
meta: { name: "update", description: "Update managed-proxy configuration for an account." },
|
|
488
|
+
args: {
|
|
489
|
+
...GLOBAL_FLAGS,
|
|
490
|
+
"account-id": { type: "positional", description: "Account id (acc_\u2026)." },
|
|
491
|
+
country: { type: "string", description: "Proxy location hint (ISO 3166-1 alpha-2)." },
|
|
492
|
+
ip: { type: "string", description: "IP to infer the managed proxy location." },
|
|
493
|
+
"proxy-protocol": { type: "string", description: "Proxy protocol: http | https | socks5." },
|
|
494
|
+
"proxy-host": { type: "string", description: "Proxy host or IP." },
|
|
495
|
+
"proxy-port": { type: "string", description: "Proxy port." },
|
|
496
|
+
"proxy-username": { type: "string", description: "Proxy auth username." },
|
|
497
|
+
"proxy-password": { type: "string", description: "Proxy auth password." }
|
|
498
|
+
},
|
|
499
|
+
async run({ args }) {
|
|
500
|
+
const flags = args;
|
|
501
|
+
const cfg = await resolveEffectiveConfig({
|
|
502
|
+
apiKey: flags["api-key"],
|
|
503
|
+
baseUrl: flags["base-url"],
|
|
504
|
+
timeout: flags.timeout,
|
|
505
|
+
profile: flags.profile
|
|
506
|
+
});
|
|
507
|
+
if (!cfg.apiKey) {
|
|
508
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
509
|
+
process.exit(3);
|
|
510
|
+
}
|
|
511
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
512
|
+
const out = buildOutputStreams();
|
|
513
|
+
await runAccountUpdate(client, flags, out);
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
var accountDisconnectCommand = defineCommand({
|
|
517
|
+
meta: { name: "disconnect", description: "Hard-disconnect a LinkedIn account and release its seat." },
|
|
518
|
+
args: {
|
|
519
|
+
...GLOBAL_FLAGS,
|
|
520
|
+
"account-id": { type: "positional", description: "Account id (acc_\u2026)." }
|
|
521
|
+
},
|
|
522
|
+
async run({ args }) {
|
|
523
|
+
const flags = args;
|
|
524
|
+
const cfg = await resolveEffectiveConfig({
|
|
525
|
+
apiKey: flags["api-key"],
|
|
526
|
+
baseUrl: flags["base-url"],
|
|
527
|
+
timeout: flags.timeout,
|
|
528
|
+
profile: flags.profile
|
|
529
|
+
});
|
|
530
|
+
if (!cfg.apiKey) {
|
|
531
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
532
|
+
process.exit(3);
|
|
533
|
+
}
|
|
534
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
535
|
+
const out = buildOutputStreams();
|
|
536
|
+
await runAccountDisconnect(client, flags, out);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
var accountCheckpointSubmitCommand = defineCommand({
|
|
540
|
+
meta: { name: "submit", description: "Submit an OTP / 2FA code to resolve a checkpoint challenge." },
|
|
541
|
+
args: {
|
|
542
|
+
...GLOBAL_FLAGS,
|
|
543
|
+
checkpoint: {
|
|
544
|
+
type: "string",
|
|
545
|
+
description: "The provisional account_id from the 202 checkpoint_required response.",
|
|
546
|
+
required: true
|
|
547
|
+
},
|
|
548
|
+
code: {
|
|
549
|
+
type: "string",
|
|
550
|
+
description: "The OTP / 2FA verification code (or TRY_ANOTHER_WAY to switch challenge type).",
|
|
551
|
+
required: true
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
async run({ args }) {
|
|
555
|
+
const flags = args;
|
|
556
|
+
const cfg = await resolveEffectiveConfig({
|
|
557
|
+
apiKey: flags["api-key"],
|
|
558
|
+
baseUrl: flags["base-url"],
|
|
559
|
+
timeout: flags.timeout,
|
|
560
|
+
profile: flags.profile
|
|
561
|
+
});
|
|
562
|
+
if (!cfg.apiKey) {
|
|
563
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
564
|
+
process.exit(3);
|
|
565
|
+
}
|
|
566
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
567
|
+
const out = buildOutputStreams();
|
|
568
|
+
await runAccountCheckpointSubmit(client, flags, out);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
var accountCheckpointPollCommand = defineCommand({
|
|
572
|
+
meta: { name: "poll", description: "Poll for mobile-app approval of a pending checkpoint challenge." },
|
|
573
|
+
args: {
|
|
574
|
+
...GLOBAL_FLAGS,
|
|
575
|
+
checkpoint: {
|
|
576
|
+
type: "string",
|
|
577
|
+
description: "The provisional account_id from the 202 checkpoint_required response.",
|
|
578
|
+
required: true
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
async run({ args }) {
|
|
582
|
+
const flags = args;
|
|
583
|
+
const cfg = await resolveEffectiveConfig({
|
|
584
|
+
apiKey: flags["api-key"],
|
|
585
|
+
baseUrl: flags["base-url"],
|
|
586
|
+
timeout: flags.timeout,
|
|
587
|
+
profile: flags.profile
|
|
588
|
+
});
|
|
589
|
+
if (!cfg.apiKey) {
|
|
590
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
591
|
+
process.exit(3);
|
|
592
|
+
}
|
|
593
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
594
|
+
const out = buildOutputStreams();
|
|
595
|
+
await runAccountCheckpointPoll(client, flags, out);
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
var accountCheckpointCommand = defineCommand({
|
|
599
|
+
meta: { name: "checkpoint", description: "Checkpoint challenge operations (submit OTP or poll mobile-app approval)." },
|
|
600
|
+
subCommands: {
|
|
601
|
+
submit: accountCheckpointSubmitCommand,
|
|
602
|
+
poll: accountCheckpointPollCommand
|
|
603
|
+
},
|
|
604
|
+
async run() {
|
|
605
|
+
process.stderr.write("Usage: curviate account checkpoint submit | poll\n");
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
var accountCommand = defineCommand({
|
|
609
|
+
meta: { name: "account", description: "LinkedIn account connection management." },
|
|
610
|
+
subCommands: {
|
|
611
|
+
list: accountListCommand,
|
|
612
|
+
get: accountGetCommand,
|
|
613
|
+
link: accountLinkCommand,
|
|
614
|
+
"connect-link": accountConnectLinkCommand,
|
|
615
|
+
reconnect: accountReconnectCommand,
|
|
616
|
+
refresh: accountRefreshCommand,
|
|
617
|
+
update: accountUpdateCommand,
|
|
618
|
+
disconnect: accountDisconnectCommand,
|
|
619
|
+
checkpoint: accountCheckpointCommand
|
|
620
|
+
},
|
|
621
|
+
async run() {
|
|
622
|
+
process.stderr.write(
|
|
623
|
+
"Usage: curviate account <subcommand>\n list | get | link | connect-link | reconnect | refresh | update | disconnect | checkpoint\n"
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
export {
|
|
628
|
+
accountCommand,
|
|
629
|
+
runAccountCheckpointPoll,
|
|
630
|
+
runAccountCheckpointSubmit,
|
|
631
|
+
runAccountConnectLink,
|
|
632
|
+
runAccountDisconnect,
|
|
633
|
+
runAccountGet,
|
|
634
|
+
runAccountLink,
|
|
635
|
+
runAccountList,
|
|
636
|
+
runAccountReconnect,
|
|
637
|
+
runAccountRefresh,
|
|
638
|
+
runAccountUpdate
|
|
639
|
+
};
|