@curviate/cli 0.5.0 → 0.6.1
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 +25 -0
- package/dist/{account-47TRPUKL.js → account-O5GZNE72.js} +5 -4
- package/dist/{chunk-U6ACUNLU.js → chunk-47SYFQRF.js} +1 -1
- package/dist/chunk-CHFKVAEI.js +32 -0
- package/dist/chunk-FX6VBI43.js +221 -0
- package/dist/{chunk-SND3NHCT.js → chunk-GXTZION6.js} +1 -2
- package/dist/{chunk-BNUTM6KD.js → chunk-SZB3CFRZ.js} +8 -1
- package/dist/{chunk-52RZLSWP.js → chunk-TDYIQHQX.js} +13 -1
- package/dist/cli.js +18 -14
- package/dist/{company-4MUABENR.js → company-WH2ZETTP.js} +6 -6
- package/dist/{config-6PNGYL5E.js → config-2GBLD4GN.js} +1 -1
- package/dist/{connect-ZXD7P5CA.js → connect-YUJ2T5CN.js} +50 -22
- package/dist/{inbox-ME4TXGFV.js → inbox-YV6GPRG6.js} +107 -22
- package/dist/{login-UJQGIP7S.js → login-POKHNDYX.js} +1 -1
- package/dist/{message-O7QN2L6Q.js → message-YRMLMHK7.js} +124 -39
- package/dist/{post-VDQF23WS.js → post-KBSR3ADF.js} +20 -12
- package/dist/{profile-CUVVESMY.js → profile-4IPEB7MN.js} +26 -17
- package/dist/{recruiter-QKJKOWD7.js → recruiter-7UEBT3JZ.js} +10 -7
- package/dist/{sales-nav-UL2H6J6V.js → sales-nav-LSBARRGL.js} +8 -6
- package/dist/{search-M4WK3PDC.js → search-ONCNS43D.js} +75 -24
- package/dist/{webhook-2SSNW25K.js → webhook-F6CRIISR.js} +5 -4
- package/package.json +2 -2
- package/dist/chunk-5NS2G4WQ.js +0 -95
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
normalizeChatId
|
|
4
|
+
} from "./chunk-SZB3CFRZ.js";
|
|
2
5
|
import {
|
|
3
6
|
streamAll
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GXTZION6.js";
|
|
5
8
|
import {
|
|
6
9
|
createClient,
|
|
7
10
|
renderError,
|
|
8
11
|
renderSuccess,
|
|
9
12
|
renderUnexpectedError,
|
|
10
13
|
resolveEffectiveConfig
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-47SYFQRF.js";
|
|
12
15
|
import {
|
|
13
|
-
GLOBAL_FLAGS
|
|
14
|
-
|
|
16
|
+
GLOBAL_FLAGS,
|
|
17
|
+
READ_SINGLE_FLAGS
|
|
18
|
+
} from "./chunk-TDYIQHQX.js";
|
|
15
19
|
|
|
16
20
|
// src/commands/inbox.ts
|
|
17
21
|
import { defineCommand } from "citty";
|
|
@@ -53,6 +57,15 @@ function buildPaginationParams(flags) {
|
|
|
53
57
|
if (flags.cursor) params["cursor"] = flags.cursor;
|
|
54
58
|
return params;
|
|
55
59
|
}
|
|
60
|
+
function validateIsoZTimestamp(value, flagName, out) {
|
|
61
|
+
if (Number.isNaN(new Date(value).getTime()) || !value.endsWith("Z")) {
|
|
62
|
+
out.stderr.write(
|
|
63
|
+
`error: --${flagName}: must be a UTC ISO-8601 timestamp ending in 'Z' (e.g. 2025-01-01T00:00:00Z).
|
|
64
|
+
`
|
|
65
|
+
);
|
|
66
|
+
process.exit(2);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
56
69
|
async function handleSdkError(err, outOpts, out) {
|
|
57
70
|
const { CurviateError } = await import("@curviate/sdk");
|
|
58
71
|
if (err instanceof CurviateError) {
|
|
@@ -71,12 +84,16 @@ async function runInboxList(client, flags, out) {
|
|
|
71
84
|
const all = flags.all ?? false;
|
|
72
85
|
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
73
86
|
const params = buildPaginationParams(flags);
|
|
87
|
+
if (flags.unread !== void 0) {
|
|
88
|
+
params.unread = flags.unread;
|
|
89
|
+
}
|
|
74
90
|
try {
|
|
75
91
|
if (all) {
|
|
76
92
|
const fn = (p) => ns.messaging.listChats(p);
|
|
77
93
|
for await (const item of streamAll(fn, params, {
|
|
78
94
|
maxPages,
|
|
79
|
-
onTruncated: (
|
|
95
|
+
onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
|
|
96
|
+
`)
|
|
80
97
|
})) {
|
|
81
98
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
82
99
|
}
|
|
@@ -92,7 +109,7 @@ async function runInboxGet(client, flags, out) {
|
|
|
92
109
|
rejectPreviewOnRead(flags.preview, out);
|
|
93
110
|
rejectAllOnNonPaginated(flags.all, out);
|
|
94
111
|
const accountId = requireAccount(flags.account, out);
|
|
95
|
-
const chatId = flags.chatId ?? "";
|
|
112
|
+
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
96
113
|
const ns = client.account(accountId);
|
|
97
114
|
const outOpts = resolveOutputOpts(flags);
|
|
98
115
|
try {
|
|
@@ -105,18 +122,27 @@ async function runInboxGet(client, flags, out) {
|
|
|
105
122
|
async function runInboxMessages(client, flags, out) {
|
|
106
123
|
rejectPreviewOnRead(flags.preview, out);
|
|
107
124
|
const accountId = requireAccount(flags.account, out);
|
|
108
|
-
const chatId = flags.chatId ?? "";
|
|
125
|
+
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
109
126
|
const ns = client.account(accountId);
|
|
110
127
|
const outOpts = resolveOutputOpts(flags);
|
|
111
128
|
const all = flags.all ?? false;
|
|
112
129
|
const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
|
|
113
130
|
const params = buildPaginationParams(flags);
|
|
131
|
+
if (flags.before !== void 0) {
|
|
132
|
+
validateIsoZTimestamp(flags.before, "before", out);
|
|
133
|
+
params.before = flags.before;
|
|
134
|
+
}
|
|
135
|
+
if (flags.after !== void 0) {
|
|
136
|
+
validateIsoZTimestamp(flags.after, "after", out);
|
|
137
|
+
params.after = flags.after;
|
|
138
|
+
}
|
|
114
139
|
try {
|
|
115
140
|
if (all) {
|
|
116
141
|
const fn = (p) => ns.messaging.listMessages(chatId, p);
|
|
117
142
|
for await (const item of streamAll(fn, params, {
|
|
118
143
|
maxPages,
|
|
119
|
-
onTruncated: (
|
|
144
|
+
onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
|
|
145
|
+
`)
|
|
120
146
|
})) {
|
|
121
147
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
122
148
|
}
|
|
@@ -141,23 +167,58 @@ async function runInboxSync(client, flags, out) {
|
|
|
141
167
|
await handleSdkError(err, outOpts, out);
|
|
142
168
|
}
|
|
143
169
|
}
|
|
144
|
-
|
|
170
|
+
var SYNC_TERMINAL_STATUSES = /* @__PURE__ */ new Set(["done", "error", "chat_deleted"]);
|
|
171
|
+
var SYNC_POLL_INTERVAL_MS = 2e3;
|
|
172
|
+
async function runInboxSyncChat(client, flags, out, _sleep) {
|
|
145
173
|
rejectPreviewOnRead(flags.preview, out);
|
|
146
174
|
rejectAllOnNonPaginated(flags.all, out);
|
|
147
175
|
const accountId = requireAccount(flags.account, out);
|
|
148
|
-
const chatId = flags.chatId ?? "";
|
|
176
|
+
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
149
177
|
const ns = client.account(accountId);
|
|
150
178
|
const outOpts = resolveOutputOpts(flags);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
if (!flags.wait) {
|
|
180
|
+
try {
|
|
181
|
+
const result = await ns.messaging.syncChat(chatId);
|
|
182
|
+
renderSuccess(result, outOpts, out);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
await handleSdkError(err, outOpts, out);
|
|
185
|
+
}
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const sleep = _sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
189
|
+
const timeoutSecs = parseInt(flags.timeout ?? "30", 10);
|
|
190
|
+
const timeoutMs = (Number.isNaN(timeoutSecs) ? 30 : timeoutSecs) * 1e3;
|
|
191
|
+
const startTime = Date.now();
|
|
192
|
+
while (true) {
|
|
193
|
+
let result;
|
|
194
|
+
try {
|
|
195
|
+
result = await ns.messaging.syncChat(chatId);
|
|
196
|
+
} catch (err) {
|
|
197
|
+
await handleSdkError(err, outOpts, out);
|
|
198
|
+
}
|
|
199
|
+
const resp = result;
|
|
200
|
+
if (resp.status !== void 0 && SYNC_TERMINAL_STATUSES.has(resp.status)) {
|
|
201
|
+
renderSuccess(result, outOpts, out);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (Date.now() - startTime >= timeoutMs) {
|
|
205
|
+
renderSuccess(result, outOpts, out);
|
|
206
|
+
process.exit(3);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
await sleep(SYNC_POLL_INTERVAL_MS);
|
|
156
210
|
}
|
|
157
211
|
}
|
|
158
212
|
var inboxListCommand = defineCommand({
|
|
159
213
|
meta: { name: "list", description: "List inbox chats." },
|
|
160
|
-
args: {
|
|
214
|
+
args: {
|
|
215
|
+
...GLOBAL_FLAGS,
|
|
216
|
+
unread: {
|
|
217
|
+
type: "boolean",
|
|
218
|
+
description: "Show unread chats only (--no-unread for read-only; omit for all)."
|
|
219
|
+
// No default → three-way semantics: undefined when omitted, true for --unread, false for --no-unread
|
|
220
|
+
}
|
|
221
|
+
},
|
|
161
222
|
async run({ args }) {
|
|
162
223
|
const flags = args;
|
|
163
224
|
const cfg = await resolveEffectiveConfig({
|
|
@@ -179,7 +240,8 @@ var inboxListCommand = defineCommand({
|
|
|
179
240
|
var inboxGetCommand = defineCommand({
|
|
180
241
|
meta: { name: "get", description: "Get details of a single chat." },
|
|
181
242
|
args: {
|
|
182
|
-
|
|
243
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
244
|
+
...READ_SINGLE_FLAGS,
|
|
183
245
|
chatId: { type: "positional", description: "Chat ID." }
|
|
184
246
|
},
|
|
185
247
|
async run({ args }) {
|
|
@@ -204,7 +266,15 @@ var inboxMessagesCommand = defineCommand({
|
|
|
204
266
|
meta: { name: "messages", description: "List messages in a chat." },
|
|
205
267
|
args: {
|
|
206
268
|
...GLOBAL_FLAGS,
|
|
207
|
-
chatId: { type: "positional", description: "Chat ID." }
|
|
269
|
+
chatId: { type: "positional", description: "Chat ID." },
|
|
270
|
+
before: {
|
|
271
|
+
type: "string",
|
|
272
|
+
description: "Return messages before this timestamp (ISO-8601, UTC \u2014 Z suffix required, e.g. 2025-01-01T00:00:00Z)."
|
|
273
|
+
},
|
|
274
|
+
after: {
|
|
275
|
+
type: "string",
|
|
276
|
+
description: "Return messages after this timestamp (ISO-8601, UTC \u2014 Z suffix required, e.g. 2025-01-01T00:00:00Z)."
|
|
277
|
+
}
|
|
208
278
|
},
|
|
209
279
|
async run({ args }) {
|
|
210
280
|
const flags = args;
|
|
@@ -226,7 +296,10 @@ var inboxMessagesCommand = defineCommand({
|
|
|
226
296
|
});
|
|
227
297
|
var inboxSyncCommand = defineCommand({
|
|
228
298
|
meta: { name: "sync", description: "Re-sync account message history." },
|
|
229
|
-
args: {
|
|
299
|
+
args: {
|
|
300
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
301
|
+
...READ_SINGLE_FLAGS
|
|
302
|
+
},
|
|
230
303
|
async run({ args }) {
|
|
231
304
|
const flags = args;
|
|
232
305
|
const cfg = await resolveEffectiveConfig({
|
|
@@ -248,15 +321,27 @@ var inboxSyncCommand = defineCommand({
|
|
|
248
321
|
var inboxSyncChatCommand = defineCommand({
|
|
249
322
|
meta: { name: "sync-chat", description: "Re-sync a specific chat's message history." },
|
|
250
323
|
args: {
|
|
251
|
-
|
|
252
|
-
|
|
324
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields.
|
|
325
|
+
// The timeout below overrides READ_SINGLE_FLAGS.timeout with a command-specific description.
|
|
326
|
+
...READ_SINGLE_FLAGS,
|
|
327
|
+
chatId: { type: "positional", description: "Chat ID." },
|
|
328
|
+
wait: {
|
|
329
|
+
type: "boolean",
|
|
330
|
+
description: "Poll until sync completes (or --timeout elapses).",
|
|
331
|
+
default: false
|
|
332
|
+
},
|
|
333
|
+
// Override READ_SINGLE_FLAGS.timeout: here --timeout is the polling wait timeout
|
|
334
|
+
// in seconds (default: 30), not the SDK request timeout.
|
|
335
|
+
timeout: {
|
|
336
|
+
type: "string",
|
|
337
|
+
description: "Polling timeout in seconds (default: 30, requires --wait)."
|
|
338
|
+
}
|
|
253
339
|
},
|
|
254
340
|
async run({ args }) {
|
|
255
341
|
const flags = args;
|
|
256
342
|
const cfg = await resolveEffectiveConfig({
|
|
257
343
|
apiKey: flags["api-key"],
|
|
258
344
|
baseUrl: flags["base-url"],
|
|
259
|
-
timeout: flags.timeout,
|
|
260
345
|
account: flags.account,
|
|
261
346
|
profile: flags.profile
|
|
262
347
|
});
|
|
@@ -7,22 +7,27 @@ import {
|
|
|
7
7
|
AttachError,
|
|
8
8
|
readAttachment
|
|
9
9
|
} from "./chunk-Q43HZUN3.js";
|
|
10
|
+
import {
|
|
11
|
+
resolveTextOrStdin
|
|
12
|
+
} from "./chunk-CHFKVAEI.js";
|
|
10
13
|
import {
|
|
11
14
|
buildPreviewOutput
|
|
12
15
|
} from "./chunk-R3VLWLVV.js";
|
|
13
16
|
import {
|
|
17
|
+
normalizeChatId,
|
|
14
18
|
resolveIdentifier
|
|
15
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-SZB3CFRZ.js";
|
|
16
20
|
import {
|
|
17
21
|
createClient,
|
|
18
22
|
renderError,
|
|
19
23
|
renderSuccess,
|
|
20
24
|
renderUnexpectedError,
|
|
21
25
|
resolveEffectiveConfig
|
|
22
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-47SYFQRF.js";
|
|
23
27
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
READ_SINGLE_FLAGS,
|
|
29
|
+
WRITE_FLAGS
|
|
30
|
+
} from "./chunk-TDYIQHQX.js";
|
|
26
31
|
|
|
27
32
|
// src/commands/message.ts
|
|
28
33
|
import { defineCommand } from "citty";
|
|
@@ -64,7 +69,7 @@ function normalizeAttachPaths(attach) {
|
|
|
64
69
|
}
|
|
65
70
|
var INMAIL_SURFACES = ["sales_nav", "recruiter", "classic"];
|
|
66
71
|
var MEMBER_URN_RE = /^urn:li:member:\d+$/;
|
|
67
|
-
var MEMBER_PROVIDER_ID_RE = /^A[CDE][A-Za-z0-9_-]{
|
|
72
|
+
var MEMBER_PROVIDER_ID_RE = /^A[CDE][A-Za-z0-9_-]{4,}$/;
|
|
68
73
|
async function handleSdkError(err, outOpts, out) {
|
|
69
74
|
const { CurviateError } = await import("@curviate/sdk");
|
|
70
75
|
if (err instanceof CurviateError) {
|
|
@@ -75,10 +80,10 @@ async function handleSdkError(err, outOpts, out) {
|
|
|
75
80
|
renderUnexpectedError(err, out);
|
|
76
81
|
process.exit(1);
|
|
77
82
|
}
|
|
78
|
-
async function runMessageNew(client, flags, out) {
|
|
83
|
+
async function runMessageNew(client, flags, out, _readStdin) {
|
|
79
84
|
const accountId = requireAccount(flags.account, out);
|
|
80
|
-
const
|
|
81
|
-
const
|
|
85
|
+
const rawTo = flags.to ?? "";
|
|
86
|
+
const rawText = flags.text ?? "";
|
|
82
87
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
83
88
|
let attachBuffers = [];
|
|
84
89
|
try {
|
|
@@ -91,14 +96,30 @@ async function runMessageNew(client, flags, out) {
|
|
|
91
96
|
}
|
|
92
97
|
throw err;
|
|
93
98
|
}
|
|
99
|
+
const ns = client.account(accountId);
|
|
100
|
+
const outOpts = resolveOutputOpts(flags);
|
|
101
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
102
|
+
const resolvedSlugOrId = resolveIdentifier(rawTo);
|
|
103
|
+
let providerId;
|
|
104
|
+
if (MEMBER_PROVIDER_ID_RE.test(resolvedSlugOrId)) {
|
|
105
|
+
providerId = resolvedSlugOrId;
|
|
106
|
+
} else {
|
|
107
|
+
try {
|
|
108
|
+
const profileData = await ns.profiles.get(resolvedSlugOrId, {});
|
|
109
|
+
providerId = profileData["provider_id"];
|
|
110
|
+
} catch (err) {
|
|
111
|
+
await handleSdkError(err, outOpts, out);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
94
115
|
const body = {
|
|
95
|
-
attendees_ids: [
|
|
116
|
+
attendees_ids: [providerId],
|
|
96
117
|
text
|
|
97
118
|
};
|
|
98
119
|
if (flags.preview) {
|
|
99
120
|
const preview = buildPreviewOutput({
|
|
100
121
|
method: "messaging.startChat",
|
|
101
|
-
args: { attendees_ids: [
|
|
122
|
+
args: { attendees_ids: [providerId] },
|
|
102
123
|
body: { ...body },
|
|
103
124
|
account: accountId,
|
|
104
125
|
attachments: attachBuffers.map((buf, i) => ({
|
|
@@ -112,8 +133,6 @@ async function runMessageNew(client, flags, out) {
|
|
|
112
133
|
if (attachBuffers.length > 0) {
|
|
113
134
|
body["attachments"] = attachBuffers;
|
|
114
135
|
}
|
|
115
|
-
const ns = client.account(accountId);
|
|
116
|
-
const outOpts = resolveOutputOpts(flags);
|
|
117
136
|
try {
|
|
118
137
|
const result = await ns.messaging.startChat(body);
|
|
119
138
|
renderSuccess(result, outOpts, out);
|
|
@@ -121,11 +140,12 @@ async function runMessageNew(client, flags, out) {
|
|
|
121
140
|
await handleSdkError(err, outOpts, out);
|
|
122
141
|
}
|
|
123
142
|
}
|
|
124
|
-
async function runMessageSend(client, flags, out) {
|
|
143
|
+
async function runMessageSend(client, flags, out, _readStdin) {
|
|
125
144
|
const accountId = requireAccount(flags.account, out);
|
|
126
|
-
const chatId = flags.chatId ?? "";
|
|
127
|
-
const
|
|
145
|
+
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
146
|
+
const rawText = flags.text ?? "";
|
|
128
147
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
148
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
129
149
|
let attachBuffers = [];
|
|
130
150
|
try {
|
|
131
151
|
attachBuffers = await Promise.all(attachPaths.map((p) => readAttachment(p)));
|
|
@@ -178,10 +198,11 @@ async function runMessageGet(client, flags, out) {
|
|
|
178
198
|
await handleSdkError(err, outOpts, out);
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
|
-
async function runMessageEdit(client, flags, out) {
|
|
201
|
+
async function runMessageEdit(client, flags, out, _readStdin) {
|
|
182
202
|
const accountId = requireAccount(flags.account, out);
|
|
183
203
|
const messageId = flags.messageId ?? "";
|
|
184
|
-
const
|
|
204
|
+
const rawText = flags.text ?? "";
|
|
205
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
185
206
|
if (flags.preview) {
|
|
186
207
|
const preview = buildPreviewOutput({
|
|
187
208
|
method: "messaging.editMessage",
|
|
@@ -269,7 +290,7 @@ async function runMessageAttachment(client, flags, out, isTTY) {
|
|
|
269
290
|
await handleSdkError(err, outOpts, out);
|
|
270
291
|
}
|
|
271
292
|
}
|
|
272
|
-
async function runMessageInMail(client, flags, out) {
|
|
293
|
+
async function runMessageInMail(client, flags, out, _readStdin) {
|
|
273
294
|
const accountId = requireAccount(flags.account, out);
|
|
274
295
|
const surface = flags.surface ?? "";
|
|
275
296
|
if (!INMAIL_SURFACES.includes(surface)) {
|
|
@@ -279,15 +300,34 @@ async function runMessageInMail(client, flags, out) {
|
|
|
279
300
|
);
|
|
280
301
|
process.exit(2);
|
|
281
302
|
}
|
|
282
|
-
const
|
|
283
|
-
if (!
|
|
303
|
+
const rawTo = flags.to ?? "";
|
|
304
|
+
if (!rawTo) {
|
|
284
305
|
out.stderr.write(
|
|
285
|
-
"error: --to
|
|
306
|
+
"error: --to: not a valid LinkedIn URL, slug, provider-id, or URN.\n"
|
|
286
307
|
);
|
|
287
308
|
process.exit(2);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const ns = client.account(accountId);
|
|
312
|
+
const outOpts = resolveOutputOpts(flags);
|
|
313
|
+
const resolvedSlugOrId = resolveIdentifier(rawTo);
|
|
314
|
+
let recipientUrn;
|
|
315
|
+
if (MEMBER_URN_RE.test(resolvedSlugOrId)) {
|
|
316
|
+
recipientUrn = resolvedSlugOrId;
|
|
317
|
+
} else if (MEMBER_PROVIDER_ID_RE.test(resolvedSlugOrId)) {
|
|
318
|
+
recipientUrn = resolvedSlugOrId;
|
|
319
|
+
} else {
|
|
320
|
+
try {
|
|
321
|
+
const profileData = await ns.profiles.get(resolvedSlugOrId, {});
|
|
322
|
+
recipientUrn = profileData["provider_id"];
|
|
323
|
+
} catch (err) {
|
|
324
|
+
await handleSdkError(err, outOpts, out);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
288
327
|
}
|
|
289
328
|
const subject = flags.subject ?? "";
|
|
290
|
-
const
|
|
329
|
+
const rawText = flags.text ?? "";
|
|
330
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
291
331
|
const body = {
|
|
292
332
|
recipient_urn: recipientUrn,
|
|
293
333
|
surface,
|
|
@@ -304,8 +344,6 @@ async function runMessageInMail(client, flags, out) {
|
|
|
304
344
|
out.stdout.write(JSON.stringify(preview) + "\n");
|
|
305
345
|
return;
|
|
306
346
|
}
|
|
307
|
-
const ns = client.account(accountId);
|
|
308
|
-
const outOpts = resolveOutputOpts(flags);
|
|
309
347
|
try {
|
|
310
348
|
const result = await ns.messaging.sendInMail(body);
|
|
311
349
|
renderSuccess(result, outOpts, out);
|
|
@@ -329,9 +367,14 @@ async function runMessageInMailBalance(client, flags, out) {
|
|
|
329
367
|
var messageNewCommand = defineCommand({
|
|
330
368
|
meta: { name: "new", description: "Start a new chat with one or more members." },
|
|
331
369
|
args: {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
370
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
371
|
+
...WRITE_FLAGS,
|
|
372
|
+
to: {
|
|
373
|
+
type: "string",
|
|
374
|
+
description: "Recipient: LinkedIn profile URL (e.g. https://www.linkedin.com/in/some-slug), bare slug (e.g. some-slug), or provider ID (e.g. ACoAAA\u2026). URL and slug inputs resolve the provider ID automatically.",
|
|
375
|
+
required: true
|
|
376
|
+
},
|
|
377
|
+
text: { type: "positional", description: "Opening message text. Pass - to read from stdin (e.g. via heredoc or pipe)." },
|
|
335
378
|
attach: { type: "string", description: "File to attach (repeatable)." }
|
|
336
379
|
},
|
|
337
380
|
async run({ args }) {
|
|
@@ -355,7 +398,8 @@ var messageNewCommand = defineCommand({
|
|
|
355
398
|
var messageGetCommand = defineCommand({
|
|
356
399
|
meta: { name: "get", description: "Get a message by ID." },
|
|
357
400
|
args: {
|
|
358
|
-
|
|
401
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
402
|
+
...READ_SINGLE_FLAGS,
|
|
359
403
|
messageId: { type: "positional", description: "Message ID." }
|
|
360
404
|
},
|
|
361
405
|
async run({ args }) {
|
|
@@ -379,9 +423,10 @@ var messageGetCommand = defineCommand({
|
|
|
379
423
|
var messageEditCommand = defineCommand({
|
|
380
424
|
meta: { name: "edit", description: "Edit a message (within the allowed window)." },
|
|
381
425
|
args: {
|
|
382
|
-
|
|
426
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
427
|
+
...WRITE_FLAGS,
|
|
383
428
|
messageId: { type: "positional", description: "Message ID." },
|
|
384
|
-
text: { type: "positional", description: "Replacement text." }
|
|
429
|
+
text: { type: "positional", description: "Replacement text. Pass - to read from stdin." }
|
|
385
430
|
},
|
|
386
431
|
async run({ args }) {
|
|
387
432
|
const flags = args;
|
|
@@ -404,7 +449,8 @@ var messageEditCommand = defineCommand({
|
|
|
404
449
|
var messageDeleteCommand = defineCommand({
|
|
405
450
|
meta: { name: "delete", description: "Delete a message." },
|
|
406
451
|
args: {
|
|
407
|
-
|
|
452
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
453
|
+
...WRITE_FLAGS,
|
|
408
454
|
messageId: { type: "positional", description: "Message ID." }
|
|
409
455
|
},
|
|
410
456
|
async run({ args }) {
|
|
@@ -428,7 +474,8 @@ var messageDeleteCommand = defineCommand({
|
|
|
428
474
|
var messageReactCommand = defineCommand({
|
|
429
475
|
meta: { name: "react", description: "Add an emoji reaction to a message." },
|
|
430
476
|
args: {
|
|
431
|
-
|
|
477
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
478
|
+
...WRITE_FLAGS,
|
|
432
479
|
messageId: { type: "positional", description: "Message ID." },
|
|
433
480
|
emoji: { type: "string", description: "Native emoji reaction value (e.g. \u{1F44D}).", required: true }
|
|
434
481
|
},
|
|
@@ -453,7 +500,8 @@ var messageReactCommand = defineCommand({
|
|
|
453
500
|
var messageAttachmentCommand = defineCommand({
|
|
454
501
|
meta: { name: "attachment", description: "Download a message attachment." },
|
|
455
502
|
args: {
|
|
456
|
-
|
|
503
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
504
|
+
...READ_SINGLE_FLAGS,
|
|
457
505
|
messageId: { type: "positional", description: "Message ID." },
|
|
458
506
|
attachmentId: { type: "positional", description: "Attachment ID." },
|
|
459
507
|
output: { type: "string", alias: "o", description: "Path to write the file to." }
|
|
@@ -484,11 +532,16 @@ var messageAttachmentCommand = defineCommand({
|
|
|
484
532
|
var messageInMailCommand = defineCommand({
|
|
485
533
|
meta: { name: "inmail", description: "Send an InMail to a member." },
|
|
486
534
|
args: {
|
|
487
|
-
|
|
488
|
-
|
|
535
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
536
|
+
...WRITE_FLAGS,
|
|
537
|
+
to: {
|
|
538
|
+
type: "string",
|
|
539
|
+
description: "Recipient: LinkedIn profile URL, bare slug, provider-id (ACoAAA\u2026), or member URN (urn:li:member:<id>). URL and slug inputs resolve the provider ID automatically.",
|
|
540
|
+
required: true
|
|
541
|
+
},
|
|
489
542
|
surface: { type: "string", description: "InMail surface: sales_nav, recruiter, or classic (classic uses the account's own premium InMail credits).", required: true },
|
|
490
543
|
subject: { type: "string", description: "InMail subject line.", required: true },
|
|
491
|
-
text: { type: "positional", description: "InMail body text." }
|
|
544
|
+
text: { type: "positional", description: "InMail body text. Pass - to read from stdin." }
|
|
492
545
|
},
|
|
493
546
|
async run({ args }) {
|
|
494
547
|
const flags = args;
|
|
@@ -508,9 +561,39 @@ var messageInMailCommand = defineCommand({
|
|
|
508
561
|
await runMessageInMail(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
509
562
|
}
|
|
510
563
|
});
|
|
564
|
+
var messageSendCommand = defineCommand({
|
|
565
|
+
meta: { name: "send", description: "Send a message to an existing chat." },
|
|
566
|
+
args: {
|
|
567
|
+
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
568
|
+
...WRITE_FLAGS,
|
|
569
|
+
chatId: { type: "positional", description: "Chat ID or LinkedIn messaging thread URL." },
|
|
570
|
+
text: { type: "positional", description: "Message text. Pass - to read from stdin (e.g. via heredoc or pipe)." },
|
|
571
|
+
attach: { type: "string", description: "File to attach (repeatable)." }
|
|
572
|
+
},
|
|
573
|
+
async run({ args }) {
|
|
574
|
+
const flags = args;
|
|
575
|
+
const cfg = await resolveEffectiveConfig({
|
|
576
|
+
apiKey: flags["api-key"],
|
|
577
|
+
baseUrl: flags["base-url"],
|
|
578
|
+
timeout: flags.timeout,
|
|
579
|
+
account: flags.account,
|
|
580
|
+
profile: flags.profile
|
|
581
|
+
});
|
|
582
|
+
if (!cfg.apiKey) {
|
|
583
|
+
process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
|
|
584
|
+
process.exit(3);
|
|
585
|
+
}
|
|
586
|
+
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
587
|
+
const out = buildOutputStreams();
|
|
588
|
+
await runMessageSend(client, { ...flags, account: flags.account ?? cfg.account }, out);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
511
591
|
var messageInMailBalanceCommand = defineCommand({
|
|
512
592
|
meta: { name: "inmail-balance", description: "Get InMail credit balance." },
|
|
513
|
-
args: {
|
|
593
|
+
args: {
|
|
594
|
+
// Single-object read: READ_SINGLE_FLAGS omits pagination flags, keeps --fields
|
|
595
|
+
...READ_SINGLE_FLAGS
|
|
596
|
+
},
|
|
514
597
|
async run({ args }) {
|
|
515
598
|
const flags = args;
|
|
516
599
|
const cfg = await resolveEffectiveConfig({
|
|
@@ -532,13 +615,15 @@ var messageInMailBalanceCommand = defineCommand({
|
|
|
532
615
|
var messageCommand = defineCommand({
|
|
533
616
|
meta: { name: "message", description: "Send and manage LinkedIn messages." },
|
|
534
617
|
args: {
|
|
535
|
-
|
|
618
|
+
// Write command (message send): WRITE_FLAGS omits pagination/projection flags
|
|
619
|
+
...WRITE_FLAGS,
|
|
536
620
|
chatId: { type: "positional", description: "Chat ID to send a message to.", required: false },
|
|
537
|
-
text: { type: "positional", description: "Message text.", required: false },
|
|
621
|
+
text: { type: "positional", description: "Message text. Pass - to read from stdin.", required: false },
|
|
538
622
|
attach: { type: "string", description: "File to attach (repeatable)." }
|
|
539
623
|
},
|
|
540
624
|
subCommands: {
|
|
541
625
|
new: messageNewCommand,
|
|
626
|
+
send: messageSendCommand,
|
|
542
627
|
get: messageGetCommand,
|
|
543
628
|
edit: messageEditCommand,
|
|
544
629
|
delete: messageDeleteCommand,
|
|
@@ -3,23 +3,26 @@ import {
|
|
|
3
3
|
AttachError,
|
|
4
4
|
readAttachment
|
|
5
5
|
} from "./chunk-Q43HZUN3.js";
|
|
6
|
+
import {
|
|
7
|
+
resolveTextOrStdin
|
|
8
|
+
} from "./chunk-CHFKVAEI.js";
|
|
6
9
|
import {
|
|
7
10
|
buildPreviewOutput
|
|
8
11
|
} from "./chunk-R3VLWLVV.js";
|
|
9
12
|
import {
|
|
10
13
|
streamAll
|
|
11
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-GXTZION6.js";
|
|
12
15
|
import {
|
|
13
16
|
createClient,
|
|
14
17
|
renderError,
|
|
15
18
|
renderSuccess,
|
|
16
19
|
renderUnexpectedError,
|
|
17
20
|
resolveEffectiveConfig
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-47SYFQRF.js";
|
|
19
22
|
import {
|
|
20
23
|
GLOBAL_FLAGS,
|
|
21
24
|
WRITE_FLAGS
|
|
22
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-TDYIQHQX.js";
|
|
23
26
|
|
|
24
27
|
// src/commands/post.ts
|
|
25
28
|
import { defineCommand } from "citty";
|
|
@@ -89,7 +92,8 @@ async function runPostList(client, flags, out) {
|
|
|
89
92
|
const fn = (p) => ns.posts.list(p);
|
|
90
93
|
for await (const item of streamAll(fn, params, {
|
|
91
94
|
maxPages,
|
|
92
|
-
onTruncated: (
|
|
95
|
+
onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
|
|
96
|
+
`)
|
|
93
97
|
})) {
|
|
94
98
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
95
99
|
}
|
|
@@ -115,11 +119,12 @@ async function runPostGet(client, flags, out) {
|
|
|
115
119
|
await handleSdkError(err, outOpts, out);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
|
-
async function runPostCreate(client, flags, out) {
|
|
122
|
+
async function runPostCreate(client, flags, out, _readStdin) {
|
|
119
123
|
const accountId = requireAccount(flags.account, out);
|
|
120
|
-
const
|
|
124
|
+
const rawText = flags.text ?? "";
|
|
121
125
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
122
126
|
const thumbPath = flags["video-thumbnail"];
|
|
127
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
123
128
|
let attachBuffers = [];
|
|
124
129
|
try {
|
|
125
130
|
attachBuffers = await Promise.all(attachPaths.map((p) => readAttachment(p)));
|
|
@@ -181,11 +186,12 @@ async function runPostCreate(client, flags, out) {
|
|
|
181
186
|
await handleSdkError(err, outOpts, out);
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
|
-
async function runPostComment(client, flags, out) {
|
|
189
|
+
async function runPostComment(client, flags, out, _readStdin) {
|
|
185
190
|
const accountId = requireAccount(flags.account, out);
|
|
186
191
|
const postId = flags.postId ?? "";
|
|
187
|
-
const
|
|
192
|
+
const rawText = flags.text ?? "";
|
|
188
193
|
const replyTo = flags["reply-to"];
|
|
194
|
+
const text = await resolveTextOrStdin(rawText, out, _readStdin);
|
|
189
195
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
190
196
|
let attachBuffers = [];
|
|
191
197
|
try {
|
|
@@ -241,7 +247,8 @@ async function runPostComments(client, flags, out) {
|
|
|
241
247
|
const fn = (p) => ns.posts.listComments(postId, p);
|
|
242
248
|
for await (const item of streamAll(fn, params, {
|
|
243
249
|
maxPages,
|
|
244
|
-
onTruncated: (
|
|
250
|
+
onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
|
|
251
|
+
`)
|
|
245
252
|
})) {
|
|
246
253
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
247
254
|
}
|
|
@@ -303,7 +310,8 @@ async function runPostReactions(client, flags, out) {
|
|
|
303
310
|
const fn = (p) => ns.posts.listReactions(postId, p);
|
|
304
311
|
for await (const item of streamAll(fn, params, {
|
|
305
312
|
maxPages,
|
|
306
|
-
onTruncated: (
|
|
313
|
+
onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
|
|
314
|
+
`)
|
|
307
315
|
})) {
|
|
308
316
|
out.stdout.write(JSON.stringify(item) + "\n");
|
|
309
317
|
}
|
|
@@ -368,7 +376,7 @@ var postCreateCommand = defineCommand({
|
|
|
368
376
|
args: {
|
|
369
377
|
// Write command: WRITE_FLAGS omits pagination/projection flags
|
|
370
378
|
...WRITE_FLAGS,
|
|
371
|
-
text: { type: "positional", description: "Post body text." },
|
|
379
|
+
text: { type: "positional", description: "Post body text. Pass - to read from stdin (enables multiline via heredoc or pipe)." },
|
|
372
380
|
attach: {
|
|
373
381
|
type: "string",
|
|
374
382
|
description: "Image/video/document to attach (repeatable for images; use --video-thumbnail when attaching a video). Supported: jpg, png, gif, mp4, pdf."
|
|
@@ -405,7 +413,7 @@ var postCommentCommand = defineCommand({
|
|
|
405
413
|
type: "positional",
|
|
406
414
|
description: "Numeric post id, urn:li:activity:N, or full LinkedIn share URL (activity-<N>- extracted). POSTID is always the post's id; use --reply-to <comment_id> to reply to a specific comment within this post."
|
|
407
415
|
},
|
|
408
|
-
text: { type: "positional", description: "Comment text (max ~1,250 characters per LinkedIn limits)." },
|
|
416
|
+
text: { type: "positional", description: "Comment text (max ~1,250 characters per LinkedIn limits). Pass - to read from stdin." },
|
|
409
417
|
attach: { type: "string", description: "Image to attach to the comment (optional; one image per comment)." },
|
|
410
418
|
"reply-to": {
|
|
411
419
|
type: "string",
|