@curviate/cli 0.18.0 → 0.19.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.
@@ -31,6 +31,7 @@ import {
31
31
  } from "./chunk-M33MI53G.js";
32
32
  import {
33
33
  GLOBAL_FLAGS,
34
+ READ_SINGLE_FLAGS,
34
35
  WRITE_SINGLE_FLAGS
35
36
  } from "./chunk-TMU3CSPR.js";
36
37
 
@@ -425,6 +426,75 @@ async function handleSdkError(err, outOpts, out) {
425
426
  renderUnexpectedError(err, out);
426
427
  process.exit(1);
427
428
  }
429
+ async function runProfileSubscription(client, flags, out) {
430
+ rejectPreviewOnRead(flags.preview, out);
431
+ rejectAllOnNonPaginated(flags.all, out);
432
+ const accountId = requireAccount(flags.account, out);
433
+ const ns = client.account(accountId);
434
+ const outOpts = resolveOutputOpts(flags);
435
+ try {
436
+ const result = await ns.profile.subscription();
437
+ renderSuccess(result, outOpts, out);
438
+ } catch (err) {
439
+ await handleSdkError(err, outOpts, out);
440
+ }
441
+ }
442
+ async function runProfileAnalytics(client, flags, out) {
443
+ rejectPreviewOnRead(flags.preview, out);
444
+ rejectAllOnNonPaginated(flags.all, out);
445
+ const accountId = requireAccount(flags.account, out);
446
+ const ns = client.account(accountId);
447
+ const outOpts = resolveOutputOpts(flags);
448
+ try {
449
+ const result = await ns.profile.analytics();
450
+ renderSuccess(result, outOpts, out);
451
+ } catch (err) {
452
+ await handleSdkError(err, outOpts, out);
453
+ }
454
+ }
455
+ async function runProfileVisitors(client, flags, out) {
456
+ rejectPreviewOnRead(flags.preview, out);
457
+ const accountId = requireAccount(flags.account, out);
458
+ const ns = client.account(accountId);
459
+ const outOpts = resolveOutputOpts(flags);
460
+ const all = flags.all ?? false;
461
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
462
+ const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
463
+ const cursor = flags.cursor;
464
+ const params = {};
465
+ if (limit !== void 0) params.limit = limit;
466
+ if (cursor) params.cursor = cursor;
467
+ try {
468
+ if (all) {
469
+ const fn = (p) => ns.profile.visitors(p);
470
+ for await (const item of streamAll(fn, params, {
471
+ maxPages,
472
+ out,
473
+ pageDelayMs: pageDelayFromFlags(flags)
474
+ })) {
475
+ out.stdout.write(JSON.stringify(item) + "\n");
476
+ }
477
+ } else {
478
+ const result = await ns.profile.visitors(params);
479
+ renderSuccess(result, outOpts, out);
480
+ }
481
+ } catch (err) {
482
+ await handleSdkError(err, outOpts, out);
483
+ }
484
+ }
485
+ async function runProfileSsi(client, flags, out) {
486
+ rejectPreviewOnRead(flags.preview, out);
487
+ rejectAllOnNonPaginated(flags.all, out);
488
+ const accountId = requireAccount(flags.account, out);
489
+ const ns = client.account(accountId);
490
+ const outOpts = resolveOutputOpts(flags);
491
+ try {
492
+ const result = await ns.profile.ssi();
493
+ renderSuccess(result, outOpts, out);
494
+ } catch (err) {
495
+ await handleSdkError(err, outOpts, out);
496
+ }
497
+ }
428
498
  async function runProfileUpdate(client, flags, out) {
429
499
  const accountId = requireAccount(flags.account, out);
430
500
  const body = {};
@@ -746,6 +816,34 @@ var profileFollowingCommand = defineCommand({
746
816
  await withClient(args, runProfileFollowing);
747
817
  }
748
818
  });
