@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 +4 -7
- package/dist/toolkit.js +125 -113
- package/package.json +1 -1
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
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const
|
|
643
|
-
|
|
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
|
-
|
|
695
|
+
res.on("data", (c) => {
|
|
647
696
|
bytes += c.length;
|
|
648
|
-
if (bytes <= MAX_RESP
|
|
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
|
|
658
|
-
const
|
|
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
|
|
668
|
-
|
|
669
|
-
|
|
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:
|
|
713
|
+
resolve({ status: res.statusCode ?? 0, headers: hdrs, body, bytes: bodyBytes });
|
|
673
714
|
};
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
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
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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
|
-
|
|
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
|