@curviate/cli 0.6.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.
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-R3VLWLVV.js";
5
5
  import {
6
6
  streamAll
7
- } from "./chunk-SND3NHCT.js";
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -68,7 +68,8 @@ async function runAccountList(client, flags, out) {
68
68
  const fn = (p) => client.accounts.list(p);
69
69
  for await (const item of streamAll(fn, params, {
70
70
  maxPages,
71
- onTruncated: (msg) => out.stderr.write(msg + "\n")
71
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
72
+ `)
72
73
  })) {
73
74
  out.stdout.write(JSON.stringify(item) + "\n");
74
75
  }
@@ -106,6 +106,78 @@ function slimInviteReceived(data) {
106
106
  cursor: d["cursor"] ?? null
107
107
  };
108
108
  }
109
+ function slimSearchPeopleItem(item) {
110
+ return {
111
+ id: item["id"] ?? null,
112
+ public_identifier: item["public_identifier"] ?? null,
113
+ full_name: item["full_name"] ?? null,
114
+ headline: item["headline"] ?? null,
115
+ location: item["location"] ?? null,
116
+ network_distance: item["network_distance"] ?? null
117
+ };
118
+ }
119
+ function slimSearchPeople(data) {
120
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
121
+ const items = Array.isArray(d["items"]) ? d["items"].map(slimSearchPeopleItem) : [];
122
+ return { ...d, items };
123
+ }
124
+ function slimSearchCompaniesItem(item) {
125
+ const result = {
126
+ id: item["id"] ?? null,
127
+ name: item["name"] ?? null,
128
+ location: item["location"] ?? null,
129
+ followers_count: item["followers_count"] ?? null
130
+ };
131
+ if (Object.prototype.hasOwnProperty.call(item, "industry")) {
132
+ result["industry"] = item["industry"];
133
+ }
134
+ return result;
135
+ }
136
+ function slimSearchCompanies(data) {
137
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
138
+ const items = Array.isArray(d["items"]) ? d["items"].map(slimSearchCompaniesItem) : [];
139
+ return { ...d, items };
140
+ }
141
+ function slimSearchJobsItem(item) {
142
+ return {
143
+ job_urn: item["job_urn"] ?? null,
144
+ title: item["title"] ?? null,
145
+ location: item["location"] ?? null,
146
+ company_name: item["company_name"] ?? null,
147
+ posted_at: item["posted_at"] ?? null,
148
+ easy_apply: item["easy_apply"] ?? null
149
+ };
150
+ }
151
+ function slimSearchJobs(data) {
152
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
153
+ const items = Array.isArray(d["items"]) ? d["items"].map(slimSearchJobsItem) : [];
154
+ return { ...d, items };
155
+ }
156
+ function slimSearchPostsItem(item) {
157
+ const rawAuthor = item["author"] !== null && item["author"] !== void 0 && typeof item["author"] === "object" ? item["author"] : null;
158
+ const author = rawAuthor !== null ? { name: rawAuthor["name"] ?? null } : null;
159
+ const rawText = item["text"];
160
+ let text;
161
+ if (rawText === null || rawText === void 0) {
162
+ text = null;
163
+ } else {
164
+ const s = String(rawText);
165
+ text = s.length > 200 ? s.slice(0, 200) : s;
166
+ }
167
+ return {
168
+ post_urn: item["post_urn"] ?? null,
169
+ posted_at: item["posted_at"] ?? null,
170
+ author,
171
+ text,
172
+ reaction_count: item["reaction_count"] ?? null,
173
+ comment_count: item["comment_count"] ?? null
174
+ };
175
+ }
176
+ function slimSearchPosts(data) {
177
+ const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
178
+ const items = Array.isArray(d["items"]) ? d["items"].map(slimSearchPostsItem) : [];
179
+ return { ...d, items };
180
+ }
109
181
  function slimCompany(data) {
110
182
  const d = data !== null && data !== void 0 && typeof data === "object" ? data : {};
111
183
  const rawMessaging = d["messaging"] !== null && d["messaging"] !== void 0 && typeof d["messaging"] === "object" ? d["messaging"] : null;
@@ -137,5 +209,13 @@ export {
137
209
  slimInviteSent,
138
210
  slimInviteReceivedItem,
139
211
  slimInviteReceived,
212
+ slimSearchPeopleItem,
213
+ slimSearchPeople,
214
+ slimSearchCompaniesItem,
215
+ slimSearchCompanies,
216
+ slimSearchJobsItem,
217
+ slimSearchJobs,
218
+ slimSearchPostsItem,
219
+ slimSearchPosts,
140
220
  slimCompany
141
221
  };
@@ -32,9 +32,8 @@ async function* streamAll(fn, params, opts = {}) {
32
32
  cursor = page.cursor;
33
33
  if (!cursor) break;
34
34
  if (pageCount >= maxPages) {
35
- const msg = `Streaming truncated at ${maxPages} page(s) \u2014 more results may exist. Increase --max-pages or use --cursor / --limit for manual paging.`;
36
35
  if (opts.onTruncated) {
37
- opts.onTruncated(msg);
36
+ opts.onTruncated(pageCount, cursor !== null && cursor !== void 0);
38
37
  }
39
38
  break;
40
39
  }
package/dist/cli.js CHANGED
@@ -143,17 +143,17 @@ var main = defineCommand({
143
143
  // ---------------------------------------------------------------------------
144
144
  // Noun groups — lazy-loaded on first invocation.
145
145
  // ---------------------------------------------------------------------------
146
- profile: () => import("./profile-NDDG26PL.js").then((m) => m.profileCommand),
147
- company: () => import("./company-SZPGJE3M.js").then((m) => m.companyCommand),
148
- connect: () => import("./connect-RMT7OS3I.js").then((m) => m.connectCommand),
149
- search: () => import("./search-QO237C4O.js").then((m) => m.searchCommand),
150
- inbox: () => import("./inbox-MIKI4HU3.js").then((m) => m.inboxCommand),
146
+ profile: () => import("./profile-4IPEB7MN.js").then((m) => m.profileCommand),
147
+ company: () => import("./company-WH2ZETTP.js").then((m) => m.companyCommand),
148
+ connect: () => import("./connect-YUJ2T5CN.js").then((m) => m.connectCommand),
149
+ search: () => import("./search-ONCNS43D.js").then((m) => m.searchCommand),
150
+ inbox: () => import("./inbox-YV6GPRG6.js").then((m) => m.inboxCommand),
151
151
  message: () => import("./message-YRMLMHK7.js").then((m) => m.messageCommand),
152
- post: () => import("./post-2FYHZAKC.js").then((m) => m.postCommand),
153
- account: () => import("./account-ZWBNNQKQ.js").then((m) => m.accountCommand),
154
- webhook: () => import("./webhook-FDIERREB.js").then((m) => m.webhookCommand),
155
- "sales-nav": () => import("./sales-nav-7WPN7BT4.js").then((m) => m.salesNavCommand),
156
- recruiter: () => import("./recruiter-3DRGDOVV.js").then((m) => m.recruiterCommand)
152
+ post: () => import("./post-KBSR3ADF.js").then((m) => m.postCommand),
153
+ account: () => import("./account-O5GZNE72.js").then((m) => m.accountCommand),
154
+ webhook: () => import("./webhook-F6CRIISR.js").then((m) => m.webhookCommand),
155
+ "sales-nav": () => import("./sales-nav-LSBARRGL.js").then((m) => m.salesNavCommand),
156
+ recruiter: () => import("./recruiter-7UEBT3JZ.js").then((m) => m.recruiterCommand)
157
157
  },
158
158
  async run() {
159
159
  const { runMain } = await import("citty");
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- slimCompany
4
- } from "./chunk-6VBOKOQJ.js";
5
2
  import {
6
3
  resolveIdentifier
7
4
  } from "./chunk-SZB3CFRZ.js";
5
+ import {
6
+ slimCompany
7
+ } from "./chunk-FX6VBI43.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -2,18 +2,18 @@
2
2
  import {
3
3
  buildPreviewOutput
4
4
  } from "./chunk-R3VLWLVV.js";
5
- import {
6
- slimInviteReceived,
7
- slimInviteReceivedItem,
8
- slimInviteSent,
9
- slimInviteSentItem
10
- } from "./chunk-6VBOKOQJ.js";
11
5
  import {
12
6
  resolveIdentifier
13
7
  } from "./chunk-SZB3CFRZ.js";
14
8
  import {
15
9
  streamAll
16
- } from "./chunk-SND3NHCT.js";
10
+ } from "./chunk-GXTZION6.js";
11
+ import {
12
+ slimInviteReceived,
13
+ slimInviteReceivedItem,
14
+ slimInviteSent,
15
+ slimInviteSentItem
16
+ } from "./chunk-FX6VBI43.js";
17
17
  import {
18
18
  createClient,
19
19
  renderError,
@@ -104,7 +104,8 @@ async function runConnectSent(client, flags, out) {
104
104
  const fn = (p) => ns.invites.listSent(p);
105
105
  for await (const item of streamAll(fn, params, {
106
106
  maxPages,
107
- onTruncated: (msg) => out.stderr.write(msg + "\n")
107
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
108
+ `)
108
109
  })) {
109
110
  const projected = !flags.verbose ? slimInviteSentItem(item) : item;
110
111
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -141,7 +142,8 @@ async function runConnectReceived(client, flags, out) {
141
142
  const fn = (p) => ns.invites.listReceived(p);
142
143
  for await (const item of streamAll(fn, params, {
143
144
  maxPages,
144
- onTruncated: (msg) => out.stderr.write(msg + "\n")
145
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
146
+ `)
145
147
  })) {
146
148
  const projected = !flags.verbose ? slimInviteReceivedItem(item) : item;
147
149
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-SZB3CFRZ.js";
5
5
  import {
6
6
  streamAll
7
- } from "./chunk-SND3NHCT.js";
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -92,7 +92,8 @@ async function runInboxList(client, flags, out) {
92
92
  const fn = (p) => ns.messaging.listChats(p);
93
93
  for await (const item of streamAll(fn, params, {
94
94
  maxPages,
95
- onTruncated: (msg) => out.stderr.write(msg + "\n")
95
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
96
+ `)
96
97
  })) {
97
98
  out.stdout.write(JSON.stringify(item) + "\n");
98
99
  }
@@ -140,7 +141,8 @@ async function runInboxMessages(client, flags, out) {
140
141
  const fn = (p) => ns.messaging.listMessages(chatId, p);
141
142
  for await (const item of streamAll(fn, params, {
142
143
  maxPages,
143
- onTruncated: (msg) => out.stderr.write(msg + "\n")
144
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
145
+ `)
144
146
  })) {
145
147
  out.stdout.write(JSON.stringify(item) + "\n");
146
148
  }
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-R3VLWLVV.js";
12
12
  import {
13
13
  streamAll
14
- } from "./chunk-SND3NHCT.js";
14
+ } from "./chunk-GXTZION6.js";
15
15
  import {
16
16
  createClient,
17
17
  renderError,
@@ -92,7 +92,8 @@ async function runPostList(client, flags, out) {
92
92
  const fn = (p) => ns.posts.list(p);
93
93
  for await (const item of streamAll(fn, params, {
94
94
  maxPages,
95
- onTruncated: (msg) => out.stderr.write(msg + "\n")
95
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
96
+ `)
96
97
  })) {
97
98
  out.stdout.write(JSON.stringify(item) + "\n");
98
99
  }
@@ -246,7 +247,8 @@ async function runPostComments(client, flags, out) {
246
247
  const fn = (p) => ns.posts.listComments(postId, p);
247
248
  for await (const item of streamAll(fn, params, {
248
249
  maxPages,
249
- onTruncated: (msg) => out.stderr.write(msg + "\n")
250
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
251
+ `)
250
252
  })) {
251
253
  out.stdout.write(JSON.stringify(item) + "\n");
252
254
  }
@@ -308,7 +310,8 @@ async function runPostReactions(client, flags, out) {
308
310
  const fn = (p) => ns.posts.listReactions(postId, p);
309
311
  for await (const item of streamAll(fn, params, {
310
312
  maxPages,
311
- onTruncated: (msg) => out.stderr.write(msg + "\n")
313
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
314
+ `)
312
315
  })) {
313
316
  out.stdout.write(JSON.stringify(item) + "\n");
314
317
  }
@@ -2,16 +2,16 @@
2
2
  import {
3
3
  buildPreviewOutput
4
4
  } from "./chunk-R3VLWLVV.js";
5
- import {
6
- slimProfile,
7
- slimProfileMe
8
- } from "./chunk-6VBOKOQJ.js";
9
5
  import {
10
6
  resolveIdentifier
11
7
  } from "./chunk-SZB3CFRZ.js";
12
8
  import {
13
9
  streamAll
14
- } from "./chunk-SND3NHCT.js";
10
+ } from "./chunk-GXTZION6.js";
11
+ import {
12
+ slimProfile,
13
+ slimProfileMe
14
+ } from "./chunk-FX6VBI43.js";
15
15
  import {
16
16
  createClient,
17
17
  renderError,
@@ -86,7 +86,8 @@ async function runProfileMe(client, flags, out) {
86
86
  const fn = (p) => ns.profiles.listPosts(ownSlug, p);
87
87
  for await (const item of streamAll(fn, params2, {
88
88
  maxPages,
89
- onTruncated: (msg) => out.stderr.write(msg + "\n")
89
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
90
+ `)
90
91
  })) {
91
92
  out.stdout.write(JSON.stringify(item) + "\n");
92
93
  }
@@ -99,7 +100,8 @@ async function runProfileMe(client, flags, out) {
99
100
  const fn = (p) => ns.profiles.listComments(ownSlug, p);
100
101
  for await (const item of streamAll(fn, params2, {
101
102
  maxPages,
102
- onTruncated: (msg) => out.stderr.write(msg + "\n")
103
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
104
+ `)
103
105
  })) {
104
106
  out.stdout.write(JSON.stringify(item) + "\n");
105
107
  }
@@ -112,7 +114,8 @@ async function runProfileMe(client, flags, out) {
112
114
  const fn = (p) => ns.profiles.listReactions(ownSlug, p);
113
115
  for await (const item of streamAll(fn, params2, {
114
116
  maxPages,
115
- onTruncated: (msg) => out.stderr.write(msg + "\n")
117
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
118
+ `)
116
119
  })) {
117
120
  out.stdout.write(JSON.stringify(item) + "\n");
118
121
  }
@@ -125,7 +128,8 @@ async function runProfileMe(client, flags, out) {
125
128
  const fn = (p) => ns.profiles.listFollowers(ownSlug, p);
126
129
  for await (const item of streamAll(fn, params2, {
127
130
  maxPages,
128
- onTruncated: (msg) => out.stderr.write(msg + "\n")
131
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
132
+ `)
129
133
  })) {
130
134
  out.stdout.write(JSON.stringify(item) + "\n");
131
135
  }
@@ -200,7 +204,8 @@ async function runProfileGet(client, flags, out) {
200
204
  const fn = (p) => ns.profiles.listPosts(postId, p);
201
205
  for await (const item of streamAll(fn, params, {
202
206
  maxPages,
203
- onTruncated: (msg) => out.stderr.write(msg + "\n")
207
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
208
+ `)
204
209
  })) {
205
210
  out.stdout.write(JSON.stringify(item) + "\n");
206
211
  }
@@ -216,7 +221,8 @@ async function runProfileGet(client, flags, out) {
216
221
  const fn = (p) => ns.profiles.listComments(resolvedId, p);
217
222
  for await (const item of streamAll(fn, params, {
218
223
  maxPages,
219
- onTruncated: (msg) => out.stderr.write(msg + "\n")
224
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
225
+ `)
220
226
  })) {
221
227
  out.stdout.write(JSON.stringify(item) + "\n");
222
228
  }
@@ -232,7 +238,8 @@ async function runProfileGet(client, flags, out) {
232
238
  const fn = (p) => ns.profiles.listReactions(resolvedId, p);
233
239
  for await (const item of streamAll(fn, params, {
234
240
  maxPages,
235
- onTruncated: (msg) => out.stderr.write(msg + "\n")
241
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
242
+ `)
236
243
  })) {
237
244
  out.stdout.write(JSON.stringify(item) + "\n");
238
245
  }
@@ -248,7 +255,8 @@ async function runProfileGet(client, flags, out) {
248
255
  const fn = (p) => ns.profiles.listFollowers(resolvedId, p);
249
256
  for await (const item of streamAll(fn, params, {
250
257
  maxPages,
251
- onTruncated: (msg) => out.stderr.write(msg + "\n")
258
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
259
+ `)
252
260
  })) {
253
261
  out.stdout.write(JSON.stringify(item) + "\n");
254
262
  }
@@ -295,7 +303,8 @@ async function runProfileConnections(client, flags, out) {
295
303
  const fn = (p) => ns.profiles.listConnections(p);
296
304
  for await (const item of streamAll(fn, params, {
297
305
  maxPages,
298
- onTruncated: (msg) => out.stderr.write(msg + "\n")
306
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
307
+ `)
299
308
  })) {
300
309
  out.stdout.write(JSON.stringify(item) + "\n");
301
310
  }
@@ -20,7 +20,7 @@ import {
20
20
  } from "./chunk-42VUUKQ3.js";
21
21
  import {
22
22
  streamAll
23
- } from "./chunk-SND3NHCT.js";
23
+ } from "./chunk-GXTZION6.js";
24
24
  import {
25
25
  createClient,
26
26
  renderError,
@@ -242,7 +242,8 @@ async function runRecruiterSearchPeople(client, flags, out, readers = DEFAULT_FI
242
242
  };
243
243
  for await (const item of streamAll(fn, params, {
244
244
  maxPages,
245
- onTruncated: (msg) => out.stderr.write(msg + "\n")
245
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
246
+ `)
246
247
  })) {
247
248
  out.stdout.write(JSON.stringify(item) + "\n");
248
249
  }
@@ -287,7 +288,8 @@ async function runRecruiterListProjects(client, flags, out) {
287
288
  const fn = (p) => ns.recruiter.listProjects(p);
288
289
  for await (const item of streamAll(fn, params, {
289
290
  maxPages,
290
- onTruncated: (msg) => out.stderr.write(msg + "\n")
291
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
292
+ `)
291
293
  })) {
292
294
  out.stdout.write(JSON.stringify(item) + "\n");
293
295
  }
@@ -404,7 +406,8 @@ async function runRecruiterListJobs(client, flags, out) {
404
406
  const fn = (p) => ns.recruiter.listJobs(p);
405
407
  for await (const item of streamAll(fn, params, {
406
408
  maxPages,
407
- onTruncated: (msg) => out.stderr.write(msg + "\n")
409
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
410
+ `)
408
411
  })) {
409
412
  out.stdout.write(JSON.stringify(item) + "\n");
410
413
  }
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-42VUUKQ3.js";
18
18
  import {
19
19
  streamAll
20
- } from "./chunk-SND3NHCT.js";
20
+ } from "./chunk-GXTZION6.js";
21
21
  import {
22
22
  createClient,
23
23
  renderError,
@@ -123,7 +123,8 @@ async function runSalesNavSearchPeople(client, flags, out, readers = DEFAULT_FIL
123
123
  };
124
124
  for await (const item of streamAll(fn, params, {
125
125
  maxPages,
126
- onTruncated: (msg) => out.stderr.write(msg + "\n")
126
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
127
+ `)
127
128
  })) {
128
129
  out.stdout.write(JSON.stringify(item) + "\n");
129
130
  }
@@ -171,7 +172,8 @@ async function runSalesNavSearchCompanies(client, flags, out, readers = DEFAULT_
171
172
  };
172
173
  for await (const item of streamAll(fn, params, {
173
174
  maxPages,
174
- onTruncated: (msg) => out.stderr.write(msg + "\n")
175
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
176
+ `)
175
177
  })) {
176
178
  out.stdout.write(JSON.stringify(item) + "\n");
177
179
  }
