@hasna/domains 0.0.43 → 0.0.45
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/cli/index.js +352 -3
- package/dist/mcp/index.js +20 -0
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -41360,8 +41360,12 @@ import { existsSync as existsSync4 } from "fs";
|
|
|
41360
41360
|
import { homedir as homedir5 } from "os";
|
|
41361
41361
|
import { join as join6 } from "path";
|
|
41362
41362
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
41363
|
+
import { lookup as dnsLookup } from "dns/promises";
|
|
41364
|
+
import { isIP as isIP2 } from "net";
|
|
41363
41365
|
import { randomUUID } from "crypto";
|
|
41364
41366
|
import { spawn } from "child_process";
|
|
41367
|
+
import { request as nodeHttpRequest } from "http";
|
|
41368
|
+
import { request as nodeHttpsRequest } from "https";
|
|
41365
41369
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
41366
41370
|
function getPathValue(input, path) {
|
|
41367
41371
|
return path.split(".").reduce((value, part) => {
|
|
@@ -41758,6 +41762,177 @@ function signPayload(secret, timestamp, body) {
|
|
|
41758
41762
|
const digest = createHmac("sha256", secret).update(buildSignatureBase(timestamp, body)).digest("hex");
|
|
41759
41763
|
return `sha256=${digest}`;
|
|
41760
41764
|
}
|
|
41765
|
+
function isPrivateAddress(address) {
|
|
41766
|
+
const normalized = stripZoneId(address);
|
|
41767
|
+
const version2 = isIP2(normalized);
|
|
41768
|
+
if (version2 === 4) {
|
|
41769
|
+
const integer = ipv4ToInt(normalized);
|
|
41770
|
+
if (integer === undefined)
|
|
41771
|
+
return true;
|
|
41772
|
+
return IPV4_PRIVATE_RANGES.some(([low, high]) => integer >= low && integer <= high);
|
|
41773
|
+
}
|
|
41774
|
+
if (version2 === 6) {
|
|
41775
|
+
const groups = ipv6Groups(normalized);
|
|
41776
|
+
if (!groups)
|
|
41777
|
+
return true;
|
|
41778
|
+
for (const prefix of IPV6_SPECIAL_PREFIXES) {
|
|
41779
|
+
if (!ipv6MatchesPrefix(groups, prefix.groups, prefix.bits))
|
|
41780
|
+
continue;
|
|
41781
|
+
if (prefix.bits === 96 && groups[5] === 65535) {
|
|
41782
|
+
return isPrivateAddress(ipv4IntToString(groups[6] << 16 | groups[7]));
|
|
41783
|
+
}
|
|
41784
|
+
if (prefix.bits === 16 && groups[0] === 8194) {
|
|
41785
|
+
return isPrivateAddress(ipv4IntToString(groups[1] << 16 | groups[2]));
|
|
41786
|
+
}
|
|
41787
|
+
return true;
|
|
41788
|
+
}
|
|
41789
|
+
return false;
|
|
41790
|
+
}
|
|
41791
|
+
return true;
|
|
41792
|
+
}
|
|
41793
|
+
async function resolveWebhookTarget(url, policy = {}) {
|
|
41794
|
+
const hostname = normalizeHostname(url.hostname);
|
|
41795
|
+
const allowlist = (policy.allowPrivateHosts ?? []).map((entry) => normalizeHostname(entry.toLowerCase()));
|
|
41796
|
+
if (allowlist.includes(hostname)) {
|
|
41797
|
+
const version22 = isIP2(hostname);
|
|
41798
|
+
if (version22 === 4 || version22 === 6) {
|
|
41799
|
+
return { hostname, addresses: [hostname] };
|
|
41800
|
+
}
|
|
41801
|
+
const lookup2 = policy.lookup ?? defaultTargetLookup;
|
|
41802
|
+
let resolved2;
|
|
41803
|
+
try {
|
|
41804
|
+
resolved2 = await lookup2(hostname);
|
|
41805
|
+
} catch {
|
|
41806
|
+
throw new Error(`Webhook target ${hostname} could not be resolved`);
|
|
41807
|
+
}
|
|
41808
|
+
if (!Array.isArray(resolved2) || resolved2.length === 0) {
|
|
41809
|
+
throw new Error(`Webhook target ${hostname} resolved to no addresses`);
|
|
41810
|
+
}
|
|
41811
|
+
const addresses = resolved2.map((entry) => normalizeHostname(entry.address));
|
|
41812
|
+
return { hostname, addresses };
|
|
41813
|
+
}
|
|
41814
|
+
const version2 = isIP2(hostname);
|
|
41815
|
+
if (version2 === 4 || version2 === 6) {
|
|
41816
|
+
if (isPrivateAddress(hostname)) {
|
|
41817
|
+
throw new Error(`Webhook target ${hostname} is a private or special-use address`);
|
|
41818
|
+
}
|
|
41819
|
+
return { hostname, addresses: [hostname] };
|
|
41820
|
+
}
|
|
41821
|
+
const lookup = policy.lookup ?? defaultTargetLookup;
|
|
41822
|
+
let resolved;
|
|
41823
|
+
try {
|
|
41824
|
+
resolved = await lookup(hostname);
|
|
41825
|
+
} catch {
|
|
41826
|
+
throw new Error(`Webhook target ${hostname} could not be resolved`);
|
|
41827
|
+
}
|
|
41828
|
+
if (!Array.isArray(resolved) || resolved.length === 0) {
|
|
41829
|
+
throw new Error(`Webhook target ${hostname} resolved to no addresses`);
|
|
41830
|
+
}
|
|
41831
|
+
const allowed = [];
|
|
41832
|
+
for (const entry of resolved) {
|
|
41833
|
+
const address = normalizeHostname(entry.address);
|
|
41834
|
+
if (isPrivateAddress(address)) {
|
|
41835
|
+
if (allowlist.includes(address)) {
|
|
41836
|
+
allowed.push(address);
|
|
41837
|
+
continue;
|
|
41838
|
+
}
|
|
41839
|
+
throw new Error(`Webhook target ${hostname} resolves to private or special-use address ${address}`);
|
|
41840
|
+
}
|
|
41841
|
+
allowed.push(address);
|
|
41842
|
+
}
|
|
41843
|
+
if (allowed.length === 0) {
|
|
41844
|
+
throw new Error(`Webhook target ${hostname} resolved to no public addresses`);
|
|
41845
|
+
}
|
|
41846
|
+
return { hostname, addresses: allowed };
|
|
41847
|
+
}
|
|
41848
|
+
function normalizeMaxRedirects(value) {
|
|
41849
|
+
if (value === undefined)
|
|
41850
|
+
return DEFAULT_MAX_REDIRECTS;
|
|
41851
|
+
if (!Number.isInteger(value) || value < 0)
|
|
41852
|
+
throw new Error("webhookTargetPolicy.maxRedirects must be a non-negative integer");
|
|
41853
|
+
return value;
|
|
41854
|
+
}
|
|
41855
|
+
function normalizeHostname(hostname) {
|
|
41856
|
+
const lower = hostname.toLowerCase();
|
|
41857
|
+
if (lower.startsWith("[") && lower.endsWith("]"))
|
|
41858
|
+
return lower.slice(1, -1);
|
|
41859
|
+
return lower;
|
|
41860
|
+
}
|
|
41861
|
+
function stripZoneId(address) {
|
|
41862
|
+
const percent = address.indexOf("%");
|
|
41863
|
+
return percent === -1 ? address : address.slice(0, percent);
|
|
41864
|
+
}
|
|
41865
|
+
function ipv4ToInt(address) {
|
|
41866
|
+
const parts = address.split(".");
|
|
41867
|
+
if (parts.length !== 4)
|
|
41868
|
+
return;
|
|
41869
|
+
let value = 0;
|
|
41870
|
+
for (const part of parts) {
|
|
41871
|
+
if (!/^\d{1,3}$/.test(part))
|
|
41872
|
+
return;
|
|
41873
|
+
const octet = Number(part);
|
|
41874
|
+
if (octet > 255)
|
|
41875
|
+
return;
|
|
41876
|
+
value = value << 8 | octet;
|
|
41877
|
+
}
|
|
41878
|
+
return value >>> 0;
|
|
41879
|
+
}
|
|
41880
|
+
function ipv4IntToString(integer) {
|
|
41881
|
+
return [
|
|
41882
|
+
integer >>> 24 & 255,
|
|
41883
|
+
integer >>> 16 & 255,
|
|
41884
|
+
integer >>> 8 & 255,
|
|
41885
|
+
integer & 255
|
|
41886
|
+
].join(".");
|
|
41887
|
+
}
|
|
41888
|
+
function ipv6Groups(address) {
|
|
41889
|
+
const raw = stripZoneId(address);
|
|
41890
|
+
const doubleColon = raw.indexOf("::");
|
|
41891
|
+
const headText = doubleColon === -1 ? raw : raw.slice(0, doubleColon);
|
|
41892
|
+
const tailText = doubleColon === -1 ? "" : raw.slice(doubleColon + 2);
|
|
41893
|
+
const parseGroups = (text) => {
|
|
41894
|
+
if (text === "")
|
|
41895
|
+
return [];
|
|
41896
|
+
const out = [];
|
|
41897
|
+
for (const part of text.split(":")) {
|
|
41898
|
+
if (part.includes(".")) {
|
|
41899
|
+
const v4 = ipv4ToInt(part);
|
|
41900
|
+
if (v4 === undefined)
|
|
41901
|
+
return;
|
|
41902
|
+
out.push(v4 >>> 16 & 65535, v4 & 65535);
|
|
41903
|
+
} else {
|
|
41904
|
+
if (!/^[0-9a-fA-F]{1,4}$/.test(part))
|
|
41905
|
+
return;
|
|
41906
|
+
out.push(parseInt(part, 16));
|
|
41907
|
+
}
|
|
41908
|
+
}
|
|
41909
|
+
return out;
|
|
41910
|
+
};
|
|
41911
|
+
const head = parseGroups(headText);
|
|
41912
|
+
if (!head)
|
|
41913
|
+
return;
|
|
41914
|
+
const tail = parseGroups(tailText);
|
|
41915
|
+
if (!tail)
|
|
41916
|
+
return;
|
|
41917
|
+
const total = head.length + tail.length;
|
|
41918
|
+
if (doubleColon === -1) {
|
|
41919
|
+
return total === 8 ? head : undefined;
|
|
41920
|
+
}
|
|
41921
|
+
if (total >= 8)
|
|
41922
|
+
return;
|
|
41923
|
+
return [...head, ...new Array(8 - total).fill(0), ...tail];
|
|
41924
|
+
}
|
|
41925
|
+
function ipv6MatchesPrefix(groups, prefixGroups, prefixBits) {
|
|
41926
|
+
let remaining = prefixBits;
|
|
41927
|
+
for (let index = 0;index < prefixGroups.length && remaining > 0; index += 1) {
|
|
41928
|
+
const take = Math.min(16, remaining);
|
|
41929
|
+
const mask = 65535 << 16 - take & 65535;
|
|
41930
|
+
if ((groups[index] & mask) !== (prefixGroups[index] & mask))
|
|
41931
|
+
return false;
|
|
41932
|
+
remaining -= take;
|
|
41933
|
+
}
|
|
41934
|
+
return true;
|
|
41935
|
+
}
|
|
41761
41936
|
function now() {
|
|
41762
41937
|
return new Date().toISOString();
|
|
41763
41938
|
}
|
|
@@ -41788,9 +41963,18 @@ function buildWebhookRequest(event, channel, options = {}) {
|
|
|
41788
41963
|
}
|
|
41789
41964
|
return { body, headers };
|
|
41790
41965
|
}
|
|
41966
|
+
function normalizeWebhookUrl(raw) {
|
|
41967
|
+
const url = new URL(raw);
|
|
41968
|
+
if (url.username !== "" || url.password !== "") {
|
|
41969
|
+
url.username = "";
|
|
41970
|
+
url.password = "";
|
|
41971
|
+
}
|
|
41972
|
+
return url.toString();
|
|
41973
|
+
}
|
|
41791
41974
|
async function dispatchWebhook(event, channel, options = {}) {
|
|
41792
41975
|
if (!channel.webhook)
|
|
41793
41976
|
throw new Error(`Channel ${channel.id} has no webhook config`);
|
|
41977
|
+
const webhookUrl = normalizeWebhookUrl(channel.webhook.url);
|
|
41794
41978
|
const startedAt = now();
|
|
41795
41979
|
let secret = channel.webhook.secret;
|
|
41796
41980
|
if (channel.webhook.secretRef) {
|
|
@@ -41807,10 +41991,14 @@ async function dispatchWebhook(event, channel, options = {}) {
|
|
|
41807
41991
|
}
|
|
41808
41992
|
const timestamp = (options.now?.() ?? new Date).toISOString();
|
|
41809
41993
|
const { body, headers } = buildWebhookRequest(event, channel, { secret, timestamp });
|
|
41994
|
+
const validateTargets = options.webhookTargetPolicy !== undefined || options.fetchImpl === undefined;
|
|
41995
|
+
if (validateTargets) {
|
|
41996
|
+
return dispatchValidatedWebhook(event, channel, { body, headers, startedAt, options });
|
|
41997
|
+
}
|
|
41810
41998
|
const controller = new AbortController;
|
|
41811
41999
|
const timeout = setTimeout(() => controller.abort(), channel.webhook.timeoutMs ?? 15000);
|
|
41812
42000
|
try {
|
|
41813
|
-
const response = await (options.fetchImpl ?? fetch)(
|
|
42001
|
+
const response = await (options.fetchImpl ?? fetch)(webhookUrl, {
|
|
41814
42002
|
method: "POST",
|
|
41815
42003
|
headers,
|
|
41816
42004
|
body,
|
|
@@ -41838,6 +42026,130 @@ async function dispatchWebhook(event, channel, options = {}) {
|
|
|
41838
42026
|
clearTimeout(timeout);
|
|
41839
42027
|
}
|
|
41840
42028
|
}
|
|
42029
|
+
function isRedirectStatus(status) {
|
|
42030
|
+
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
42031
|
+
}
|
|
42032
|
+
function redirectKeepsBody(status) {
|
|
42033
|
+
return status === 307 || status === 308;
|
|
42034
|
+
}
|
|
42035
|
+
async function pinnedNativeRequest(target, addresses, method, headers, body, signal, tls2) {
|
|
42036
|
+
const isHttps = target.protocol === "https:";
|
|
42037
|
+
if (!isHttps && target.protocol !== "http:") {
|
|
42038
|
+
throw new Error(`Webhook target uses unsupported protocol ${target.protocol}`);
|
|
42039
|
+
}
|
|
42040
|
+
const defaultPort = isHttps ? 443 : 80;
|
|
42041
|
+
const port = target.port ? Number(target.port) : defaultPort;
|
|
42042
|
+
const requestOptions = {
|
|
42043
|
+
hostname: target.hostname,
|
|
42044
|
+
port,
|
|
42045
|
+
path: `${target.pathname}${target.search}`,
|
|
42046
|
+
method,
|
|
42047
|
+
headers,
|
|
42048
|
+
...tls2?.ca ? { ca: tls2.ca } : {},
|
|
42049
|
+
lookup: (hostname, _options, callback) => {
|
|
42050
|
+
const entries = addresses.map((address) => ({
|
|
42051
|
+
address,
|
|
42052
|
+
family: address.includes(":") ? 6 : 4
|
|
42053
|
+
}));
|
|
42054
|
+
callback(null, entries);
|
|
42055
|
+
}
|
|
42056
|
+
};
|
|
42057
|
+
return new Promise((resolve3, reject) => {
|
|
42058
|
+
const request = isHttps ? nodeHttpsRequest(requestOptions, onResponse) : nodeHttpRequest(requestOptions, onResponse);
|
|
42059
|
+
const onAbort = () => {
|
|
42060
|
+
const error = new Error("The operation was aborted.");
|
|
42061
|
+
error.name = "AbortError";
|
|
42062
|
+
request.destroy(error);
|
|
42063
|
+
};
|
|
42064
|
+
if (signal.aborted)
|
|
42065
|
+
onAbort();
|
|
42066
|
+
else
|
|
42067
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
42068
|
+
request.on("error", reject);
|
|
42069
|
+
if (body !== undefined)
|
|
42070
|
+
request.write(body);
|
|
42071
|
+
request.end();
|
|
42072
|
+
function onResponse(response) {
|
|
42073
|
+
const chunks = [];
|
|
42074
|
+
response.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
42075
|
+
response.on("error", reject);
|
|
42076
|
+
response.on("end", () => {
|
|
42077
|
+
const headersRecord = {};
|
|
42078
|
+
for (const [name, value] of Object.entries(response.headers)) {
|
|
42079
|
+
if (typeof value === "string")
|
|
42080
|
+
headersRecord[name] = value;
|
|
42081
|
+
else if (Array.isArray(value))
|
|
42082
|
+
headersRecord[name] = value.join(", ");
|
|
42083
|
+
}
|
|
42084
|
+
resolve3(new Response(Buffer.concat(chunks), { status: response.statusCode ?? 200, headers: headersRecord }));
|
|
42085
|
+
});
|
|
42086
|
+
}
|
|
42087
|
+
});
|
|
42088
|
+
}
|
|
42089
|
+
async function dispatchValidatedWebhook(event, channel, input) {
|
|
42090
|
+
const { body, headers, startedAt, options } = input;
|
|
42091
|
+
const webhook = channel.webhook;
|
|
42092
|
+
if (!webhook)
|
|
42093
|
+
throw new Error(`Channel ${channel.id} has no webhook config`);
|
|
42094
|
+
const policy = options.webhookTargetPolicy ?? {};
|
|
42095
|
+
const maxRedirects = normalizeMaxRedirects(policy.maxRedirects);
|
|
42096
|
+
const controller = new AbortController;
|
|
42097
|
+
const timeout = setTimeout(() => controller.abort(), webhook.timeoutMs ?? 15000);
|
|
42098
|
+
try {
|
|
42099
|
+
let target = new URL(normalizeWebhookUrl(webhook.url));
|
|
42100
|
+
let requestHeaders = headers;
|
|
42101
|
+
let method = "POST";
|
|
42102
|
+
let requestBody = body;
|
|
42103
|
+
let redirectsFollowed = 0;
|
|
42104
|
+
for (;; ) {
|
|
42105
|
+
const resolved = await resolveWebhookTarget(target, policy).catch((error) => {
|
|
42106
|
+
throw new Error(`Webhook target rejected by SSRF guard: ${error.message}`);
|
|
42107
|
+
});
|
|
42108
|
+
const response = options.fetchImpl ? await options.fetchImpl(target, {
|
|
42109
|
+
method,
|
|
42110
|
+
headers: requestHeaders,
|
|
42111
|
+
body: requestBody,
|
|
42112
|
+
signal: controller.signal,
|
|
42113
|
+
redirect: "manual"
|
|
42114
|
+
}) : await pinnedNativeRequest(target, resolved.addresses, method, requestHeaders, requestBody, controller.signal, options.tls);
|
|
42115
|
+
const location = response.headers.get("location");
|
|
42116
|
+
if (isRedirectStatus(response.status) && location) {
|
|
42117
|
+
if (redirectsFollowed >= maxRedirects) {
|
|
42118
|
+
return failedAttempt(startedAt, `Webhook target exceeded ${maxRedirects} redirects`);
|
|
42119
|
+
}
|
|
42120
|
+
redirectsFollowed += 1;
|
|
42121
|
+
const next = new URL(location, target);
|
|
42122
|
+
target = next;
|
|
42123
|
+
if (!redirectKeepsBody(response.status)) {
|
|
42124
|
+
method = "GET";
|
|
42125
|
+
requestBody = undefined;
|
|
42126
|
+
requestHeaders = Object.fromEntries(Object.entries(requestHeaders).filter(([name]) => name.toLowerCase() !== "content-type" && name.toLowerCase() !== "content-length"));
|
|
42127
|
+
}
|
|
42128
|
+
continue;
|
|
42129
|
+
}
|
|
42130
|
+
const responseBody = truncate(await response.text());
|
|
42131
|
+
return {
|
|
42132
|
+
attempt: 1,
|
|
42133
|
+
status: response.ok ? "success" : "failed",
|
|
42134
|
+
startedAt,
|
|
42135
|
+
completedAt: now(),
|
|
42136
|
+
responseStatus: response.status,
|
|
42137
|
+
responseBody,
|
|
42138
|
+
error: response.ok ? undefined : `Webhook returned HTTP ${response.status}`
|
|
42139
|
+
};
|
|
42140
|
+
}
|
|
42141
|
+
} catch (error) {
|
|
42142
|
+
return {
|
|
42143
|
+
attempt: 1,
|
|
42144
|
+
status: "failed",
|
|
42145
|
+
startedAt,
|
|
42146
|
+
completedAt: now(),
|
|
42147
|
+
error: error instanceof Error ? error.message : String(error)
|
|
42148
|
+
};
|
|
42149
|
+
} finally {
|
|
42150
|
+
clearTimeout(timeout);
|
|
42151
|
+
}
|
|
42152
|
+
}
|
|
41841
42153
|
function failedAttempt(startedAt, error) {
|
|
41842
42154
|
return {
|
|
41843
42155
|
attempt: 1,
|
|
@@ -42033,7 +42345,9 @@ class EventsClient {
|
|
|
42033
42345
|
this.transportOptions = {
|
|
42034
42346
|
fetchImpl: options.fetchImpl,
|
|
42035
42347
|
secretResolver: options.secretResolver,
|
|
42036
|
-
now: options.now
|
|
42348
|
+
now: options.now,
|
|
42349
|
+
tls: options.tls,
|
|
42350
|
+
webhookTargetPolicy: options.webhookTargetPolicy
|
|
42037
42351
|
};
|
|
42038
42352
|
this.catalog = options.catalog ?? defaultEventTypeCatalog;
|
|
42039
42353
|
this.validateCatalogTypes = options.validateCatalogTypes ?? false;
|
|
@@ -42513,9 +42827,44 @@ function replaySummary(events, deliveries, nextCursor) {
|
|
|
42513
42827
|
const suffix = nextCursor ? `, next cursor: ${nextCursor}` : "";
|
|
42514
42828
|
return `Replayed ${events} event(s), ${deliveries} delivery result(s)${suffix}`;
|
|
42515
42829
|
}
|
|
42516
|
-
var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR", HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME", LOCAL_JSON_EVENT_CURSOR_PREFIX = "local-json-v1:", DEFAULT_EVENT_PAGE_LIMIT = 100, MAX_EVENT_PAGE_LIMIT = 1000, DEFAULT_SIGNATURE_TOLERANCE_MS,
|
|
42830
|
+
var HASNA_EVENTS_DIR_ENV = "HASNA_EVENTS_DIR", HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME", LOCAL_JSON_EVENT_CURSOR_PREFIX = "local-json-v1:", DEFAULT_EVENT_PAGE_LIMIT = 100, MAX_EVENT_PAGE_LIMIT = 1000, DEFAULT_SIGNATURE_TOLERANCE_MS, DEFAULT_MAX_REDIRECTS = 5, IPV4_PRIVATE_RANGES, IPV6_SPECIAL_PREFIXES, defaultTargetLookup = async (hostname) => {
|
|
42831
|
+
return dnsLookup(hostname, { all: true, verbatim: false });
|
|
42832
|
+
}, EventValidationError, defaultEventTypeCatalog, APP_EVENT_V1_MAX_DATA_BYTES, DEFAULT_EVENT_LIST_LIMIT = 100;
|
|
42517
42833
|
var init_commander = __esm(() => {
|
|
42518
42834
|
DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
|
|
42835
|
+
IPV4_PRIVATE_RANGES = [
|
|
42836
|
+
[0, 16777215],
|
|
42837
|
+
[167772160, 184549375],
|
|
42838
|
+
[1681915904, 1686110207],
|
|
42839
|
+
[2130706432, 2147483647],
|
|
42840
|
+
[2851995648, 2852061183],
|
|
42841
|
+
[2886729728, 2887778303],
|
|
42842
|
+
[3221225472, 3221225727],
|
|
42843
|
+
[3221225984, 3221226239],
|
|
42844
|
+
[3227017984, 3227018239],
|
|
42845
|
+
[3232235520, 3232301055],
|
|
42846
|
+
[3323068416, 3323199487],
|
|
42847
|
+
[3325256704, 3325256959],
|
|
42848
|
+
[3405803776, 3405804031],
|
|
42849
|
+
[3758096384, 4294967295]
|
|
42850
|
+
];
|
|
42851
|
+
IPV6_SPECIAL_PREFIXES = [
|
|
42852
|
+
{ groups: [0, 0, 0, 0, 0, 0, 0, 0], bits: 128 },
|
|
42853
|
+
{ groups: [0, 0, 0, 0, 0, 0, 0, 1], bits: 128 },
|
|
42854
|
+
{ groups: [0, 0, 0, 0, 0, 65535, 0, 0], bits: 96 },
|
|
42855
|
+
{ groups: [100, 65435, 0, 0, 0, 0, 0, 0], bits: 96 },
|
|
42856
|
+
{ groups: [256, 0, 0, 0, 0, 0, 0, 0], bits: 64 },
|
|
42857
|
+
{ groups: [8193, 0, 0, 0, 0, 0, 0, 0], bits: 32 },
|
|
42858
|
+
{ groups: [8193, 2, 0, 0, 0, 0, 0, 0], bits: 48 },
|
|
42859
|
+
{ groups: [8193, 16, 0, 0, 0, 0, 0, 0], bits: 28 },
|
|
42860
|
+
{ groups: [8193, 3512, 0, 0, 0, 0, 0, 0], bits: 32 },
|
|
42861
|
+
{ groups: [8194, 0, 0, 0, 0, 0, 0, 0], bits: 16 },
|
|
42862
|
+
{ groups: [16383, 0, 0, 0, 0, 0, 0, 0], bits: 20 },
|
|
42863
|
+
{ groups: [64512, 0, 0, 0, 0, 0, 0, 0], bits: 7 },
|
|
42864
|
+
{ groups: [65152, 0, 0, 0, 0, 0, 0, 0], bits: 10 },
|
|
42865
|
+
{ groups: [65216, 0, 0, 0, 0, 0, 0, 0], bits: 10 },
|
|
42866
|
+
{ groups: [65280, 0, 0, 0, 0, 0, 0, 0], bits: 8 }
|
|
42867
|
+
];
|
|
42519
42868
|
EventValidationError = class EventValidationError extends Error {
|
|
42520
42869
|
eventType;
|
|
42521
42870
|
issues;
|
package/dist/mcp/index.js
CHANGED
|
@@ -41082,8 +41082,28 @@ function buildServer() {
|
|
|
41082
41082
|
});
|
|
41083
41083
|
return server;
|
|
41084
41084
|
}
|
|
41085
|
+
function printHelp() {
|
|
41086
|
+
console.log(`Usage: domains-mcp [options]
|
|
41087
|
+
|
|
41088
|
+
MCP server for @hasna/domains (Streamable HTTP by default, stdio with --stdio)
|
|
41089
|
+
|
|
41090
|
+
Options:
|
|
41091
|
+
--stdio Serve MCP over stdio (env: MCP_STDIO=1)
|
|
41092
|
+
--http Serve MCP over Streamable HTTP (127.0.0.1; env: MCP_HTTP=1)
|
|
41093
|
+
--port <number> HTTP port (default: 8859, env: MCP_HTTP_PORT)
|
|
41094
|
+
-V, --version output the version number
|
|
41095
|
+
-h, --help display help for command`);
|
|
41096
|
+
}
|
|
41085
41097
|
async function main() {
|
|
41086
41098
|
const argv = process.argv.slice(2);
|
|
41099
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
41100
|
+
printHelp();
|
|
41101
|
+
process.exit(0);
|
|
41102
|
+
}
|
|
41103
|
+
if (argv.includes("--version") || argv.includes("-V")) {
|
|
41104
|
+
console.log(getPackageVersion());
|
|
41105
|
+
process.exit(0);
|
|
41106
|
+
}
|
|
41087
41107
|
const { isStdioMode: isStdioMode3 } = await Promise.resolve().then(() => (init_http(), exports_http));
|
|
41088
41108
|
if (isStdioMode3(argv)) {
|
|
41089
41109
|
const transport = new StdioServerTransport2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/domains",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"description": "Domain portfolio, registrar, marketplace, and DNS management for AI agents — CLI + MCP + HTTP API + SDK, local SQLite or cloud Postgres",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"@aws-sdk/client-route-53": "^3.1067.0",
|
|
98
98
|
"@aws-sdk/client-route-53-domains": "^3.1067.0",
|
|
99
99
|
"@aws-sdk/credential-provider-ini": "3.972.53",
|
|
100
|
-
"@hasna/contracts": "0.
|
|
100
|
+
"@hasna/contracts": "0.14.0",
|
|
101
101
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
102
102
|
"chalk": "^5.4.1",
|
|
103
103
|
"commander": "^13.1.0",
|