819
+ var profileSubscriptionCommand = defineCommand({
820
+ meta: { name: "subscription", description: "Read your premium subscription: entitlements, primary plan, and LinkedIn management links. A free account is a valid result (has_premium:false)." },
821
+ args: { ...READ_SINGLE_FLAGS },
822
+ async run({ args }) {
823
+ await withClient(args, runProfileSubscription);
824
+ }
825
+ });
826
+ var profileAnalyticsCommand = defineCommand({
827
+ meta: { name: "analytics", description: "Read your performance headline metrics: profile viewers, followers, post impressions, and search appearances (fixed LinkedIn reporting windows, no window selector)." },
828
+ args: { ...READ_SINGLE_FLAGS },
829
+ async run({ args }) {
830
+ await withClient(args, runProfileAnalytics);
831
+ }
832
+ });
833
+ var profileVisitorsCommand = defineCommand({
834
+ meta: { name: "visitors", description: "List people who recently viewed your profile, classified by disclosure fidelity (identified, semi-anonymous, or aggregate; Premium sees more identified viewers)." },
835
+ args: { ...GLOBAL_FLAGS },
836
+ async run({ args }) {
837
+ await withClient(args, runProfileVisitors);
838
+ }
839
+ });
840
+ var profileSsiCommand = defineCommand({
841
+ meta: { name: "ssi", description: "Read your Social Selling Index: the overall score, its four pillar breakdowns, and industry/network percentile ranks." },
842
+ args: { ...READ_SINGLE_FLAGS },
843
+ async run({ args }) {
844
+ await withClient(args, runProfileSsi);
845
+ }
846
+ });
749
847
  var profileCommand = defineCommand({
750
848
  meta: { name: "profile", description: "LinkedIn profile operations." },
751
849
  args: {
@@ -769,7 +867,11 @@ var profileCommand = defineCommand({
769
867
  follow: profileFollowCommand,
770
868
  unfollow: profileUnfollowCommand,
771
869
  followers: profileFollowersCommand,
772
- following: profileFollowingCommand
870
+ following: profileFollowingCommand,
871
+ subscription: profileSubscriptionCommand,
872
+ analytics: profileAnalyticsCommand,
873
+ visitors: profileVisitorsCommand,
874
+ ssi: profileSsiCommand
773
875
  },
774
876
  async run({ args }) {
775
877
  const flags = args;
@@ -797,6 +899,7 @@ var profileCommand = defineCommand({
797
899
  });
798
900
  export {
799
901
  profileCommand,
902
+ runProfileAnalytics,
800
903
  runProfileEndorse,
801
904
  runProfileFollow,
802
905
  runProfileFollowers,
@@ -804,6 +907,9 @@ export {
804
907
  runProfileGet,
805
908
  runProfileMe,
806
909
  runProfileRelations,
910
+ runProfileSsi,
911
+ runProfileSubscription,
807
912
  runProfileUnfollow,
808
- runProfileUpdate
913
+ runProfileUpdate,
914
+ runProfileVisitors
809
915
  };
@@ -384,6 +384,115 @@ async function runSearchParameters(client, flags, out) {
384
384
  process.exit(1);
385
385
  }
386
386
  }
387
+ async function runSearchGroups(client, flags, out) {
388
+ rejectPreviewOnRead(flags.preview, out);
389
+ const keywords = flags.query ?? "";
390
+ if (!keywords) {
391
+ out.stderr.write("error: <query> is required.\n");
392
+ process.exit(2);
393
+ }
394
+ const accountId = requireAccount(flags.account, out);
395
+ const ns = client.account(accountId);
396
+ const outOpts = resolveOutputOpts(flags);
397
+ const all = flags.all ?? false;
398
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
399
+ const query = { keywords };
400
+ if (flags.limit) query.limit = parseInt(flags.limit, 10);
401
+ if (flags.cursor) query.cursor = flags.cursor;
402
+ try {
403
+ if (all) {
404
+ const fn = (p) => ns.search.groups(p);
405
+ for await (const item of streamAll(fn, query, {
406
+ maxPages,
407
+ out,
408
+ pageDelayMs: pageDelayFromFlags(flags)
409
+ })) {
410
+ out.stdout.write(JSON.stringify(item) + "\n");
411
+ }
412
+ } else {
413
+ const result = await ns.search.groups(query);
414
+ renderSuccess(result, outOpts, out);
415
+ }
416
+ } catch (err) {
417
+ const { CurviateError } = await import("@curviate/sdk");
418
+ if (err instanceof CurviateError) {
419
+ const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
420
+ renderError(err, outOpts, out);
421
+ process.exit(getExitCode(err.code));
422
+ }
423
+ renderUnexpectedError(err, out);
424
+ process.exit(1);
425
+ }
426
+ }
427
+ async function runSearchServices(client, flags, out) {
428
+ rejectPreviewOnRead(flags.preview, out);
429
+ const accountId = requireAccount(flags.account, out);
430
+ const ns = client.account(accountId);
431
+ const outOpts = resolveOutputOpts(flags);
432
+ const all = flags.all ?? false;
433
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
434
+ const body = {};
435
+ if (flags.keywords) body["keywords"] = flags.keywords;
436
+ if (flags["service-category"]) body["service_category"] = splitCsv(flags["service-category"]);
437
+ if (flags.location) body["location"] = splitCsv(flags.location);
438
+ if (flags.connections) {
439
+ body["connections"] = splitCsvNumbers(flags.connections);
440
+ }
441
+ if (flags.language) body["language"] = splitCsv(flags.language);
442
+ if (flags.limit) body["limit"] = parseInt(flags.limit, 10);
443
+ if (flags.cursor) body["cursor"] = flags.cursor;
444
+ try {
445
+ if (all) {
446
+ const fn = (p) => ns.search.services(p);
447
+ for await (const item of streamAll(fn, body, {
448
+ maxPages,
449
+ out,
450
+ pageDelayMs: pageDelayFromFlags(flags)
451
+ })) {
452
+ out.stdout.write(JSON.stringify(item) + "\n");
453
+ }
454
+ } else {
455
+ const result = await ns.search.services(body);
456
+ renderSuccess(result, outOpts, out);
457
+ }
458
+ } catch (err) {
459
+ const { CurviateError } = await import("@curviate/sdk");
460
+ if (err instanceof CurviateError) {
461
+ const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
462
+ renderError(err, outOpts, out);
463
+ process.exit(getExitCode(err.code));
464
+ }
465
+ renderUnexpectedError(err, out);
466
+ process.exit(1);
467
+ }
468
+ }
469
+ async function runSearchServiceParameters(client, flags, out) {
470
+ rejectPreviewOnRead(flags.preview, out);
471
+ rejectAllOnNonPaginated(flags.all, out);
472
+ if (!flags.keywords) {
473
+ out.stderr.write("error: --keywords is required.\n");
474
+ process.exit(2);
475
+ }
476
+ const accountId = requireAccount(flags.account, out);
477
+ const ns = client.account(accountId);
478
+ const outOpts = resolveOutputOpts(flags);
479
+ const query = { keywords: flags.keywords };
480
+ if (flags.type) query.type = flags.type;
481
+ if (flags.limit) query.limit = parseInt(flags.limit, 10);
482
+ try {
483
+ const result = await ns.search.getServiceParameters(query);
484
+ renderSuccess(result, outOpts, out);
485
+ } catch (err) {
486
+ const { CurviateError } = await import("@curviate/sdk");
487
+ if (err instanceof CurviateError) {
488
+ const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
489
+ renderError(err, outOpts, out);
490
+ process.exit(getExitCode(err.code));
491
+ }
492
+ renderUnexpectedError(err, out);
493
+ process.exit(1);
494
+ }
495
+ }
387
496
  async function runSearchFromUrl(client, flags, out) {
388
497
  rejectPreviewOnRead(flags.preview, out);
389
498
  const accountId = requireAccount(flags.account, out);
@@ -605,6 +714,92 @@ var searchParametersCommand = defineCommand({
605
714
  await runSearchParameters(client, { ...flags, account: flags.account ?? cfg.account }, out);
606
715
  }
607
716
  });
717
+ var searchGroupsCommand = defineCommand({
718
+ meta: { name: "groups", description: "Keyword search for LinkedIn groups. A no-match search returns an empty list, not an error." },
719
+ args: {
720
+ ...GLOBAL_FLAGS,
721
+ query: { type: "positional", description: "Search terms (multi-word supported, e.g. 'gtm engineering')." }
722
+ },
723
+ async run({ args }) {
724
+ const flags = args;
725
+ const cfg = await resolveEffectiveConfig({
726
+ apiKey: flags["api-key"],
727
+ baseUrl: flags["base-url"],
728
+ timeout: flags.timeout,
729
+ account: flags.account,
730
+ profile: flags.profile
731
+ });
732
+ if (!cfg.apiKey) {
733
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
734
+ process.exit(3);
735
+ }
736
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
737
+ const out = buildOutputStreams();
738
+ await runSearchGroups(client, { ...flags, account: flags.account ?? cfg.account }, out);
739
+ }
740
+ });
741
+ var searchServicesCommand = defineCommand({
742
+ meta: {
743
+ name: "services",
744
+ description: "Search Services Marketplace providers with structured filters. At least one of --keywords, --service-category, or --location is required. Resolve --service-category/--location values with 'search service-parameters' first, both take opaque ids, not free text."
745
+ },
746
+ args: {
747
+ ...GLOBAL_FLAGS,
748
+ keywords: { type: "string", description: "Free-text keyword match." },
749
+ "service-category": { type: "string", description: "Opaque service-category ids (comma-separated; resolve via search service-parameters --type service_category)." },
750
+ location: { type: "string", description: "Opaque location ids (comma-separated; resolve via search service-parameters --type location)." },
751
+ connections: { type: "string", description: "Connection degree filter, comma-separated: 1 (1st), 2 (2nd), 3 (3rd+)." },
752
+ language: { type: "string", description: "Profile-language ISO 639-1 codes, comma-separated (e.g. en,de,es,fr)." }
753
+ },
754
+ async run({ args }) {
755
+ const flags = args;
756
+ const cfg = await resolveEffectiveConfig({
757
+ apiKey: flags["api-key"],
758
+ baseUrl: flags["base-url"],
759
+ timeout: flags.timeout,
760
+ account: flags.account,
761
+ profile: flags.profile
762
+ });
763
+ if (!cfg.apiKey) {
764
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
765
+ process.exit(3);
766
+ }
767
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
768
+ const out = buildOutputStreams();
769
+ await runSearchServices(client, { ...flags, account: flags.account ?? cfg.account }, out);
770
+ }
771
+ });
772
+ var searchServiceParametersCommand = defineCommand({
773
+ meta: {
774
+ name: "service-parameters",
775
+ description: "Resolve human-readable service-filter terms into the opaque ids 'search services' accepts."
776
+ },
777
+ args: {
778
+ ...GLOBAL_FLAGS,
779
+ type: {
780
+ type: "string",
781
+ description: "Filter type to resolve: service_category (default) or location."
782
+ },
783
+ keywords: { type: "string", description: "The typed text to resolve (e.g. 'marke').", required: true }
784
+ },
785
+ async run({ args }) {
786
+ const flags = args;
787
+ const cfg = await resolveEffectiveConfig({
788
+ apiKey: flags["api-key"],
789
+ baseUrl: flags["base-url"],
790
+ timeout: flags.timeout,
791
+ account: flags.account,
792
+ profile: flags.profile
793
+ });
794
+ if (!cfg.apiKey) {
795
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
796
+ process.exit(3);
797
+ }
798
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
799
+ const out = buildOutputStreams();
800
+ await runSearchServiceParameters(client, { ...flags, account: flags.account ?? cfg.account }, out);
801
+ }
802
+ });
608
803
  var searchCommand = defineCommand({
609
804
  meta: { name: "search", description: "Search people, companies, posts, and jobs. Also runs a pasted search URL directly." },
610
805
  args: {
@@ -620,13 +815,16 @@ var searchCommand = defineCommand({
620
815
  companies: searchCompaniesCommand,
621
816
  posts: searchPostsCommand,
622
817
  jobs: searchJobsCommand,
623
- parameters: searchParametersCommand
818
+ parameters: searchParametersCommand,
819
+ groups: searchGroupsCommand,
820
+ services: searchServicesCommand,
821
+ "service-parameters": searchServiceParametersCommand
624
822
  },
625
823
  async run({ args }) {
626
824
  const flags = args;
627
825
  if (!flags.url) {
628
826
  process.stderr.write(
629
- "Usage: curviate search <url>\n curviate search people [--keywords <k>]\n curviate search companies [--keywords <k>]\n curviate search posts [--keywords <k>]\n curviate search jobs [--keywords <k>]\n curviate search parameters --type <t> --keywords <k>\n"
827
+ "Usage: curviate search <url>\n curviate search people [--keywords <k>]\n curviate search companies [--keywords <k>]\n curviate search posts [--keywords <k>]\n curviate search jobs [--keywords <k>]\n curviate search parameters --type <t> --keywords <k>\n curviate search groups <query>\n curviate search services [--keywords <k>]\n curviate search service-parameters --keywords <k> [--type <t>]\n"
630
828
  );
631
829
  process.exit(2);
632
830
  }
@@ -649,9 +847,12 @@ var searchCommand = defineCommand({
649
847
  export {
650
848
  runSearchCompanies,
651
849
  runSearchFromUrl,
850
+ runSearchGroups,
652
851
  runSearchJobs,
653
852
  runSearchParameters,
654
853
  runSearchPeople,
655
854
  runSearchPosts,
855
+ runSearchServiceParameters,
856
+ runSearchServices,
656
857
  searchCommand
657
858
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/cli",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "private": false,
5
5
  "description": "Official command-line interface for the Curviate API.",
6
6
  "license": "MIT",
@@ -8,10 +8,10 @@
8
8
  "homepage": "https://docs.curviate.com",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/curviate/cli.git"
11
+ "url": "git+https://github.com/curviate/curviate-cli.git"
12
12
  },
13
13
  "bugs": {
14
- "url": "https://github.com/curviate/cli/issues"
14
+ "url": "https://github.com/curviate/curviate-cli/issues"
15
15
  },
16
16
  "publishConfig": {
17
17
  "access": "public"
@@ -41,7 +41,7 @@
41
41
  "clean": "rm -rf dist *.tsbuildinfo"
42
42
  },
43
43
  "dependencies": {
44
- "@curviate/sdk": "^0.18.0",
44
+ "@curviate/sdk": "^0.18.1",
45
45
  "citty": "^0.1.6",
46
46
  "open": "^10.1.0"
47
47
  },