@@ -7,7 +7,17 @@ import {
7
7
  } from "./chunk-42VUUKQ3.js";
8
8
  import {
9
9
  streamAll
10
- } from "./chunk-SND3NHCT.js";
10
+ } from "./chunk-GXTZION6.js";
11
+ import {
12
+ slimSearchCompanies,
13
+ slimSearchCompaniesItem,
14
+ slimSearchJobs,
15
+ slimSearchJobsItem,
16
+ slimSearchPeople,
17
+ slimSearchPeopleItem,
18
+ slimSearchPosts,
19
+ slimSearchPostsItem
20
+ } from "./chunk-FX6VBI43.js";
11
21
  import {
12
22
  createClient,
13
23
  renderError,
@@ -21,14 +31,15 @@ import {
21
31
 
22
32
  // src/commands/search.ts
23
33
  import { defineCommand } from "citty";
34
+ var PEOPLE_INVALID_FLAGS = ["seniority", "function", "employment-type", "sort-by"];
24
35
  var FILTER_FLAGS = {
25
36
  filters: {
26
37
  type: "string",
27
- description: "Filter body as a JSON object (escape hatch for the full filter surface); '-' reads JSON from stdin."
38
+ description: "Filter body as a JSON object (named flags win on conflict; server validates and strips unknown fields); '-' reads JSON from stdin."
28
39
  },
29
40
  "filters-file": {
30
41
  type: "string",
31
- description: "Path to a JSON file with the filter body."
42
+ description: "Path to a JSON file with the filter body (named flags win on conflict)."
32
43
  }
33
44
  };
34
45
  function buildOutputStreams() {
@@ -60,7 +71,8 @@ function resolveOutputOpts(flags) {
60
71
  return {
61
72
  json: (flags.json ?? false) || !process.stdout.isTTY,
62
73
  isTTY: process.stdout.isTTY ?? false,
63
- fields: flags.fields
74
+ fields: flags.fields,
75
+ verbose: flags.verbose ?? false
64
76
  };
65
77
  }
66
78
  function applyCommonSearchFlags(body, flags) {
@@ -79,6 +91,11 @@ var NAMED_FLAG_MAPPERS = {
79
91
  if (flags["network-distance"]) body["network_distance"] = splitCsvNumbers(flags["network-distance"]);
80
92
  if (flags["connections-of"]) body["connections_of"] = flags["connections-of"];
81
93
  if (flags["followers-of"]) body["followers_of"] = flags["followers-of"];
94
+ if (flags.title) {
95
+ const existingAK = body["advanced_keywords"] !== null && body["advanced_keywords"] !== void 0 && typeof body["advanced_keywords"] === "object" && !Array.isArray(body["advanced_keywords"]) ? body["advanced_keywords"] : {};
96
+ body["advanced_keywords"] = { ...existingAK, title: flags.title };
97
+ }
98
+ if (flags["profile-language"]) body["profile_language"] = splitCsv(flags["profile-language"]);
82
99
  },
83
100
  companies(body, flags) {
84
101
  if (flags.industry) body["industry"] = splitCsv(flags.industry);
@@ -87,17 +104,20 @@ var NAMED_FLAG_MAPPERS = {
87
104
  },
88
105
  posts(body, flags) {
89
106
  if (flags["sort-by"]) body["sort_by"] = flags["sort-by"];
90
- if (flags["date-posted"]) body["date_posted"] = flags["date-posted"];
107
+ if (flags["date-posted"]) body["date_posted"] = flags["date-posted"].replace(/-/g, "_");
91
108
  if (flags["content-type"]) body["content_type"] = flags["content-type"];
92
109
  },
93
110
  jobs(body, flags) {
94
- if (flags.location) body["location"] = splitCsv(flags.location);
111
+ if (flags.location) body["region"] = flags.location;
95
112
  if (flags.industry) body["industry"] = splitCsv(flags.industry);
96
113
  if (flags.seniority) body["seniority"] = splitCsv(flags.seniority);
97
114
  if (flags.function) body["function"] = splitCsv(flags.function);
98
115
  if (flags["job-type"]) body["job_type"] = splitCsv(flags["job-type"]);
99
116
  if (flags.company) body["company"] = splitCsv(flags.company);
100
117
  if (flags["sort-by"]) body["sort_by"] = flags["sort-by"];
118
+ if (flags["date-posted"] !== void 0 && flags["date-posted"] !== "") {
119
+ body["date_posted"] = Number(flags["date-posted"]);
120
+ }
101
121
  if (flags.region) body["region"] = flags.region;
102
122
  }
103
123
  };
@@ -111,9 +131,19 @@ async function buildSearchBody(kind, flags, readers) {
111
131
  }
112
132
  async function runSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READERS) {
113
133
  rejectPreviewOnRead(flags.preview, out);
134
+ for (const f of PEOPLE_INVALID_FLAGS) {
135
+ if (flags[f]) {
136
+ out.stderr.write(
137
+ `error: --${f} is not valid for \`search people\` (classic LinkedIn search). Use \`search jobs\` or \`sales-nav search people\` for this filter.
138
+ `
139
+ );
140
+ process.exit(2);
141
+ }
142
+ }
114
143
  const accountId = requireAccount(flags.account, out);
115
144
  const ns = client.account(accountId);
116
145
  const outOpts = resolveOutputOpts(flags);
146
+ const verbose = flags.verbose ?? false;
117
147
  const all = flags.all ?? false;
118
148
  const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
119
149
  const assembled = await buildSearchBody("people", flags, readers);
@@ -128,13 +158,17 @@ async function runSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READ
128
158
  const fn = (p) => ns.search.people(p);
129
159
  for await (const item of streamAll(fn, body, {
130
160
  maxPages,
131
- onTruncated: (msg) => out.stderr.write(msg + "\n")
161
+ // Write JSON truncation sentinel to stdout as the last NDJSON line
162
+ onTruncated: (pagesFetched, hasMore) => out.stdout.write(
163
+ JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
164
+ )
132
165
  })) {
133
- out.stdout.write(JSON.stringify(item) + "\n");
166
+ const projected = verbose ? item : slimSearchPeopleItem(item);
167
+ out.stdout.write(JSON.stringify(projected) + "\n");
134
168
  }
135
169
  } else {
136
170
  const result = await ns.search.people(body);
137
- renderSuccess(result, outOpts, out);
171
+ renderSuccess(result, { ...outOpts, slim: slimSearchPeople }, out);
138
172
  }
139
173
  } catch (err) {
140
174
  const { CurviateError } = await import("@curviate/sdk");
@@ -152,6 +186,7 @@ async function runSearchCompanies(client, flags, out, readers = DEFAULT_FILTER_R
152
186
  const accountId = requireAccount(flags.account, out);
153
187
  const ns = client.account(accountId);
154
188
  const outOpts = resolveOutputOpts(flags);
189
+ const verbose = flags.verbose ?? false;
155
190
  const all = flags.all ?? false;
156
191
  const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
157
192
  const assembled = await buildSearchBody("companies", flags, readers);
@@ -166,13 +201,16 @@ async function runSearchCompanies(client, flags, out, readers = DEFAULT_FILTER_R
166
201
  const fn = (p) => ns.search.companies(p);
167
202
  for await (const item of streamAll(fn, body, {
168
203
  maxPages,
169
- onTruncated: (msg) => out.stderr.write(msg + "\n")
204
+ onTruncated: (pagesFetched, hasMore) => out.stdout.write(
205
+ JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
206
+ )
170
207
  })) {
171
- out.stdout.write(JSON.stringify(item) + "\n");
208
+ const projected = verbose ? item : slimSearchCompaniesItem(item);
209
+ out.stdout.write(JSON.stringify(projected) + "\n");
172
210
  }
173
211
  } else {
174
212
  const result = await ns.search.companies(body);
175
- renderSuccess(result, outOpts, out);
213
+ renderSuccess(result, { ...outOpts, slim: slimSearchCompanies }, out);
176
214
  }
177
215
  } catch (err) {
178
216
  const { CurviateError } = await import("@curviate/sdk");
@@ -190,6 +228,7 @@ async function runSearchPosts(client, flags, out, readers = DEFAULT_FILTER_READE
190
228
  const accountId = requireAccount(flags.account, out);
191
229
  const ns = client.account(accountId);
192
230
  const outOpts = resolveOutputOpts(flags);
231
+ const verbose = flags.verbose ?? false;
193
232
  const all = flags.all ?? false;
194
233
  const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
195
234
  const assembled = await buildSearchBody("posts", flags, readers);
@@ -204,13 +243,16 @@ async function runSearchPosts(client, flags, out, readers = DEFAULT_FILTER_READE
204
243
  const fn = (p) => ns.search.posts(p);
205
244
  for await (const item of streamAll(fn, body, {
206
245
  maxPages,
207
- onTruncated: (msg) => out.stderr.write(msg + "\n")
246
+ onTruncated: (pagesFetched, hasMore) => out.stdout.write(
247
+ JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
248
+ )
208
249
  })) {
209
- out.stdout.write(JSON.stringify(item) + "\n");
250
+ const projected = verbose ? item : slimSearchPostsItem(item);
251
+ out.stdout.write(JSON.stringify(projected) + "\n");
210
252
  }
211
253
  } else {
212
254
  const result = await ns.search.posts(body);
213
- renderSuccess(result, outOpts, out);
255
+ renderSuccess(result, { ...outOpts, slim: slimSearchPosts }, out);
214
256
  }
215
257
  } catch (err) {
216
258
  const { CurviateError } = await import("@curviate/sdk");
@@ -228,6 +270,7 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
228
270
  const accountId = requireAccount(flags.account, out);
229
271
  const ns = client.account(accountId);
230
272
  const outOpts = resolveOutputOpts(flags);
273
+ const verbose = flags.verbose ?? false;
231
274
  const all = flags.all ?? false;
232
275
  const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
233
276
  const assembled = await buildSearchBody("jobs", flags, readers);
@@ -242,13 +285,16 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
242
285
  const fn = (p) => ns.search.jobs(p);
243
286
  for await (const item of streamAll(fn, body, {
244
287
  maxPages,
245
- onTruncated: (msg) => out.stderr.write(msg + "\n")
288
+ onTruncated: (pagesFetched, hasMore) => out.stdout.write(
289
+ JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
290
+ )
246
291
  })) {
247
- out.stdout.write(JSON.stringify(item) + "\n");
292
+ const projected = verbose ? item : slimSearchJobsItem(item);
293
+ out.stdout.write(JSON.stringify(projected) + "\n");
248
294
  }
249
295
  } else {
250
296
  const result = await ns.search.jobs(body);
251
- renderSuccess(result, outOpts, out);
297
+ renderSuccess(result, { ...outOpts, slim: slimSearchJobs }, out);
252
298
  }
253
299
  } catch (err) {
254
300
  const { CurviateError } = await import("@curviate/sdk");
@@ -299,7 +345,10 @@ var searchPeopleCommand = defineCommand({
299
345
  school: { type: "string", description: "School ids (comma-separated)." },
300
346
  "network-distance": { type: "string", description: "Network distance, 1-3 (comma-separated)." },
301
347
  "connections-of": { type: "string", description: "Member id whose connections to search." },
302
- "followers-of": { type: "string", description: "Member id whose followers to search." }
348
+ "followers-of": { type: "string", description: "Member id whose followers to search." },
349
+ // People-specific filter flags
350
+ title: { type: "string", description: "Job title keyword filter (maps to advanced_keywords.title)." },
351
+ "profile-language": { type: "string", description: "Profile language codes (comma-separated, e.g. en,de)." }
303
352
  },
304
353
  async run({ args }) {
305
354
  const flags = args;
@@ -356,7 +405,7 @@ var searchPostsCommand = defineCommand({
356
405
  url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
357
406
  ...FILTER_FLAGS,
358
407
  "sort-by": { type: "string", description: "Sort order (e.g. relevance, date)." },
359
- "date-posted": { type: "string", description: "Date-posted window (e.g. past-day, past-week)." },
408
+ "date-posted": { type: "string", description: "time window: past_day, past_week, or past_month (hyphens also accepted: past-day, past-week, past-month)" },
360
409
  "content-type": { type: "string", description: "Content type (e.g. videos, images, jobs)." }
361
410
  },
362
411
  async run({ args }) {
@@ -384,14 +433,16 @@ var searchJobsCommand = defineCommand({
384
433
  keywords: { type: "string", description: "Full-text keyword search." },
385
434
  url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
386
435
  ...FILTER_FLAGS,
387
- location: { type: "string", description: "Location ids (comma-separated)." },
436
+ // On jobs, --location maps to the geo region filter (not a location array — different API shape for jobs vs people)
437
+ location: { type: "string", description: "geo region id (single id; resolve via search parameters --type LOCATION); maps to region filter" },
388
438
  industry: { type: "string", description: "Industry ids (comma-separated)." },
389
439
  seniority: { type: "string", description: "Seniority ids (comma-separated)." },
390
440
  function: { type: "string", description: "Job function ids (comma-separated)." },
391
441
  "job-type": { type: "string", description: "Job type ids, e.g. F,P (comma-separated)." },
392
442
  company: { type: "string", description: "Company ids (comma-separated)." },
393
443
  "sort-by": { type: "string", description: "Sort order (e.g. relevance, recent)." },
394
- region: { type: "string", description: "Region id." }
444
+ "date-posted": { type: "string", description: "maximum job age in days (a number \u2014 e.g. 7, 14, 30; not an enum string)" },
445
+ region: { type: "string", description: "alias for --location (same body field: region)" }
395
446
  },
396
447
  async run({ args }) {
397
448
  const flags = args;
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-R3VLWLVV.js";
5
5
  import {
6
6
  streamAll
7
- } from "./chunk-SND3NHCT.js";
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -110,7 +110,8 @@ async function runWebhookList(client, flags, out) {
110
110
  const fn = (p) => client.webhooks.list(p);
111
111
  for await (const item of streamAll(fn, params, {
112
112
  maxPages,
113
- onTruncated: (msg) => out.stderr.write(msg + "\n")
113
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
114
+ `)
114
115
  })) {
115
116
  out.stdout.write(JSON.stringify(item) + "\n");
116
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "private": false,
5
5
  "description": "Official command-line interface for the Curviate API.",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "clean": "rm -rf dist *.tsbuildinfo"
41
41
  },
42
42
  "dependencies": {
43
- "@curviate/sdk": "^0.4.0",
43
+ "@curviate/sdk": "^0.4.1",
44
44
  "citty": "^0.1.6"
45
45
  },
46
46
  "devDependencies": {