heyreach-cli 0.1.1 → 0.1.3

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/dist/mcp.js CHANGED
@@ -39,7 +39,9 @@ var init_config = __esm({
39
39
  // src/core/errors.ts
40
40
  function classifyHttpError(status, body) {
41
41
  const parsed = safeParse(body);
42
- const message = parsed?.message ?? parsed?.error ?? body;
42
+ const rawVal = parsed?.message || parsed?.error || body || `HTTP ${status} error`;
43
+ const raw = typeof rawVal === "string" ? rawVal : JSON.stringify(rawVal);
44
+ const message = extractMessage(raw);
43
45
  if (status === 401 || status === 403) return new AuthError(message);
44
46
  if (status === 404) return new NotFoundError(message);
45
47
  if (status === 422) return new ValidationError(message);
@@ -47,6 +49,18 @@ function classifyHttpError(status, body) {
47
49
  if (status >= 500) return new ServerError(message);
48
50
  return new HeyReachError(message, "HTTP_ERROR", status);
49
51
  }
52
+ function extractMessage(raw) {
53
+ const nested = safeParse(raw);
54
+ if (nested?.errors && typeof nested.errors === "object") {
55
+ const parts = [];
56
+ for (const [field, msgs] of Object.entries(nested.errors)) {
57
+ const msgList = Array.isArray(msgs) ? msgs.join("; ") : String(msgs);
58
+ parts.push(`${field}: ${msgList}`);
59
+ }
60
+ if (parts.length > 0) return parts.join(". ");
61
+ }
62
+ return raw;
63
+ }
50
64
  function safeParse(text) {
51
65
  try {
52
66
  return JSON.parse(text);
@@ -220,7 +234,9 @@ function createClient(auth) {
220
234
  return { request, paginate };
221
235
  }
222
236
  function buildUrl(baseUrl, path2, query) {
223
- const url = new URL(path2, baseUrl.endsWith("/") ? baseUrl : baseUrl + "/");
237
+ const base = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
238
+ const cleanPath = path2.startsWith("/") ? path2.slice(1) : path2;
239
+ const url = new URL(cleanPath, base);
224
240
  if (query) {
225
241
  for (const [key, value] of Object.entries(query)) {
226
242
  if (value !== void 0 && value !== null) {
@@ -556,6 +572,7 @@ var init_get_for_lead = __esm({
556
572
  "use strict";
557
573
  init_esm_shims();
558
574
  init_handler();
575
+ init_errors();
559
576
  campaignsGetForLeadCommand = {
560
577
  name: "campaigns_get_for_lead",
561
578
  group: "campaigns",
@@ -583,7 +600,12 @@ var init_get_for_lead = __esm({
583
600
  },
584
601
  endpoint: { method: "POST", path: "/campaign/GetCampaignsForLead" },
585
602
  fieldMappings: { offset: "body", limit: "body", email: "body", linkedinId: "body", profileUrl: "body" },
586
- handler: (input, client) => executeCommand(campaignsGetForLeadCommand, input, client)
603
+ handler: (input, client) => {
604
+ if (!input.email && !input.linkedinId && !input.profileUrl) {
605
+ throw new ValidationError("At least one of --email, --linkedin-id, or --profile-url is required.");
606
+ }
607
+ return executeCommand(campaignsGetForLeadCommand, input, client);
608
+ }
587
609
  };
588
610
  }
589
611
  });
@@ -1182,6 +1204,7 @@ var init_get_for_lead2 = __esm({
1182
1204
  "use strict";
1183
1205
  init_esm_shims();
1184
1206
  init_handler();
1207
+ init_errors();
1185
1208
  listsGetForLeadCommand = {
1186
1209
  name: "lists_get_for_lead",
1187
1210
  group: "lists",
@@ -1206,7 +1229,12 @@ var init_get_for_lead2 = __esm({
1206
1229
  },
1207
1230
  endpoint: { method: "POST", path: "/list/GetListsForLead" },
1208
1231
  fieldMappings: { offset: "body", limit: "body", email: "body", linkedinId: "body", profileUrl: "body" },
1209
- handler: (input, client) => executeCommand(listsGetForLeadCommand, input, client)
1232
+ handler: (input, client) => {
1233
+ if (!input.email && !input.linkedinId && !input.profileUrl) {
1234
+ throw new ValidationError("At least one of --email, --linkedin-id, or --profile-url is required.");
1235
+ }
1236
+ return executeCommand(listsGetForLeadCommand, input, client);
1237
+ }
1210
1238
  };
1211
1239
  }
1212
1240
  });
@@ -1257,8 +1285,8 @@ var init_overview = __esm({
1257
1285
  'heyreach stats overview --start-date 2025-01-01 --end-date 2025-01-31 --campaign-ids "1,2,3"'
1258
1286
  ],
1259
1287
  inputSchema: z24.object({
1260
- startDate: z24.string().describe("Start date (ISO 8601)"),
1261
- endDate: z24.string().describe("End date (ISO 8601)"),
1288
+ startDate: z24.string().optional().describe("Start date (ISO 8601). Defaults to 30 days ago."),
1289
+ endDate: z24.string().optional().describe("End date (ISO 8601). Defaults to today."),
1262
1290
  accountIds: z24.string().optional().describe("Comma-separated LinkedIn account IDs (empty = all)"),
1263
1291
  campaignIds: z24.string().optional().describe("Comma-separated campaign IDs (empty = all)")
1264
1292
  }),
@@ -1273,12 +1301,14 @@ var init_overview = __esm({
1273
1301
  endpoint: { method: "POST", path: "/stats/GetOverallStats" },
1274
1302
  fieldMappings: {},
1275
1303
  handler: async (input, client) => {
1304
+ const now = /* @__PURE__ */ new Date();
1305
+ const thirtyDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3);
1276
1306
  const body = {
1277
- startDate: input.startDate,
1278
- endDate: input.endDate
1307
+ startDate: input.startDate ?? thirtyDaysAgo.toISOString(),
1308
+ endDate: input.endDate ?? now.toISOString(),
1309
+ accountIds: input.accountIds ? input.accountIds.split(",").map((s) => Number(s.trim())) : [],
1310
+ campaignIds: input.campaignIds ? input.campaignIds.split(",").map((s) => Number(s.trim())) : []
1279
1311
  };
1280
- if (input.accountIds) body.accountIds = input.accountIds.split(",").map((s) => Number(s.trim()));
1281
- if (input.campaignIds) body.campaignIds = input.campaignIds.split(",").map((s) => Number(s.trim()));
1282
1312
  return client.request({ method: "POST", path: "/stats/GetOverallStats", body });
1283
1313
  }
1284
1314
  };