@curviate/cli 0.22.0 → 0.23.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 +65 -0
- package/dist/chunk-3BO6GVS2.js +182 -0
- package/dist/{chunk-T5LPGAGJ.js → chunk-MBO4LBLY.js} +13 -17
- package/dist/{chunk-QJZ3LWOX.js → chunk-RJTG5YWE.js} +1 -1
- package/dist/{chunk-DMQZEPQE.js → chunk-UEAX6KUB.js} +10 -0
- package/dist/cli.js +16 -16
- package/dist/{comment-MCGXFMN4.js → comment-TUXC7K72.js} +16 -19
- package/dist/{company-WDDLWP7E.js → company-LHYDAO2C.js} +20 -23
- package/dist/{connect-5OROSY5C.js → connect-5S4TFQAF.js} +11 -14
- package/dist/{feed-SFVYEAYP.js → feed-ISNH4NXB.js} +5 -8
- package/dist/{group-HSZY2IJU.js → group-PHGUOOJE.js} +12 -12
- package/dist/{inbox-L6JBGZIB.js → inbox-3IQPPQMH.js} +10 -13
- package/dist/{inboxes-UIO74C5Q.js → inboxes-JK36F6SK.js} +6 -9
- package/dist/{job-75ML7R7I.js → job-JQG34ATV.js} +15 -18
- package/dist/{message-DAQHRBSJ.js → message-2WIZESSM.js} +4 -2
- package/dist/{notification-DYJN4ZHN.js → notification-ORSZY2IJ.js} +7 -10
- package/dist/{post-RGDOCGC4.js → post-JRJMGV2I.js} +17 -20
- package/dist/{profile-TJS2YAZD.js → profile-SUKHRWQP.js} +19 -22
- package/dist/{recruiter-NSM33IEK.js → recruiter-NIKKDGMR.js} +28 -31
- package/dist/{sales-nav-5O7FR57S.js → sales-nav-4MFL2JSE.js} +17 -20
- package/dist/{search-TDSLK2MB.js → search-MZQJDJTX.js} +13 -16
- package/package.json +2 -2
- package/dist/{account-QRGWUQXF.js → account-MIPWTAG5.js} +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,71 @@ a new command or flag is a minor; a breaking command/flag/exit-code change is a
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.23.0] - 2026-08-10
|
|
12
|
+
|
|
13
|
+
A security and correctness release. Upgrade promptly if `--account` is ever
|
|
14
|
+
set from anything other than a literal you typed yourself (an environment
|
|
15
|
+
variable, a config profile, or agent- or model-generated text): every
|
|
16
|
+
published version through 0.22.0 interpolated it into the request path with
|
|
17
|
+
no validation at all, so a value carrying a slash, `..`, a question mark, a
|
|
18
|
+
hash, or a percent sign could redirect a request, including a write, to a
|
|
19
|
+
different endpoint on the API host. This release also lets `--account` take a
|
|
20
|
+
connected account's name, not just its id.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **`--account` could redirect a request to a different endpoint.**
|
|
25
|
+
`inbox mark-read` on `--account 'x/../../../v1/accounts'` built
|
|
26
|
+
`PATCH /v1/accounts/chats/chat_1` instead of touching the account the caller
|
|
27
|
+
named. `--account 'a?x=1'` injected a query string into the middle of the
|
|
28
|
+
path. Neither needed a literal `..`: the URL Standard percent-decodes when it
|
|
29
|
+
decides whether a segment is a double-dot path segment, so `%2e%2e` walked up
|
|
30
|
+
the path with no slash in the value at all. Every account-scoped command was
|
|
31
|
+
reachable this way, since all of them build the request URL from `--account`.
|
|
32
|
+
The value is now checked before any request is built, and a value that could
|
|
33
|
+
redirect one is refused with `[INVALID_PATH_SEGMENT]` (exit `2`) naming the
|
|
34
|
+
character it contains, rather than being sent.
|
|
35
|
+
|
|
36
|
+
- **`group get` / `group members` never actually accepted a group URL,
|
|
37
|
+
despite documenting it.** The help and this file both claimed the server
|
|
38
|
+
extracted the numeric id from a full `https://www.linkedin.com/groups/...`
|
|
39
|
+
URL passed through verbatim; it does not, and cannot: the URL's own slashes
|
|
40
|
+
split it into several path segments and the request landed on a route that
|
|
41
|
+
does not exist. The numeric id is now extracted client-side, the same way
|
|
42
|
+
member, company, chat, and job URLs already are. A bare numeric id is
|
|
43
|
+
unaffected.
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **`--account` accepts a connected account's name, not just its id.** A value
|
|
48
|
+
that is not shaped like an account id is looked up against
|
|
49
|
+
`accounts.list`: an exact name match wins outright, otherwise a unique
|
|
50
|
+
prefix match resolves. A name matching more than one connected account
|
|
51
|
+
exits with `[ACCOUNT_AMBIGUOUS]` (exit `2`) rather than guessing, since
|
|
52
|
+
acting on the wrong live persona cannot be undone. A name matching none
|
|
53
|
+
exits with `[ACCOUNT_NAME_NOT_FOUND]` (exit `4`) and lists what is
|
|
54
|
+
connected. On an API key with more connected accounts than the resolver
|
|
55
|
+
reads (250 per page, 10 pages), a name lookup exits with
|
|
56
|
+
`[ACCOUNT_LIST_TRUNCATED]` (exit `2`) instead of matching against a list
|
|
57
|
+
that might be missing the very account the name would have matched; pass
|
|
58
|
+
the id instead, which needs no lookup. An id-shaped value still costs no
|
|
59
|
+
extra request. `--preview` never issues the lookup, consistent with it
|
|
60
|
+
never calling the API.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **`@curviate/sdk` dependency bumped to `^0.20.1`.** ^0.20.0 still resolves
|
|
65
|
+
the vulnerable 0.20.0 build on a fresh install or an old lockfile; 0.20.1 is
|
|
66
|
+
a hard floor at the fix. Percent-encoding of every other command's path
|
|
67
|
+
parameters (chat, job, group, company and member ids, and so on) is the
|
|
68
|
+
SDK's job as of 0.20.0, not this CLI's: a previous CLI-side guard that
|
|
69
|
+
inspected each call's leading string argument has been removed, because it
|
|
70
|
+
could not know which argument actually became a path segment and was wrong
|
|
71
|
+
in both directions, missing a path parameter passed inside an object and
|
|
72
|
+
rejecting a body field that never reached a path (`post save <share URL>`
|
|
73
|
+
was one such false rejection). `--account` is guarded separately, above,
|
|
74
|
+
because it is the one value this CLI genuinely understands the meaning of.
|
|
75
|
+
|
|
11
76
|
## [0.22.0] - 2026-08-07
|
|
12
77
|
|
|
13
78
|
Two correctness fixes for the same underlying failure: a command that answers
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
assertNoStdinPlaceholder
|
|
4
|
+
} from "./chunk-ZYURL5VK.js";
|
|
5
|
+
import {
|
|
6
|
+
getExitCode
|
|
7
|
+
} from "./chunk-PMRQXBCP.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/path-safety.ts
|
|
10
|
+
var UNSAFE_CHARS = /[\u0000-\u0020\u007F/\\?#%]/;
|
|
11
|
+
var UNICODE_WHITESPACE = /[\u00A0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
|
|
12
|
+
function describeChar(value, index) {
|
|
13
|
+
const ch = value[index] ?? "";
|
|
14
|
+
const named = {
|
|
15
|
+
"/": "a slash",
|
|
16
|
+
"\\": "a backslash",
|
|
17
|
+
"?": "a question mark",
|
|
18
|
+
"#": "a hash",
|
|
19
|
+
"%": "a percent sign",
|
|
20
|
+
" ": "a space",
|
|
21
|
+
" ": "a tab",
|
|
22
|
+
"\n": "a newline",
|
|
23
|
+
"\r": "a carriage return"
|
|
24
|
+
};
|
|
25
|
+
return named[ch] ?? `the character U+${ch.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`;
|
|
26
|
+
}
|
|
27
|
+
function firstRedirectingIndex(value) {
|
|
28
|
+
for (let i = 0; i < value.length; i++) {
|
|
29
|
+
const ch = value[i];
|
|
30
|
+
if (ch === " ") continue;
|
|
31
|
+
if (UNSAFE_CHARS.test(ch) || UNICODE_WHITESPACE.test(ch)) return i;
|
|
32
|
+
}
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
function redirectingViolation(value) {
|
|
36
|
+
if (value.length === 0) return "it is empty";
|
|
37
|
+
const i = firstRedirectingIndex(value);
|
|
38
|
+
if (i >= 0) return `it contains ${describeChar(value, i)}`;
|
|
39
|
+
if (value.includes("..")) return 'it contains ".."';
|
|
40
|
+
if (value === ".") return 'it is "."';
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function pathSegmentViolation(value) {
|
|
44
|
+
const redirecting = redirectingViolation(value);
|
|
45
|
+
if (redirecting !== null) return redirecting;
|
|
46
|
+
if (value.includes(" ")) return "it contains a space";
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function pathSegmentErrorMessage(label, value, reason) {
|
|
50
|
+
return `error: [INVALID_PATH_SEGMENT] ${label}: ${reason}, so it cannot be part of a request path. A value carrying a slash, backslash, question mark, hash, percent sign, whitespace, or ".." would redirect the request to a different endpoint. Received: ${JSON.stringify(value)}.
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/lib/account-arg.ts
|
|
55
|
+
var ACCOUNT_ID_RE = /^acc_[A-Za-z0-9_-]+$/;
|
|
56
|
+
var listCache = /* @__PURE__ */ new WeakMap();
|
|
57
|
+
var MAX_LOOKUP_PAGES = 10;
|
|
58
|
+
function toConnectedAccount(item) {
|
|
59
|
+
if (item === null || typeof item !== "object") return null;
|
|
60
|
+
const row = item;
|
|
61
|
+
const accountId = row["account_id"];
|
|
62
|
+
if (typeof accountId !== "string" || accountId.length === 0) return null;
|
|
63
|
+
const fullName = row["full_name"];
|
|
64
|
+
return {
|
|
65
|
+
accountId,
|
|
66
|
+
fullName: typeof fullName === "string" && fullName.length > 0 ? fullName : null
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function listConnectedAccounts(client) {
|
|
70
|
+
const cached = listCache.get(client);
|
|
71
|
+
if (cached) return cached;
|
|
72
|
+
const pending = (async () => {
|
|
73
|
+
const accounts = [];
|
|
74
|
+
let cursor;
|
|
75
|
+
for (let page = 0; page < MAX_LOOKUP_PAGES; page++) {
|
|
76
|
+
const params = { limit: 250 };
|
|
77
|
+
if (cursor) params["cursor"] = cursor;
|
|
78
|
+
const result = await client.accounts.list(
|
|
79
|
+
params
|
|
80
|
+
);
|
|
81
|
+
for (const item of result.items ?? []) {
|
|
82
|
+
const account = toConnectedAccount(item);
|
|
83
|
+
if (account) accounts.push(account);
|
|
84
|
+
}
|
|
85
|
+
if (!result.cursor) return { accounts, complete: true };
|
|
86
|
+
cursor = result.cursor;
|
|
87
|
+
}
|
|
88
|
+
return { accounts, complete: false };
|
|
89
|
+
})();
|
|
90
|
+
listCache.set(client, pending);
|
|
91
|
+
return pending;
|
|
92
|
+
}
|
|
93
|
+
function describeAccount(account) {
|
|
94
|
+
return account.fullName === null ? account.accountId : `"${account.fullName}" (${account.accountId})`;
|
|
95
|
+
}
|
|
96
|
+
function describeAll(accounts) {
|
|
97
|
+
return accounts.map(describeAccount).join(", ");
|
|
98
|
+
}
|
|
99
|
+
function matchAccounts(accounts, selector) {
|
|
100
|
+
const needle = selector.toLowerCase();
|
|
101
|
+
const byId = accounts.filter((a) => a.accountId === selector);
|
|
102
|
+
if (byId.length > 0) return byId;
|
|
103
|
+
const exactName = accounts.filter((a) => a.fullName?.toLowerCase() === needle);
|
|
104
|
+
if (exactName.length > 0) return exactName;
|
|
105
|
+
return accounts.filter((a) => a.fullName?.toLowerCase().startsWith(needle));
|
|
106
|
+
}
|
|
107
|
+
async function requireAccount(client, flags, out) {
|
|
108
|
+
const account = flags.account;
|
|
109
|
+
if (!account) {
|
|
110
|
+
out.stderr.write(
|
|
111
|
+
"error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n"
|
|
112
|
+
);
|
|
113
|
+
process.exit(2);
|
|
114
|
+
}
|
|
115
|
+
const selector = account.trim();
|
|
116
|
+
assertNoStdinPlaceholder("the --account value", [selector]);
|
|
117
|
+
const redirecting = redirectingViolation(selector);
|
|
118
|
+
if (redirecting !== null) {
|
|
119
|
+
out.stderr.write(pathSegmentErrorMessage("--account", selector, redirecting));
|
|
120
|
+
process.exit(2);
|
|
121
|
+
}
|
|
122
|
+
if (ACCOUNT_ID_RE.test(selector)) return selector;
|
|
123
|
+
if (flags.preview === true) {
|
|
124
|
+
out.stderr.write(
|
|
125
|
+
`note: --preview does not call the API, so --account "${selector}" is shown as you typed it. A real run resolves it to an account id first, and fails if it matches no connected account or more than one.
|
|
126
|
+
`
|
|
127
|
+
);
|
|
128
|
+
return selector;
|
|
129
|
+
}
|
|
130
|
+
let listed;
|
|
131
|
+
try {
|
|
132
|
+
listed = await listConnectedAccounts(client);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
const { CurviateError } = await import("@curviate/sdk");
|
|
135
|
+
if (err instanceof CurviateError) {
|
|
136
|
+
const e = err;
|
|
137
|
+
out.stderr.write(
|
|
138
|
+
`error: [${e.code}] could not look up connected accounts to resolve --account "${selector}": ${e.message}
|
|
139
|
+
`
|
|
140
|
+
);
|
|
141
|
+
process.exit(getExitCode(e.code));
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
if (!listed.complete) {
|
|
146
|
+
out.stderr.write(
|
|
147
|
+
`error: [ACCOUNT_LIST_TRUNCATED] --account "${selector}" cannot be resolved by name: this API key has more connected accounts than the resolver reads (it stops after ${MAX_LOOKUP_PAGES} pages of 250), so the name would be matched against an incomplete list and a single match would not prove there is only one. Pass the account id instead; an id is used as given and needs no lookup.
|
|
148
|
+
`
|
|
149
|
+
);
|
|
150
|
+
process.exit(2);
|
|
151
|
+
}
|
|
152
|
+
const accounts = listed.accounts;
|
|
153
|
+
const matches = matchAccounts(accounts, selector);
|
|
154
|
+
if (matches.length === 1) {
|
|
155
|
+
const resolved = matches[0].accountId;
|
|
156
|
+
const bad = pathSegmentViolation(resolved);
|
|
157
|
+
if (bad !== null) {
|
|
158
|
+
out.stderr.write(
|
|
159
|
+
pathSegmentErrorMessage(`the account id resolved from "${selector}"`, resolved, bad)
|
|
160
|
+
);
|
|
161
|
+
process.exit(2);
|
|
162
|
+
}
|
|
163
|
+
return resolved;
|
|
164
|
+
}
|
|
165
|
+
if (matches.length > 1) {
|
|
166
|
+
out.stderr.write(
|
|
167
|
+
`error: [ACCOUNT_AMBIGUOUS] --account "${selector}" matches ${matches.length} connected accounts: ${describeAll(matches)}. Pass the account id of the one you mean; this is not resolved by guessing, because acting as the wrong account cannot be undone.
|
|
168
|
+
`
|
|
169
|
+
);
|
|
170
|
+
process.exit(2);
|
|
171
|
+
}
|
|
172
|
+
const known = accounts.length === 0 ? "No accounts are connected on this API key." : `Connected accounts: ${describeAll(accounts)}.`;
|
|
173
|
+
out.stderr.write(
|
|
174
|
+
`error: [ACCOUNT_NAME_NOT_FOUND] --account "${selector}" matched no connected account. ${known}
|
|
175
|
+
`
|
|
176
|
+
);
|
|
177
|
+
process.exit(4);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
requireAccount
|
|
182
|
+
};
|
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
normalizeChatId,
|
|
17
17
|
resolveIdentifier
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-UEAX6KUB.js";
|
|
19
|
+
import {
|
|
20
|
+
requireAccount
|
|
21
|
+
} from "./chunk-3BO6GVS2.js";
|
|
19
22
|
import {
|
|
20
23
|
buildPreviewOutput
|
|
21
24
|
} from "./chunk-R3VLWLVV.js";
|
|
@@ -42,13 +45,6 @@ function buildOutputStreams() {
|
|
|
42
45
|
stderr: { write: (s) => process.stderr.write(s) }
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
|
-
function requireAccount(account, out) {
|
|
46
|
-
if (!account) {
|
|
47
|
-
out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
|
|
48
|
-
process.exit(2);
|
|
49
|
-
}
|
|
50
|
-
return account;
|
|
51
|
-
}
|
|
52
48
|
function rejectPreviewOnRead(preview, out) {
|
|
53
49
|
if (preview) {
|
|
54
50
|
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
@@ -95,7 +91,7 @@ function willSendAsNotice(chatId) {
|
|
|
95
91
|
return chatId.startsWith("COMPANY_") ? "Will send as a company page\n" : null;
|
|
96
92
|
}
|
|
97
93
|
async function runMessageNew(client, flags, out, _readStdin) {
|
|
98
|
-
const accountId = requireAccount(flags
|
|
94
|
+
const accountId = await requireAccount(client, flags, out);
|
|
99
95
|
const rawTo = flags.to ?? "";
|
|
100
96
|
const rawText = flags.text ?? "";
|
|
101
97
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
@@ -154,7 +150,7 @@ async function runMessageNew(client, flags, out, _readStdin) {
|
|
|
154
150
|
}
|
|
155
151
|
}
|
|
156
152
|
async function runMessageSend(client, flags, out, _readStdin) {
|
|
157
|
-
const accountId = requireAccount(flags
|
|
153
|
+
const accountId = await requireAccount(client, flags, out);
|
|
158
154
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
159
155
|
const rawText = flags.text ?? "";
|
|
160
156
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
@@ -205,7 +201,7 @@ async function runMessageSend(client, flags, out, _readStdin) {
|
|
|
205
201
|
async function runMessageGet(client, flags, out) {
|
|
206
202
|
rejectPreviewOnRead(flags.preview, out);
|
|
207
203
|
rejectAllOnNonPaginated(flags.all, out);
|
|
208
|
-
const accountId = requireAccount(flags
|
|
204
|
+
const accountId = await requireAccount(client, flags, out);
|
|
209
205
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
210
206
|
const messageId = flags.messageId ?? "";
|
|
211
207
|
const ns = client.account(accountId);
|
|
@@ -218,7 +214,7 @@ async function runMessageGet(client, flags, out) {
|
|
|
218
214
|
}
|
|
219
215
|
}
|
|
220
216
|
async function runMessageEdit(client, flags, out, _readStdin) {
|
|
221
|
-
const accountId = requireAccount(flags
|
|
217
|
+
const accountId = await requireAccount(client, flags, out);
|
|
222
218
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
223
219
|
const messageId = flags.messageId ?? "";
|
|
224
220
|
const rawText = flags.text ?? "";
|
|
@@ -243,7 +239,7 @@ async function runMessageEdit(client, flags, out, _readStdin) {
|
|
|
243
239
|
}
|
|
244
240
|
}
|
|
245
241
|
async function runMessageDelete(client, flags, out) {
|
|
246
|
-
const accountId = requireAccount(flags
|
|
242
|
+
const accountId = await requireAccount(client, flags, out);
|
|
247
243
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
248
244
|
const messageId = flags.messageId ?? "";
|
|
249
245
|
if (flags.preview) {
|
|
@@ -266,7 +262,7 @@ async function runMessageDelete(client, flags, out) {
|
|
|
266
262
|
}
|
|
267
263
|
}
|
|
268
264
|
async function runMessageReact(client, flags, out) {
|
|
269
|
-
const accountId = requireAccount(flags
|
|
265
|
+
const accountId = await requireAccount(client, flags, out);
|
|
270
266
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
271
267
|
const messageId = flags.messageId ?? "";
|
|
272
268
|
const reaction = flags.emoji ?? flags.emojiAlias ?? "";
|
|
@@ -296,7 +292,7 @@ async function runMessageReact(client, flags, out) {
|
|
|
296
292
|
}
|
|
297
293
|
async function runMessageAttachment(client, flags, out, isTTY) {
|
|
298
294
|
rejectPreviewOnRead(flags.preview, out);
|
|
299
|
-
const accountId = requireAccount(flags
|
|
295
|
+
const accountId = await requireAccount(client, flags, out);
|
|
300
296
|
const chatId = normalizeChatId(flags.chatId ?? "");
|
|
301
297
|
const messageId = flags.messageId ?? "";
|
|
302
298
|
const attachmentId = flags.attachmentId ?? "";
|
|
@@ -319,7 +315,7 @@ async function runMessageAttachment(client, flags, out, isTTY) {
|
|
|
319
315
|
}
|
|
320
316
|
}
|
|
321
317
|
async function runMessageInMail(client, flags, out, _readStdin) {
|
|
322
|
-
const accountId = requireAccount(flags
|
|
318
|
+
const accountId = await requireAccount(client, flags, out);
|
|
323
319
|
const rawTo = flags.to ?? "";
|
|
324
320
|
if (!rawTo) {
|
|
325
321
|
out.stderr.write(
|
|
@@ -373,7 +369,7 @@ async function runMessageInMail(client, flags, out, _readStdin) {
|
|
|
373
369
|
async function runMessageInMailBalance(client, flags, out) {
|
|
374
370
|
rejectPreviewOnRead(flags.preview, out);
|
|
375
371
|
rejectAllOnNonPaginated(flags.all, out);
|
|
376
|
-
const accountId = requireAccount(flags
|
|
372
|
+
const accountId = await requireAccount(client, flags, out);
|
|
377
373
|
const ns = client.account(accountId);
|
|
378
374
|
const outOpts = resolveOutputOpts(flags);
|
|
379
375
|
try {
|
|
@@ -33,6 +33,15 @@ function normalizeChatId(raw) {
|
|
|
33
33
|
if (match?.[1]) return match[1];
|
|
34
34
|
return raw;
|
|
35
35
|
}
|
|
36
|
+
var GROUP_URL_RE = /^https?:\/\/(?:[a-z0-9-]+\.)?linkedin\.com\/groups\/([^/?#]+)/i;
|
|
37
|
+
var GROUP_PATH_RE = /^\/groups\/([^/?#]+)\/?$/;
|
|
38
|
+
function normalizeGroupId(raw) {
|
|
39
|
+
const urlMatch = GROUP_URL_RE.exec(raw);
|
|
40
|
+
if (urlMatch?.[1]) return urlMatch[1];
|
|
41
|
+
const pathMatch = GROUP_PATH_RE.exec(raw);
|
|
42
|
+
if (pathMatch?.[1]) return pathMatch[1];
|
|
43
|
+
return raw;
|
|
44
|
+
}
|
|
36
45
|
var JOB_URL_RE = /\/jobs\/view\/(\d+)/;
|
|
37
46
|
function resolveJobIdentifier(raw) {
|
|
38
47
|
const match = JOB_URL_RE.exec(raw);
|
|
@@ -43,5 +52,6 @@ function resolveJobIdentifier(raw) {
|
|
|
43
52
|
export {
|
|
44
53
|
resolveIdentifier,
|
|
45
54
|
normalizeChatId,
|
|
55
|
+
normalizeGroupId,
|
|
46
56
|
resolveJobIdentifier
|
|
47
57
|
};
|
package/dist/cli.js
CHANGED
|
@@ -299,23 +299,23 @@ var main = defineCommand({
|
|
|
299
299
|
// ---------------------------------------------------------------------------
|
|
300
300
|
// Noun groups, lazy-loaded on first invocation.
|
|
301
301
|
// ---------------------------------------------------------------------------
|
|
302
|
-
profile: () => import("./profile-
|
|
303
|
-
company: () => import("./company-
|
|
304
|
-
job: () => import("./job-
|
|
305
|
-
connect: () => import("./connect-
|
|
306
|
-
search: () => import("./search-
|
|
307
|
-
inbox: () => import("./inbox-
|
|
308
|
-
inboxes: () => import("./inboxes-
|
|
309
|
-
message: () => import("./message-
|
|
310
|
-
post: () => import("./post-
|
|
311
|
-
comment: () => import("./comment-
|
|
312
|
-
account: () => import("./account-
|
|
302
|
+
profile: () => import("./profile-SUKHRWQP.js").then((m) => m.profileCommand),
|
|
303
|
+
company: () => import("./company-LHYDAO2C.js").then((m) => m.companyCommand),
|
|
304
|
+
job: () => import("./job-JQG34ATV.js").then((m) => m.jobCommand),
|
|
305
|
+
connect: () => import("./connect-5S4TFQAF.js").then((m) => m.connectCommand),
|
|
306
|
+
search: () => import("./search-MZQJDJTX.js").then((m) => m.searchCommand),
|
|
307
|
+
inbox: () => import("./inbox-3IQPPQMH.js").then((m) => m.inboxCommand),
|
|
308
|
+
inboxes: () => import("./inboxes-JK36F6SK.js").then((m) => m.inboxesCommand),
|
|
309
|
+
message: () => import("./message-2WIZESSM.js").then((m) => m.messageCommand),
|
|
310
|
+
post: () => import("./post-JRJMGV2I.js").then((m) => m.postCommand),
|
|
311
|
+
comment: () => import("./comment-TUXC7K72.js").then((m) => m.commentCommand),
|
|
312
|
+
account: () => import("./account-MIPWTAG5.js").then((m) => m.accountCommand),
|
|
313
313
|
webhook: () => import("./webhook-7ESDSIRU.js").then((m) => m.webhookCommand),
|
|
314
|
-
"sales-nav": () => import("./sales-nav-
|
|
315
|
-
recruiter: () => import("./recruiter-
|
|
316
|
-
group: () => import("./group-
|
|
317
|
-
feed: () => import("./feed-
|
|
318
|
-
notification: () => import("./notification-
|
|
314
|
+
"sales-nav": () => import("./sales-nav-4MFL2JSE.js").then((m) => m.salesNavCommand),
|
|
315
|
+
recruiter: () => import("./recruiter-NIKKDGMR.js").then((m) => m.recruiterCommand),
|
|
316
|
+
group: () => import("./group-PHGUOOJE.js").then((m) => m.groupCommand),
|
|
317
|
+
feed: () => import("./feed-ISNH4NXB.js").then((m) => m.feedCommand),
|
|
318
|
+
notification: () => import("./notification-ORSZY2IJ.js").then((m) => m.notificationCommand)
|
|
319
319
|
},
|
|
320
320
|
async run() {
|
|
321
321
|
const { runMain } = await import("citty");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
resolveMemberOrMeProviderId
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RJTG5YWE.js";
|
|
5
5
|
import {
|
|
6
6
|
AttachError,
|
|
7
7
|
describeAttachment,
|
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
pageDelayFromFlags,
|
|
13
13
|
streamAll
|
|
14
14
|
} from "./chunk-H6XD3F66.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-UEAX6KUB.js";
|
|
16
|
+
import {
|
|
17
|
+
requireAccount
|
|
18
|
+
} from "./chunk-3BO6GVS2.js";
|
|
16
19
|
import {
|
|
17
20
|
buildPreviewOutput
|
|
18
21
|
} from "./chunk-R3VLWLVV.js";
|
|
@@ -30,6 +33,7 @@ import {
|
|
|
30
33
|
import {
|
|
31
34
|
resolveTextOrStdin
|
|
32
35
|
} from "./chunk-ZYURL5VK.js";
|
|
36
|
+
import "./chunk-PMRQXBCP.js";
|
|
33
37
|
|
|
34
38
|
// src/commands/comment.ts
|
|
35
39
|
import { defineCommand } from "citty";
|
|
@@ -40,13 +44,6 @@ function buildOutputStreams() {
|
|
|
40
44
|
stderr: { write: (s) => process.stderr.write(s) }
|
|
41
45
|
};
|
|
42
46
|
}
|
|
43
|
-
function requireAccount(account, out) {
|
|
44
|
-
if (!account) {
|
|
45
|
-
out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
|
|
46
|
-
process.exit(2);
|
|
47
|
-
}
|
|
48
|
-
return account;
|
|
49
|
-
}
|
|
50
47
|
function rejectPreviewOnRead(preview, out) {
|
|
51
48
|
if (preview) {
|
|
52
49
|
out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
|
|
@@ -92,7 +89,7 @@ function assertReaction(reaction, out) {
|
|
|
92
89
|
}
|
|
93
90
|
async function runCommentList(client, flags, out) {
|
|
94
91
|
rejectPreviewOnRead(flags.preview, out);
|
|
95
|
-
const accountId = requireAccount(flags
|
|
92
|
+
const accountId = await requireAccount(client, flags, out);
|
|
96
93
|
const postId = flags.postId ?? "";
|
|
97
94
|
const ns = client.account(accountId);
|
|
98
95
|
const outOpts = resolveOutputOpts(flags);
|
|
@@ -119,7 +116,7 @@ async function runCommentList(client, flags, out) {
|
|
|
119
116
|
}
|
|
120
117
|
async function runCommentReplies(client, flags, out) {
|
|
121
118
|
rejectPreviewOnRead(flags.preview, out);
|
|
122
|
-
const accountId = requireAccount(flags
|
|
119
|
+
const accountId = await requireAccount(client, flags, out);
|
|
123
120
|
const postId = flags.postId ?? "";
|
|
124
121
|
const commentId = flags.commentId ?? "";
|
|
125
122
|
const ns = client.account(accountId);
|
|
@@ -147,7 +144,7 @@ async function runCommentReplies(client, flags, out) {
|
|
|
147
144
|
}
|
|
148
145
|
async function runCommentReactions(client, flags, out) {
|
|
149
146
|
rejectPreviewOnRead(flags.preview, out);
|
|
150
|
-
const accountId = requireAccount(flags
|
|
147
|
+
const accountId = await requireAccount(client, flags, out);
|
|
151
148
|
const postId = flags.postId ?? "";
|
|
152
149
|
const commentId = flags.commentId ?? "";
|
|
153
150
|
const ns = client.account(accountId);
|
|
@@ -175,7 +172,7 @@ async function runCommentReactions(client, flags, out) {
|
|
|
175
172
|
}
|
|
176
173
|
async function runCommentUser(client, flags, out) {
|
|
177
174
|
rejectPreviewOnRead(flags.preview, out);
|
|
178
|
-
const accountId = requireAccount(flags
|
|
175
|
+
const accountId = await requireAccount(client, flags, out);
|
|
179
176
|
const ns = client.account(accountId);
|
|
180
177
|
const outOpts = resolveOutputOpts(flags);
|
|
181
178
|
let userId;
|
|
@@ -207,7 +204,7 @@ async function runCommentUser(client, flags, out) {
|
|
|
207
204
|
}
|
|
208
205
|
}
|
|
209
206
|
async function runCommentAdd(client, flags, out, readStdin) {
|
|
210
|
-
const accountId = requireAccount(flags
|
|
207
|
+
const accountId = await requireAccount(client, flags, out);
|
|
211
208
|
const postId = flags.postId ?? "";
|
|
212
209
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
213
210
|
let attachBuffers = [];
|
|
@@ -248,7 +245,7 @@ async function runCommentAdd(client, flags, out, readStdin) {
|
|
|
248
245
|
}
|
|
249
246
|
}
|
|
250
247
|
async function runCommentReply(client, flags, out, readStdin) {
|
|
251
|
-
const accountId = requireAccount(flags
|
|
248
|
+
const accountId = await requireAccount(client, flags, out);
|
|
252
249
|
const postId = flags.postId ?? "";
|
|
253
250
|
const commentId = flags.commentId ?? "";
|
|
254
251
|
const attachPaths = normalizeAttachPaths(flags.attach);
|
|
@@ -290,7 +287,7 @@ async function runCommentReply(client, flags, out, readStdin) {
|
|
|
290
287
|
}
|
|
291
288
|
}
|
|
292
289
|
async function runCommentEdit(client, flags, out, readStdin) {
|
|
293
|
-
const accountId = requireAccount(flags
|
|
290
|
+
const accountId = await requireAccount(client, flags, out);
|
|
294
291
|
const postId = flags.postId ?? "";
|
|
295
292
|
const commentId = flags.commentId ?? "";
|
|
296
293
|
const text = await resolveTextOrStdin(flags.text ?? "", out, readStdin);
|
|
@@ -315,7 +312,7 @@ async function runCommentEdit(client, flags, out, readStdin) {
|
|
|
315
312
|
}
|
|
316
313
|
}
|
|
317
314
|
async function runCommentDelete(client, flags, out) {
|
|
318
|
-
const accountId = requireAccount(flags
|
|
315
|
+
const accountId = await requireAccount(client, flags, out);
|
|
319
316
|
const postId = flags.postId ?? "";
|
|
320
317
|
const commentId = flags.commentId ?? "";
|
|
321
318
|
if (flags.preview) {
|
|
@@ -338,7 +335,7 @@ async function runCommentDelete(client, flags, out) {
|
|
|
338
335
|
}
|
|
339
336
|
}
|
|
340
337
|
async function runCommentReact(client, flags, out) {
|
|
341
|
-
const accountId = requireAccount(flags
|
|
338
|
+
const accountId = await requireAccount(client, flags, out);
|
|
342
339
|
const postId = flags.postId ?? "";
|
|
343
340
|
const commentId = flags.commentId ?? "";
|
|
344
341
|
const reaction = flags.reaction ?? "";
|
|
@@ -364,7 +361,7 @@ async function runCommentReact(client, flags, out) {
|
|
|
364
361
|
}
|
|
365
362
|
}
|
|
366
363
|
async function runCommentUnreact(client, flags, out) {
|
|
367
|
-
const accountId = requireAccount(flags
|
|
364
|
+
const accountId = await requireAccount(client, flags, out);
|
|
368
365
|
const postId = flags.postId ?? "";
|
|
369
366
|
const commentId = flags.commentId ?? "";
|
|
370
367
|
const reaction = flags.reaction ?? "";
|