@dominusnode/mastra-tools 1.3.0 → 1.3.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/dist/toolkit.d.ts CHANGED
@@ -86,8 +86,10 @@ export declare class DominusNodeToolkit {
86
86
  status: number;
87
87
  headers: Record<string, string>;
88
88
  body: string;
89
+ bytes: number;
89
90
  pool: string;
90
91
  country: string;
92
+ error?: string;
91
93
  }>;
92
94
  checkBalance(): Promise<{
93
95
  balanceCents: number;
@@ -161,15 +163,10 @@ export declare class DominusNodeToolkit {
161
163
  status: number;
162
164
  headers: Record<string, string>;
163
165
  body: string;
166
+ bytes: number;
164
167
  pool: string;
165
168
  country: string;
166
- } | {
167
- status: number;
168
- headers: {};
169
- body: string;
170
- pool: any;
171
- country: any;
172
- error: string;
169
+ error?: string;
173
170
  }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_proxied_fetch", unknown> | import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<unknown, {
174
171
  balanceCents: number;
175
172
  balanceUsd: number;
package/dist/toolkit.js CHANGED
@@ -602,50 +602,99 @@ class DominusNodeToolkit {
602
602
  // Tool implementations
603
603
  // -----------------------------------------------------------------------
604
604
  async proxiedFetch(url, method = "GET", country, proxyType = "dc") {
605
- const parsedUrl = validateTargetUrl(url);
606
- await checkDnsRebinding(parsedUrl.hostname);
607
- const validCountry = validateCountry(country);
608
- const ALLOWED_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
609
- const methodUpper = method.toUpperCase();
610
- if (!ALLOWED_METHODS.has(methodUpper)) {
611
- throw new Error(`HTTP method "${methodUpper}" is not allowed. Only GET, HEAD, and OPTIONS are permitted.`);
612
- }
613
- const apiKey = this.getApiKey();
614
- const parts = [];
615
- if (proxyType && proxyType !== "auto")
616
- parts.push(proxyType);
617
- if (validCountry)
618
- parts.push(`country-${validCountry.toUpperCase()}`);
619
- const username = parts.length > 0 ? parts.join("-") : "auto";
620
- const proxyAuth = "Basic " + Buffer.from(`${username}:${apiKey}`).toString("base64");
621
- const parsed = new URL(url);
622
- const MAX_RESP = 1_048_576; // 1MB
623
- const result = await new Promise((resolve, reject) => {
624
- const timer = setTimeout(() => reject(new Error("Proxy request timed out")), REQUEST_TIMEOUT_MS);
625
- if (parsed.protocol === "https:") {
626
- const connectHost = parsed.hostname.includes(":") ? `[${parsed.hostname}]` : parsed.hostname;
627
- const connectReq = http.request({
628
- hostname: this.proxyHost,
629
- port: this.proxyPort,
630
- method: "CONNECT",
631
- path: `${connectHost}:${parsed.port || 443}`,
632
- headers: { "Proxy-Authorization": proxyAuth, Host: `${connectHost}:${parsed.port || 443}` },
633
- });
634
- connectReq.on("connect", (_res, sock) => {
635
- if (_res.statusCode !== 200) {
636
- clearTimeout(timer);
637
- sock.destroy();
638
- reject(new Error(`CONNECT failed: ${_res.statusCode}`));
639
- return;
640
- }
641
- const tlsSock = tls.connect({ host: parsed.hostname, socket: sock, servername: parsed.hostname, minVersion: "TLSv1.2" }, () => {
642
- const reqLine = `${methodUpper} ${parsed.pathname + parsed.search} HTTP/1.1\r\nHost: ${parsed.host}\r\nUser-Agent: dominusnode-mastra/1.0.0\r\nConnection: close\r\n\r\n`;
643
- tlsSock.write(reqLine);
605
+ try {
606
+ const parsedUrl = validateTargetUrl(url);
607
+ await checkDnsRebinding(parsedUrl.hostname);
608
+ const validCountry = validateCountry(country);
609
+ const ALLOWED_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
610
+ const methodUpper = method.toUpperCase();
611
+ if (!ALLOWED_METHODS.has(methodUpper)) {
612
+ return { status: 0, headers: {}, body: "", bytes: 0, pool: proxyType, country: country ?? "auto", error: `HTTP method "${methodUpper}" is not allowed. Only GET, HEAD, and OPTIONS are permitted.` };
613
+ }
614
+ const apiKey = this.getApiKey();
615
+ const parts = [];
616
+ if (proxyType && proxyType !== "auto")
617
+ parts.push(proxyType);
618
+ if (validCountry)
619
+ parts.push(`country-${validCountry.toUpperCase()}`);
620
+ const username = parts.length > 0 ? parts.join("-") : "auto";
621
+ const proxyAuth = "Basic " + Buffer.from(`${username}:${apiKey}`).toString("base64");
622
+ const parsed = new URL(url);
623
+ const MAX_RESP = 1_048_576; // 1MB
624
+ const result = await new Promise((resolve, reject) => {
625
+ const timer = setTimeout(() => reject(new Error("Proxy request timed out")), REQUEST_TIMEOUT_MS);
626
+ if (parsed.protocol === "https:") {
627
+ const connectHost = parsed.hostname.includes(":") ? `[${parsed.hostname}]` : parsed.hostname;
628
+ const connectReq = http.request({
629
+ hostname: this.proxyHost,
630
+ port: this.proxyPort,
631
+ method: "CONNECT",
632
+ path: `${connectHost}:${parsed.port || 443}`,
633
+ headers: { "Proxy-Authorization": proxyAuth, Host: `${connectHost}:${parsed.port || 443}` },
634
+ });
635
+ connectReq.on("connect", (_res, sock) => {
636
+ if (_res.statusCode !== 200) {
637
+ clearTimeout(timer);
638
+ sock.destroy();
639
+ reject(new Error(`CONNECT failed: ${_res.statusCode}`));
640
+ return;
641
+ }
642
+ const tlsSock = tls.connect({ host: parsed.hostname, socket: sock, servername: parsed.hostname, minVersion: "TLSv1.2" }, () => {
643
+ const reqLine = `${methodUpper} ${parsed.pathname + parsed.search} HTTP/1.1\r\nHost: ${parsed.host}\r\nUser-Agent: dominusnode-mastra/1.0.0\r\nConnection: close\r\n\r\n`;
644
+ tlsSock.write(reqLine);
645
+ const chunks = [];
646
+ let bytes = 0;
647
+ tlsSock.on("data", (c) => {
648
+ bytes += c.length;
649
+ if (bytes <= MAX_RESP + 16384)
650
+ chunks.push(c);
651
+ });
652
+ let done = false;
653
+ const fin = () => {
654
+ if (done)
655
+ return;
656
+ done = true;
657
+ clearTimeout(timer);
658
+ const raw = Buffer.concat(chunks).toString("utf-8");
659
+ const hEnd = raw.indexOf("\r\n\r\n");
660
+ if (hEnd === -1) {
661
+ reject(new Error("Malformed response"));
662
+ return;
663
+ }
664
+ const hdr = raw.substring(0, hEnd);
665
+ const body = raw.substring(hEnd + 4).substring(0, MAX_RESP);
666
+ const bodyBytes = new TextEncoder().encode(body).length;
667
+ const sm = hdr.split("\r\n")[0].match(/^HTTP\/\d\.\d\s+(\d+)/);
668
+ const hdrs = {};
669
+ for (const l of hdr.split("\r\n").slice(1)) {
670
+ const ci = l.indexOf(":");
671
+ if (ci > 0)
672
+ hdrs[l.substring(0, ci).trim().toLowerCase()] = l.substring(ci + 1).trim();
673
+ }
674
+ resolve({ status: sm ? parseInt(sm[1], 10) : 0, headers: hdrs, body, bytes: bodyBytes });
675
+ };
676
+ tlsSock.on("end", fin);
677
+ tlsSock.on("close", fin);
678
+ tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
679
+ });
680
+ tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
681
+ });
682
+ connectReq.on("error", (e) => { clearTimeout(timer); reject(e); });
683
+ connectReq.end();
684
+ }
685
+ else {
686
+ const req = http.request({
687
+ hostname: this.proxyHost,
688
+ port: this.proxyPort,
689
+ method: methodUpper,
690
+ path: url,
691
+ headers: { "Proxy-Authorization": proxyAuth, Host: parsed.host ?? "" },
692
+ }, (res) => {
644
693
  const chunks = [];
645
694
  let bytes = 0;
646
- tlsSock.on("data", (c) => {
695
+ res.on("data", (c) => {
647
696
  bytes += c.length;
648
- if (bytes <= MAX_RESP + 16384)
697
+ if (bytes <= MAX_RESP)
649
698
  chunks.push(c);
650
699
  });
651
700
  let done = false;
@@ -654,76 +703,43 @@ class DominusNodeToolkit {
654
703
  return;
655
704
  done = true;
656
705
  clearTimeout(timer);
657
- const raw = Buffer.concat(chunks).toString("utf-8");
658
- const hEnd = raw.indexOf("\r\n\r\n");
659
- if (hEnd === -1) {
660
- reject(new Error("Malformed response"));
661
- return;
662
- }
663
- const hdr = raw.substring(0, hEnd);
664
- const body = raw.substring(hEnd + 4).substring(0, MAX_RESP);
665
- const sm = hdr.split("\r\n")[0].match(/^HTTP\/\d\.\d\s+(\d+)/);
706
+ const body = Buffer.concat(chunks).toString("utf-8").substring(0, MAX_RESP);
707
+ const bodyBytes = new TextEncoder().encode(body).length;
666
708
  const hdrs = {};
667
- for (const l of hdr.split("\r\n").slice(1)) {
668
- const ci = l.indexOf(":");
669
- if (ci > 0)
670
- hdrs[l.substring(0, ci).trim().toLowerCase()] = l.substring(ci + 1).trim();
709
+ for (const [k, v] of Object.entries(res.headers)) {
710
+ if (v)
711
+ hdrs[k] = Array.isArray(v) ? v.join(", ") : v;
671
712
  }
672
- resolve({ status: sm ? parseInt(sm[1], 10) : 0, headers: hdrs, body });
713
+ resolve({ status: res.statusCode ?? 0, headers: hdrs, body, bytes: bodyBytes });
673
714
  };
674
- tlsSock.on("end", fin);
675
- tlsSock.on("close", fin);
676
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
677
- });
678
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
679
- });
680
- connectReq.on("error", (e) => { clearTimeout(timer); reject(e); });
681
- connectReq.end();
682
- }
683
- else {
684
- const req = http.request({
685
- hostname: this.proxyHost,
686
- port: this.proxyPort,
687
- method: methodUpper,
688
- path: url,
689
- headers: { "Proxy-Authorization": proxyAuth, Host: parsed.host ?? "" },
690
- }, (res) => {
691
- const chunks = [];
692
- let bytes = 0;
693
- res.on("data", (c) => {
694
- bytes += c.length;
695
- if (bytes <= MAX_RESP)
696
- chunks.push(c);
715
+ res.on("end", fin);
716
+ res.on("close", fin);
717
+ res.on("error", (e) => { clearTimeout(timer); reject(e); });
697
718
  });
698
- let done = false;
699
- const fin = () => {
700
- if (done)
701
- return;
702
- done = true;
703
- clearTimeout(timer);
704
- const body = Buffer.concat(chunks).toString("utf-8").substring(0, MAX_RESP);
705
- const hdrs = {};
706
- for (const [k, v] of Object.entries(res.headers)) {
707
- if (v)
708
- hdrs[k] = Array.isArray(v) ? v.join(", ") : v;
709
- }
710
- resolve({ status: res.statusCode ?? 0, headers: hdrs, body });
711
- };
712
- res.on("end", fin);
713
- res.on("close", fin);
714
- res.on("error", (e) => { clearTimeout(timer); reject(e); });
715
- });
716
- req.on("error", (e) => { clearTimeout(timer); reject(e); });
717
- req.end();
718
- }
719
- });
720
- return {
721
- status: result.status,
722
- headers: result.headers,
723
- body: truncate(scrubCredentials(result.body)),
724
- pool: proxyType,
725
- country: validCountry ?? "auto",
726
- };
719
+ req.on("error", (e) => { clearTimeout(timer); reject(e); });
720
+ req.end();
721
+ }
722
+ });
723
+ return {
724
+ status: result.status,
725
+ headers: result.headers,
726
+ body: truncate(scrubCredentials(result.body)),
727
+ bytes: result.bytes,
728
+ pool: proxyType,
729
+ country: validCountry ?? "auto",
730
+ };
731
+ }
732
+ catch (err) {
733
+ return {
734
+ status: 0,
735
+ headers: {},
736
+ body: "",
737
+ bytes: 0,
738
+ pool: proxyType,
739
+ country: country ?? "auto",
740
+ error: safeError(err),
741
+ };
742
+ }
727
743
  }
728
744
  async checkBalance() {
729
745
  const data = await this.apiGet("/api/wallet");
@@ -1124,17 +1140,13 @@ class DominusNodeToolkit {
1124
1140
  status: zod_1.z.number(),
1125
1141
  headers: zod_1.z.record(zod_1.z.string()),
1126
1142
  body: zod_1.z.string(),
1143
+ bytes: zod_1.z.number(),
1127
1144
  pool: zod_1.z.string(),
1128
1145
  country: zod_1.z.string(),
1129
1146
  error: zod_1.z.string().optional(),
1130
1147
  }),
1131
1148
  execute: async ({ context }) => {
1132
- try {
1133
- return await this.proxiedFetch(context.url, context.method, context.country, context.proxyType);
1134
- }
1135
- catch (err) {
1136
- return { status: 0, headers: {}, body: "", pool: context.proxyType ?? "dc", country: context.country ?? "auto", error: safeError(err) };
1137
- }
1149
+ return await this.proxiedFetch(context.url, context.method, context.country, context.proxyType);
1138
1150
  },
1139
1151
  }),
1140
1152
  // 2. check_balance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dominusnode/mastra-tools",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Dominus Node rotating proxy tools for Mastra AI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",