@hasna/domains 0.0.46 → 0.0.47
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/README.md +1 -1
- package/dist/cli/index.js +413 -158
- package/dist/db/database.d.ts +5 -3
- package/dist/db/database.d.ts.map +1 -1
- package/dist/index.js +340 -104
- package/dist/lib/app-home.d.ts +60 -0
- package/dist/lib/app-home.d.ts.map +1 -0
- package/dist/lib/config.d.ts +4 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/mcp/index.js +360 -124
- package/dist/sdk/index.js +93 -15
- package/dist/server/migrations.d.ts +35 -0
- package/dist/server/migrations.d.ts.map +1 -1
- package/package.json +5 -3
- package/postinstall.js +42 -0
package/dist/mcp/index.js
CHANGED
|
@@ -5228,7 +5228,7 @@ var require_client = __commonJS((exports) => {
|
|
|
5228
5228
|
};
|
|
5229
5229
|
};
|
|
5230
5230
|
var sleep = (seconds) => {
|
|
5231
|
-
return new Promise((
|
|
5231
|
+
return new Promise((resolve4) => setTimeout(resolve4, seconds * 1000));
|
|
5232
5232
|
};
|
|
5233
5233
|
var waiterServiceDefaults = {
|
|
5234
5234
|
minDelay: 2,
|
|
@@ -5357,8 +5357,8 @@ var require_client = __commonJS((exports) => {
|
|
|
5357
5357
|
};
|
|
5358
5358
|
var abortTimeout = (abortSignal) => {
|
|
5359
5359
|
let onAbort;
|
|
5360
|
-
const promise = new Promise((
|
|
5361
|
-
onAbort = () =>
|
|
5360
|
+
const promise = new Promise((resolve4) => {
|
|
5361
|
+
onAbort = () => resolve4({ state: WaiterState.ABORTED });
|
|
5362
5362
|
if (typeof abortSignal.addEventListener === "function") {
|
|
5363
5363
|
abortSignal.addEventListener("abort", onAbort);
|
|
5364
5364
|
} else {
|
|
@@ -6011,8 +6011,8 @@ var require_client = __commonJS((exports) => {
|
|
|
6011
6011
|
|
|
6012
6012
|
// ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/config/index.js
|
|
6013
6013
|
var require_config = __commonJS((exports) => {
|
|
6014
|
-
var { homedir:
|
|
6015
|
-
var { sep, join:
|
|
6014
|
+
var { homedir: homedir4 } = __require("os");
|
|
6015
|
+
var { sep, join: join5 } = __require("path");
|
|
6016
6016
|
var { createHash: createHash2 } = __require("crypto");
|
|
6017
6017
|
var { readFile: readFile$1 } = __require("fs/promises");
|
|
6018
6018
|
var { IniSectionType } = require_dist_cjs();
|
|
@@ -6161,7 +6161,7 @@ var require_config = __commonJS((exports) => {
|
|
|
6161
6161
|
return `${HOMEDRIVE}${HOMEPATH}`;
|
|
6162
6162
|
const homeDirCacheKey = getHomeDirCacheKey();
|
|
6163
6163
|
if (!homeDirCache[homeDirCacheKey])
|
|
6164
|
-
homeDirCache[homeDirCacheKey] =
|
|
6164
|
+
homeDirCache[homeDirCacheKey] = homedir4();
|
|
6165
6165
|
return homeDirCache[homeDirCacheKey];
|
|
6166
6166
|
};
|
|
6167
6167
|
var ENV_PROFILE = "AWS_PROFILE";
|
|
@@ -6170,7 +6170,7 @@ var require_config = __commonJS((exports) => {
|
|
|
6170
6170
|
var getSSOTokenFilepath = (id) => {
|
|
6171
6171
|
const hasher = createHash2("sha1");
|
|
6172
6172
|
const cacheName = hasher.update(id).digest("hex");
|
|
6173
|
-
return
|
|
6173
|
+
return join5(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
6174
6174
|
};
|
|
6175
6175
|
var tokenIntercept = {};
|
|
6176
6176
|
var getSSOTokenFromFile = async (id) => {
|
|
@@ -6197,9 +6197,9 @@ var require_config = __commonJS((exports) => {
|
|
|
6197
6197
|
...data.default && { default: data.default }
|
|
6198
6198
|
});
|
|
6199
6199
|
var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
6200
|
-
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] ||
|
|
6200
|
+
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || join5(getHomeDir(), ".aws", "config");
|
|
6201
6201
|
var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
6202
|
-
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] ||
|
|
6202
|
+
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || join5(getHomeDir(), ".aws", "credentials");
|
|
6203
6203
|
var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@+.%:/]+)\2$/;
|
|
6204
6204
|
var profileNameBlockList = ["__proto__", "profile __proto__"];
|
|
6205
6205
|
var parseIni = (iniData) => {
|
|
@@ -6265,11 +6265,11 @@ var require_config = __commonJS((exports) => {
|
|
|
6265
6265
|
const relativeHomeDirPrefix = "~/";
|
|
6266
6266
|
let resolvedFilepath = filepath;
|
|
6267
6267
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
6268
|
-
resolvedFilepath =
|
|
6268
|
+
resolvedFilepath = join5(homeDir2, filepath.slice(2));
|
|
6269
6269
|
}
|
|
6270
6270
|
let resolvedConfigFilepath = configFilepath;
|
|
6271
6271
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
6272
|
-
resolvedConfigFilepath =
|
|
6272
|
+
resolvedConfigFilepath = join5(homeDir2, configFilepath.slice(2));
|
|
6273
6273
|
}
|
|
6274
6274
|
const parsedFiles = await Promise.all([
|
|
6275
6275
|
readFile(resolvedConfigFilepath, {
|
|
@@ -6486,7 +6486,7 @@ var require_config = __commonJS((exports) => {
|
|
|
6486
6486
|
};
|
|
6487
6487
|
var imdsRequest = async (options) => {
|
|
6488
6488
|
const { request } = __require("http");
|
|
6489
|
-
return new Promise((
|
|
6489
|
+
return new Promise((resolve4, reject) => {
|
|
6490
6490
|
const req = request({
|
|
6491
6491
|
hostname: options.hostname,
|
|
6492
6492
|
port: options.port,
|
|
@@ -6514,7 +6514,7 @@ var require_config = __commonJS((exports) => {
|
|
|
6514
6514
|
const chunks = [];
|
|
6515
6515
|
res.on("data", (chunk) => chunks.push(chunk));
|
|
6516
6516
|
res.on("end", () => {
|
|
6517
|
-
|
|
6517
|
+
resolve4(Buffer.concat(chunks));
|
|
6518
6518
|
req.destroy();
|
|
6519
6519
|
});
|
|
6520
6520
|
});
|
|
@@ -8865,7 +8865,7 @@ ${value}\r
|
|
|
8865
8865
|
if (isReadableStream(stream)) {
|
|
8866
8866
|
return headStream$1(stream, bytes);
|
|
8867
8867
|
}
|
|
8868
|
-
return new Promise((
|
|
8868
|
+
return new Promise((resolve4, reject) => {
|
|
8869
8869
|
const collector = new Collector$1;
|
|
8870
8870
|
collector.limit = bytes;
|
|
8871
8871
|
stream.pipe(collector);
|
|
@@ -8876,7 +8876,7 @@ ${value}\r
|
|
|
8876
8876
|
collector.on("error", reject);
|
|
8877
8877
|
collector.on("finish", function() {
|
|
8878
8878
|
const bytes2 = concatBytes(this.buffers);
|
|
8879
|
-
|
|
8879
|
+
resolve4(bytes2);
|
|
8880
8880
|
});
|
|
8881
8881
|
});
|
|
8882
8882
|
};
|
|
@@ -8990,7 +8990,7 @@ ${value}\r
|
|
|
8990
8990
|
if (isReadableStream(stream)) {
|
|
8991
8991
|
return collectReadableStream(stream);
|
|
8992
8992
|
}
|
|
8993
|
-
return new Promise((
|
|
8993
|
+
return new Promise((resolve4, reject) => {
|
|
8994
8994
|
const collector = new Collector;
|
|
8995
8995
|
const nodeStream = stream;
|
|
8996
8996
|
nodeStream.pipe(collector);
|
|
@@ -9001,7 +9001,7 @@ ${value}\r
|
|
|
9001
9001
|
collector.on("error", reject);
|
|
9002
9002
|
collector.on("finish", function() {
|
|
9003
9003
|
const bytes = concatBytes(this.bufferedBytes);
|
|
9004
|
-
|
|
9004
|
+
resolve4(bytes);
|
|
9005
9005
|
});
|
|
9006
9006
|
});
|
|
9007
9007
|
};
|
|
@@ -9193,7 +9193,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
9193
9193
|
callback();
|
|
9194
9194
|
}
|
|
9195
9195
|
}
|
|
9196
|
-
var fileStreamHasher = (hashCtor, fileStream) => new Promise((
|
|
9196
|
+
var fileStreamHasher = (hashCtor, fileStream) => new Promise((resolve4, reject) => {
|
|
9197
9197
|
if (!isReadStream(fileStream)) {
|
|
9198
9198
|
reject(new Error("Unable to calculate hash for non-file streams."));
|
|
9199
9199
|
return;
|
|
@@ -9211,7 +9211,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
9211
9211
|
});
|
|
9212
9212
|
hashCalculator.on("error", reject);
|
|
9213
9213
|
hashCalculator.on("finish", function() {
|
|
9214
|
-
hash.digest().then(
|
|
9214
|
+
hash.digest().then(resolve4).catch(reject);
|
|
9215
9215
|
});
|
|
9216
9216
|
});
|
|
9217
9217
|
var isReadStream = (stream) => typeof stream.path === "string";
|
|
@@ -9222,14 +9222,14 @@ var require_checksum = __commonJS((exports) => {
|
|
|
9222
9222
|
const hash = new hashCtor;
|
|
9223
9223
|
const hashCalculator = new HashCalculator(hash);
|
|
9224
9224
|
readableStream.pipe(hashCalculator);
|
|
9225
|
-
return new Promise((
|
|
9225
|
+
return new Promise((resolve4, reject) => {
|
|
9226
9226
|
readableStream.on("error", (err) => {
|
|
9227
9227
|
hashCalculator.end();
|
|
9228
9228
|
reject(err);
|
|
9229
9229
|
});
|
|
9230
9230
|
hashCalculator.on("error", reject);
|
|
9231
9231
|
hashCalculator.on("finish", () => {
|
|
9232
|
-
hash.digest().then(
|
|
9232
|
+
hash.digest().then(resolve4).catch(reject);
|
|
9233
9233
|
});
|
|
9234
9234
|
});
|
|
9235
9235
|
};
|
|
@@ -10335,7 +10335,7 @@ var require_event_streams = __commonJS((exports) => {
|
|
|
10335
10335
|
streamEnded = true;
|
|
10336
10336
|
});
|
|
10337
10337
|
while (!generationEnded) {
|
|
10338
|
-
const value = await new Promise((
|
|
10338
|
+
const value = await new Promise((resolve4) => setTimeout(() => resolve4(records.shift()), 0));
|
|
10339
10339
|
if (value) {
|
|
10340
10340
|
yield value;
|
|
10341
10341
|
}
|
|
@@ -11215,8 +11215,8 @@ var require_protocols = __commonJS((exports) => {
|
|
|
11215
11215
|
async build() {
|
|
11216
11216
|
const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
|
|
11217
11217
|
this.path = basePath;
|
|
11218
|
-
for (const
|
|
11219
|
-
|
|
11218
|
+
for (const resolvePath2 of this.resolvePathStack) {
|
|
11219
|
+
resolvePath2(this.path);
|
|
11220
11220
|
}
|
|
11221
11221
|
return new HttpRequest({
|
|
11222
11222
|
protocol,
|
|
@@ -11830,7 +11830,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
11830
11830
|
}
|
|
11831
11831
|
};
|
|
11832
11832
|
}
|
|
11833
|
-
var cooldown = (ms) => new Promise((
|
|
11833
|
+
var cooldown = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
11834
11834
|
var isRetryStrategyV2 = (retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" && typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" && typeof retryStrategy.recordSuccess !== "undefined";
|
|
11835
11835
|
var getRetryErrorInfo = (error, logger) => {
|
|
11836
11836
|
const errorInfo = {
|
|
@@ -11929,7 +11929,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
11929
11929
|
this.refillTokenBucket();
|
|
11930
11930
|
while (amount > this.availableTokens) {
|
|
11931
11931
|
const delay = (amount - this.availableTokens) / this.fillRate * 1000;
|
|
11932
|
-
await new Promise((
|
|
11932
|
+
await new Promise((resolve4) => DefaultRateLimiter.setTimeoutFn(resolve4, delay));
|
|
11933
11933
|
this.refillTokenBucket();
|
|
11934
11934
|
}
|
|
11935
11935
|
this.availableTokens = this.availableTokens - amount;
|
|
@@ -12271,7 +12271,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
12271
12271
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
12272
12272
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
12273
12273
|
totalDelay += delay;
|
|
12274
|
-
await new Promise((
|
|
12274
|
+
await new Promise((resolve4) => setTimeout(resolve4, delay));
|
|
12275
12275
|
continue;
|
|
12276
12276
|
}
|
|
12277
12277
|
if (!err.$metadata) {
|
|
@@ -15604,7 +15604,7 @@ var init_node_http = () => {};
|
|
|
15604
15604
|
|
|
15605
15605
|
// ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js
|
|
15606
15606
|
function httpRequest(options) {
|
|
15607
|
-
return new Promise((
|
|
15607
|
+
return new Promise((resolve4, reject) => {
|
|
15608
15608
|
const req = node_http.request({
|
|
15609
15609
|
method: "GET",
|
|
15610
15610
|
...options,
|
|
@@ -15629,7 +15629,7 @@ function httpRequest(options) {
|
|
|
15629
15629
|
chunks.push(chunk);
|
|
15630
15630
|
});
|
|
15631
15631
|
res.on("end", () => {
|
|
15632
|
-
|
|
15632
|
+
resolve4(Buffer.concat(chunks));
|
|
15633
15633
|
req.destroy();
|
|
15634
15634
|
});
|
|
15635
15635
|
});
|
|
@@ -15853,9 +15853,9 @@ var import_config6, IMDS_PATH = "/latest/meta-data/iam/security-credentials/", I
|
|
|
15853
15853
|
let fallbackBlockedFromProcessEnv = false;
|
|
15854
15854
|
const configValue = await import_config6.loadConfig({
|
|
15855
15855
|
environmentVariableSelector: (env) => {
|
|
15856
|
-
const
|
|
15857
|
-
fallbackBlockedFromProcessEnv = !!
|
|
15858
|
-
if (
|
|
15856
|
+
const envValue2 = env[AWS_EC2_METADATA_V1_DISABLED];
|
|
15857
|
+
fallbackBlockedFromProcessEnv = !!envValue2 && envValue2 !== "false";
|
|
15858
|
+
if (envValue2 === undefined) {
|
|
15859
15859
|
throw new import_config6.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`, { logger: init.logger });
|
|
15860
15860
|
}
|
|
15861
15861
|
return fallbackBlockedFromProcessEnv;
|
|
@@ -16123,21 +16123,21 @@ var require_dist_cjs4 = __commonJS((exports) => {
|
|
|
16123
16123
|
let sendBody = true;
|
|
16124
16124
|
if (!externalAgent && expect === "100-continue") {
|
|
16125
16125
|
sendBody = await Promise.race([
|
|
16126
|
-
new Promise((
|
|
16127
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
16126
|
+
new Promise((resolve4) => {
|
|
16127
|
+
timeoutId = Number(timing.setTimeout(() => resolve4(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
16128
16128
|
}),
|
|
16129
|
-
new Promise((
|
|
16129
|
+
new Promise((resolve4) => {
|
|
16130
16130
|
httpRequest2.on("continue", () => {
|
|
16131
16131
|
timing.clearTimeout(timeoutId);
|
|
16132
|
-
|
|
16132
|
+
resolve4(true);
|
|
16133
16133
|
});
|
|
16134
16134
|
httpRequest2.on("response", () => {
|
|
16135
16135
|
timing.clearTimeout(timeoutId);
|
|
16136
|
-
|
|
16136
|
+
resolve4(false);
|
|
16137
16137
|
});
|
|
16138
16138
|
httpRequest2.on("error", () => {
|
|
16139
16139
|
timing.clearTimeout(timeoutId);
|
|
16140
|
-
|
|
16140
|
+
resolve4(false);
|
|
16141
16141
|
});
|
|
16142
16142
|
})
|
|
16143
16143
|
]);
|
|
@@ -16212,13 +16212,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16212
16212
|
return socketWarningTimestamp;
|
|
16213
16213
|
}
|
|
16214
16214
|
constructor(options) {
|
|
16215
|
-
this.configProvider = new Promise((
|
|
16215
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
16216
16216
|
if (typeof options === "function") {
|
|
16217
16217
|
options().then((_options) => {
|
|
16218
|
-
|
|
16218
|
+
resolve4(this.resolveDefaultConfig(_options));
|
|
16219
16219
|
}).catch(reject);
|
|
16220
16220
|
} else {
|
|
16221
|
-
|
|
16221
|
+
resolve4(this.resolveDefaultConfig(options));
|
|
16222
16222
|
}
|
|
16223
16223
|
});
|
|
16224
16224
|
}
|
|
@@ -16250,7 +16250,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16250
16250
|
timing.clearTimeout(socketTimeoutId);
|
|
16251
16251
|
timing.clearTimeout(keepAliveTimeoutId);
|
|
16252
16252
|
};
|
|
16253
|
-
const
|
|
16253
|
+
const resolve4 = async (arg) => {
|
|
16254
16254
|
await writeRequestBodyPromise;
|
|
16255
16255
|
clearTimeouts();
|
|
16256
16256
|
_resolve(arg);
|
|
@@ -16314,7 +16314,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16314
16314
|
headers: getTransformedHeaders(res.headers),
|
|
16315
16315
|
body: res
|
|
16316
16316
|
});
|
|
16317
|
-
|
|
16317
|
+
resolve4({ response: httpResponse });
|
|
16318
16318
|
});
|
|
16319
16319
|
req.on("error", (err) => {
|
|
16320
16320
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -16646,13 +16646,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16646
16646
|
return new NodeHttp2Handler(instanceOrOptions);
|
|
16647
16647
|
}
|
|
16648
16648
|
constructor(options) {
|
|
16649
|
-
this.configProvider = new Promise((
|
|
16649
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
16650
16650
|
if (typeof options === "function") {
|
|
16651
16651
|
options().then((opts) => {
|
|
16652
|
-
|
|
16652
|
+
resolve4(opts || {});
|
|
16653
16653
|
}).catch(reject);
|
|
16654
16654
|
} else {
|
|
16655
|
-
|
|
16655
|
+
resolve4(options || {});
|
|
16656
16656
|
}
|
|
16657
16657
|
});
|
|
16658
16658
|
}
|
|
@@ -16677,7 +16677,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16677
16677
|
return new Promise((_resolve, _reject) => {
|
|
16678
16678
|
let fulfilled = false;
|
|
16679
16679
|
let writeRequestBodyPromise = undefined;
|
|
16680
|
-
const
|
|
16680
|
+
const resolve4 = async (arg) => {
|
|
16681
16681
|
await writeRequestBodyPromise;
|
|
16682
16682
|
_resolve(arg);
|
|
16683
16683
|
};
|
|
@@ -16762,7 +16762,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
16762
16762
|
body: clientHttp2Stream
|
|
16763
16763
|
});
|
|
16764
16764
|
fulfilled = true;
|
|
16765
|
-
|
|
16765
|
+
resolve4({ response: httpResponse });
|
|
16766
16766
|
if (useIsolatedSession) {
|
|
16767
16767
|
session.close();
|
|
16768
16768
|
}
|
|
@@ -16888,7 +16888,7 @@ var retryWrapper = (toRetry, maxRetries, delayMs) => {
|
|
|
16888
16888
|
try {
|
|
16889
16889
|
return await toRetry();
|
|
16890
16890
|
} catch (e) {
|
|
16891
|
-
await new Promise((
|
|
16891
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
16892
16892
|
}
|
|
16893
16893
|
}
|
|
16894
16894
|
return await toRetry();
|
|
@@ -26096,8 +26096,8 @@ var require_signin = __commonJS((exports) => {
|
|
|
26096
26096
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
|
|
26097
26097
|
import { createHash as createHash2, createPrivateKey, createPublicKey, sign } from "crypto";
|
|
26098
26098
|
import { promises as fs2 } from "fs";
|
|
26099
|
-
import { homedir as
|
|
26100
|
-
import { dirname as dirname3, join as
|
|
26099
|
+
import { homedir as homedir4 } from "os";
|
|
26100
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
26101
26101
|
var import_config20, import_protocols3, LoginCredentialsFetcher;
|
|
26102
26102
|
var init_LoginCredentialsFetcher = __esm(() => {
|
|
26103
26103
|
import_config20 = __toESM(require_config(), 1);
|
|
@@ -26264,10 +26264,10 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
26264
26264
|
await fs2.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
26265
26265
|
}
|
|
26266
26266
|
getTokenFilePath() {
|
|
26267
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
26267
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join5(homedir4(), ".aws", "login", "cache");
|
|
26268
26268
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
26269
26269
|
const loginSessionSha256 = createHash2("sha256").update(loginSessionBytes).digest("hex");
|
|
26270
|
-
return
|
|
26270
|
+
return join5(directory, `${loginSessionSha256}.json`);
|
|
26271
26271
|
}
|
|
26272
26272
|
derToRawSignature(derSignature) {
|
|
26273
26273
|
let offset = 2;
|
|
@@ -26841,9 +26841,9 @@ async function startMcpHttpServer(buildServer, options) {
|
|
|
26841
26841
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
26842
26842
|
res.end("Not Found");
|
|
26843
26843
|
});
|
|
26844
|
-
await new Promise((
|
|
26844
|
+
await new Promise((resolve4, reject) => {
|
|
26845
26845
|
httpServer.once("error", reject);
|
|
26846
|
-
httpServer.listen(requestedPort, host, () =>
|
|
26846
|
+
httpServer.listen(requestedPort, host, () => resolve4());
|
|
26847
26847
|
});
|
|
26848
26848
|
const addr = httpServer.address();
|
|
26849
26849
|
const port = typeof addr === "object" && addr ? addr.port : requestedPort;
|
|
@@ -26851,8 +26851,8 @@ async function startMcpHttpServer(buildServer, options) {
|
|
|
26851
26851
|
return {
|
|
26852
26852
|
port,
|
|
26853
26853
|
host,
|
|
26854
|
-
close: () => new Promise((
|
|
26855
|
-
httpServer.close((err) => err ? reject(err) :
|
|
26854
|
+
close: () => new Promise((resolve4, reject) => {
|
|
26855
|
+
httpServer.close((err) => err ? reject(err) : resolve4());
|
|
26856
26856
|
})
|
|
26857
26857
|
};
|
|
26858
26858
|
}
|
|
@@ -26996,6 +26996,7 @@ import { StdioServerTransport as StdioServerTransport2 } from "@modelcontextprot
|
|
|
26996
26996
|
// ../contracts/dist/client/storage.js
|
|
26997
26997
|
import { isIP } from "net";
|
|
26998
26998
|
import { readFileSync, statSync } from "fs";
|
|
26999
|
+
import { createRequire } from "module";
|
|
26999
27000
|
import { join } from "path";
|
|
27000
27001
|
function envToken(name) {
|
|
27001
27002
|
return name.toUpperCase().replace(/-/g, "_");
|
|
@@ -27011,6 +27012,9 @@ function credentialOverrideEnvKey(name) {
|
|
|
27011
27012
|
return `HASNA_${envToken(name)}_API_KEY_OVERRIDE`;
|
|
27012
27013
|
}
|
|
27013
27014
|
var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE";
|
|
27015
|
+
function credentialPointerEnvKey(name) {
|
|
27016
|
+
return `HASNA_${envToken(name)}_API_KEY_REF`;
|
|
27017
|
+
}
|
|
27014
27018
|
|
|
27015
27019
|
class CredentialResolutionError extends Error {
|
|
27016
27020
|
appName;
|
|
@@ -27023,31 +27027,55 @@ class CredentialResolutionError extends Error {
|
|
|
27023
27027
|
}
|
|
27024
27028
|
}
|
|
27025
27029
|
var HASNA_STATE_DIR = ".hasna";
|
|
27026
|
-
var FLEET_CREDENTIAL_DIR = "
|
|
27030
|
+
var FLEET_CREDENTIAL_DIR = "fleet-env";
|
|
27031
|
+
var LEGACY_CLOUD_DIR = "cloud";
|
|
27027
27032
|
var CONFIG_DIR = ".config";
|
|
27028
27033
|
var CONFIG_NAMESPACE = "hasna";
|
|
27034
|
+
var LEGACY_CLOUD_REMOVAL_DEADLINE = "2026-10-01";
|
|
27029
27035
|
var MAX_CREDENTIAL_FILE_BYTES = 64 * 1024;
|
|
27030
27036
|
var SAFE_APP_SLUG = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
27031
27037
|
var SAFE_PROFILE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
27032
27038
|
var ILLEGAL_IN_HEADER_VALUE = /[^\t\x20-\x7e]/;
|
|
27039
|
+
var VAULT_POINTER_SHAPE = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-_.]*){2,}$/;
|
|
27033
27040
|
function homeDir(env) {
|
|
27034
27041
|
const home = env.HOME?.trim();
|
|
27035
27042
|
return home ? home : null;
|
|
27036
27043
|
}
|
|
27037
|
-
function
|
|
27038
|
-
return profileDiskSources(name, env, null);
|
|
27039
|
-
}
|
|
27040
|
-
function profileDiskSources(name, env, profile) {
|
|
27044
|
+
function credentialDiskSourceList(name, env, profile = null) {
|
|
27041
27045
|
const home = homeDir(env);
|
|
27042
27046
|
if (!home || !SAFE_APP_SLUG.test(name))
|
|
27043
27047
|
return [];
|
|
27044
27048
|
const stem = profile ? `${name}.${profile}` : name;
|
|
27045
27049
|
const configStem = profile ? `${name}-${profile}` : name;
|
|
27046
27050
|
return [
|
|
27047
|
-
|
|
27048
|
-
|
|
27051
|
+
{
|
|
27052
|
+
path: join(home, HASNA_STATE_DIR, FLEET_CREDENTIAL_DIR, `${stem}.env`),
|
|
27053
|
+
tier: "fleet-env",
|
|
27054
|
+
deprecated: false
|
|
27055
|
+
},
|
|
27056
|
+
{
|
|
27057
|
+
path: join(home, HASNA_STATE_DIR, LEGACY_CLOUD_DIR, `${stem}.env`),
|
|
27058
|
+
tier: "legacy-cloud",
|
|
27059
|
+
deprecated: true
|
|
27060
|
+
},
|
|
27061
|
+
{
|
|
27062
|
+
path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}.env`),
|
|
27063
|
+
tier: "config",
|
|
27064
|
+
deprecated: false
|
|
27065
|
+
},
|
|
27066
|
+
{
|
|
27067
|
+
path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}-cloud.env`),
|
|
27068
|
+
tier: "config-legacy",
|
|
27069
|
+
deprecated: true
|
|
27070
|
+
}
|
|
27049
27071
|
];
|
|
27050
27072
|
}
|
|
27073
|
+
function credentialDiskSources(name, env) {
|
|
27074
|
+
return credentialDiskSourceList(name, env, null).map((s) => s.path);
|
|
27075
|
+
}
|
|
27076
|
+
function profileDiskSources(name, env, profile) {
|
|
27077
|
+
return credentialDiskSourceList(name, env, profile).map((s) => s.path);
|
|
27078
|
+
}
|
|
27051
27079
|
function parseEnvFile(text) {
|
|
27052
27080
|
const values = new Map;
|
|
27053
27081
|
for (const rawLine of text.split(/\r?\n/)) {
|
|
@@ -27115,6 +27143,9 @@ function appConfigDiskValue(name, env, keys) {
|
|
|
27115
27143
|
return null;
|
|
27116
27144
|
}
|
|
27117
27145
|
function assertUsableCredential(appName, source, value) {
|
|
27146
|
+
if (VAULT_POINTER_SHAPE.test(value)) {
|
|
27147
|
+
throw new CredentialResolutionError(appName, `The credential from ${source} looks like a secrets-vault pointer (a path-shaped reference like ` + `'namespace/app/live/api_key'). A vault path is NEVER accepted as a literal API key. ` + `Use ${credentialPointerEnvKey(appName)} to resolve the key through the vault, or provide the actual key value.`, [source]);
|
|
27148
|
+
}
|
|
27118
27149
|
if (!ILLEGAL_IN_HEADER_VALUE.test(value))
|
|
27119
27150
|
return;
|
|
27120
27151
|
throw new CredentialResolutionError(appName, `The credential from ${source} contains characters that cannot be sent in an HTTP header ` + `(a control character or non-ASCII byte). A file written with CR-only line endings is the usual ` + `cause. Rewrite that credential file with one LF-terminated KEY=value line. ` + `The value is not shown here, and is deliberately never logged.`, [source]);
|
|
@@ -27139,6 +27170,14 @@ function sealCredential(fields) {
|
|
|
27139
27170
|
writable: false,
|
|
27140
27171
|
configurable: false
|
|
27141
27172
|
});
|
|
27173
|
+
if (fields.pointerVaultKey !== undefined) {
|
|
27174
|
+
Object.defineProperty(sealed, "pointerVaultKey", {
|
|
27175
|
+
value: fields.pointerVaultKey,
|
|
27176
|
+
enumerable: false,
|
|
27177
|
+
writable: false,
|
|
27178
|
+
configurable: false
|
|
27179
|
+
});
|
|
27180
|
+
}
|
|
27142
27181
|
Object.defineProperty(sealed, INSPECT_CUSTOM, {
|
|
27143
27182
|
value: () => ({ ...visible, apiKey: "[redacted]" }),
|
|
27144
27183
|
enumerable: false,
|
|
@@ -27190,7 +27229,8 @@ function validateAndSealResolvedCredential(appName, credential) {
|
|
|
27190
27229
|
deliberate: credential.deliberate,
|
|
27191
27230
|
deprecated: credential.deprecated,
|
|
27192
27231
|
diskCandidates: credential.diskCandidates,
|
|
27193
|
-
warning: credential.warning
|
|
27232
|
+
warning: credential.warning,
|
|
27233
|
+
...credential.pointerVaultKey !== undefined ? { pointerVaultKey: credential.pointerVaultKey } : {}
|
|
27194
27234
|
});
|
|
27195
27235
|
}
|
|
27196
27236
|
function firstEnvValue(env, keys) {
|
|
@@ -27251,6 +27291,27 @@ function resolveCredential(name, env, options = {}) {
|
|
|
27251
27291
|
warning: null
|
|
27252
27292
|
});
|
|
27253
27293
|
}
|
|
27294
|
+
const pointerKeyName = credentialPointerEnvKey(name);
|
|
27295
|
+
const pointerRaw = env[pointerKeyName];
|
|
27296
|
+
if (pointerRaw !== undefined) {
|
|
27297
|
+
const pointer = pointerRaw.trim();
|
|
27298
|
+
if (!pointer) {
|
|
27299
|
+
throw new CredentialResolutionError(name, `${pointerKeyName} is set but empty. It is a deliberate vault pointer, so it is not resolved around: ` + `either give it a vault item key or unset it to fall back to the credential on disk.`, [pointerKeyName]);
|
|
27300
|
+
}
|
|
27301
|
+
if (!VAULT_POINTER_SHAPE.test(pointer)) {
|
|
27302
|
+
throw new CredentialResolutionError(name, `${pointerKeyName} must name a vault ITEM KEY (a path-shaped reference like ` + `'namespace/app/live/api_key'), not a credential value. A pointer that carries a literal is refused.`, [pointerKeyName]);
|
|
27303
|
+
}
|
|
27304
|
+
return sealCredential({
|
|
27305
|
+
apiKey: "",
|
|
27306
|
+
pointerVaultKey: pointer,
|
|
27307
|
+
tier: "pointer",
|
|
27308
|
+
source: pointerKeyName,
|
|
27309
|
+
deliberate: true,
|
|
27310
|
+
deprecated: false,
|
|
27311
|
+
diskCandidates: diskPaths,
|
|
27312
|
+
warning: null
|
|
27313
|
+
});
|
|
27314
|
+
}
|
|
27254
27315
|
const profile = options.profile?.trim() || env[CREDENTIAL_PROFILE_ENV_KEY]?.trim();
|
|
27255
27316
|
if (profile) {
|
|
27256
27317
|
const profileSource = options.profile?.trim() ? "explicit profile argument" : CREDENTIAL_PROFILE_ENV_KEY;
|
|
@@ -27275,26 +27336,42 @@ function resolveCredential(name, env, options = {}) {
|
|
|
27275
27336
|
}
|
|
27276
27337
|
throw new CredentialResolutionError(name, `Profile '${profile}' (from ${profileSource}) has no ${apiKeyKeys[0]} for '${name}'. ` + `Looked in: ${paths.join(", ") || "<no HOME in this environment>"}. ` + `A profile names WHICH identity to use, so it is never resolved around \u2014 ` + `create the profile's credential file or unset ${CREDENTIAL_PROFILE_ENV_KEY}.`, paths);
|
|
27277
27338
|
}
|
|
27278
|
-
const
|
|
27339
|
+
const diskSourceList = credentialDiskSourceList(name, env, null);
|
|
27340
|
+
const diskHits = diskSourceList.map((src) => ({ src, value: readCredentialFile(src.path, apiKeyKeys) })).filter((hit) => hit.value !== null);
|
|
27279
27341
|
if (diskHits.length > 0) {
|
|
27280
27342
|
const winner = diskHits[0];
|
|
27281
|
-
assertUsableCredential(name, winner.path, winner.value);
|
|
27343
|
+
assertUsableCredential(name, winner.src.path, winner.value);
|
|
27282
27344
|
const divergentSources = [
|
|
27283
|
-
...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.path),
|
|
27345
|
+
...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.src.path),
|
|
27284
27346
|
...(() => {
|
|
27285
27347
|
const legacyHit = firstEnvValue(env, apiKeyKeys);
|
|
27286
27348
|
return legacyHit && legacyHit.value !== winner.value ? [legacyHit.key] : [];
|
|
27287
27349
|
})()
|
|
27288
27350
|
];
|
|
27289
|
-
const warning = divergentSources.length > 0 ? `Credential sources disagree for '${name}': ${winner.path} and ` + `${divergentSources.join(", ")} hold different keys. ${winner.path} wins, because a file on ` + `disk is re-read on every call while an environment variable is a snapshot. Reconcile them \u2014 ` + `a rotation that updated only one leaves the other to fail 401 wherever it is loaded first.` : null;
|
|
27351
|
+
const warning = divergentSources.length > 0 ? `Credential sources disagree for '${name}': ${winner.src.path} and ` + `${divergentSources.join(", ")} hold different keys. ${winner.src.path} wins, because a file on ` + `disk is re-read on every call while an environment variable is a snapshot. Reconcile them \u2014 ` + `a rotation that updated only one leaves the other to fail 401 wherever it is loaded first.` : null;
|
|
27352
|
+
let deprecated = winner.src.deprecated;
|
|
27353
|
+
let finalWarning = warning;
|
|
27354
|
+
if (winner.src.deprecated) {
|
|
27355
|
+
deprecated = true;
|
|
27356
|
+
const sink = options.onDeprecation ?? defaultDeprecationSink;
|
|
27357
|
+
const notified = deprecationNotified();
|
|
27358
|
+
const noticeKey = `${name}:${winner.src.path}`;
|
|
27359
|
+
if (!notified.has(noticeKey)) {
|
|
27360
|
+
notified.add(noticeKey);
|
|
27361
|
+
const target = diskSourceList[0]?.path ?? "<none>";
|
|
27362
|
+
const message = `[${name}] DEPRECATED: the API key came from ${winner.src.path} \u2014 a legacy credential location. ` + `The primary location is ${target} (~/.hasna/fleet-env/<app>.env). The legacy 'cloud' tiers are ` + `removed after ${LEGACY_CLOUD_REMOVAL_DEADLINE}. Migrate the key to the primary location.`;
|
|
27363
|
+
sink(message);
|
|
27364
|
+
}
|
|
27365
|
+
finalWarning = [warning, `Legacy credential source: ${winner.src.path}. Removed after ${LEGACY_CLOUD_REMOVAL_DEADLINE}.`].filter(Boolean).join(" ") || null;
|
|
27366
|
+
}
|
|
27290
27367
|
return sealCredential({
|
|
27291
27368
|
apiKey: winner.value,
|
|
27292
|
-
tier:
|
|
27293
|
-
source: winner.path,
|
|
27369
|
+
tier: winner.src.tier,
|
|
27370
|
+
source: winner.src.path,
|
|
27294
27371
|
deliberate: false,
|
|
27295
|
-
deprecated
|
|
27372
|
+
deprecated,
|
|
27296
27373
|
diskCandidates: diskPaths,
|
|
27297
|
-
warning
|
|
27374
|
+
warning: finalWarning
|
|
27298
27375
|
});
|
|
27299
27376
|
}
|
|
27300
27377
|
const legacy = firstEnvValue(env, apiKeyKeys);
|
|
@@ -27320,6 +27397,47 @@ function resolveCredential(name, env, options = {}) {
|
|
|
27320
27397
|
}
|
|
27321
27398
|
return null;
|
|
27322
27399
|
}
|
|
27400
|
+
var SECRETS_PACKAGE_SPECIFIER = "@hasna/" + "secrets";
|
|
27401
|
+
var requireSecretsSdk = createRequire(import.meta.url);
|
|
27402
|
+
async function completePointerCredential(name, pointerResolution, env = process.env) {
|
|
27403
|
+
const vaultKey = pointerResolution.pointerVaultKey;
|
|
27404
|
+
const pointerEnvKey = pointerResolution.source;
|
|
27405
|
+
if (!vaultKey) {
|
|
27406
|
+
throw new CredentialResolutionError(name, `Pointer resolution from ${pointerEnvKey} carries no vault item key; this is a defect in the resolver.`, [pointerEnvKey]);
|
|
27407
|
+
}
|
|
27408
|
+
let secretsSdk;
|
|
27409
|
+
try {
|
|
27410
|
+
secretsSdk = requireSecretsSdk(SECRETS_PACKAGE_SPECIFIER);
|
|
27411
|
+
} catch {
|
|
27412
|
+
throw new CredentialResolutionError(name, `${pointerEnvKey} names vault item '${vaultKey}', but the secrets SDK (@hasna/secrets) is not installed ` + `in this process. A vault pointer is TERMINAL: install @hasna/secrets to resolve it, or unset ${pointerEnvKey}.`, [pointerEnvKey]);
|
|
27413
|
+
}
|
|
27414
|
+
let client;
|
|
27415
|
+
try {
|
|
27416
|
+
client = secretsSdk.createSecretsClientFromEnv(env);
|
|
27417
|
+
} catch {
|
|
27418
|
+
throw new CredentialResolutionError(name, `${pointerEnvKey} names vault item '${vaultKey}', but the secrets client could not be configured from this ` + `environment (the secrets service URL and key env are missing or invalid). A vault pointer is TERMINAL and ` + `never falls through to a literal or disk credential.`, [pointerEnvKey]);
|
|
27419
|
+
}
|
|
27420
|
+
let secret;
|
|
27421
|
+
try {
|
|
27422
|
+
secret = await client.getSecret({ key: vaultKey });
|
|
27423
|
+
} catch {
|
|
27424
|
+
throw new CredentialResolutionError(name, `${pointerEnvKey} names vault item '${vaultKey}', but the vault could not be reached or the item is ` + `unavailable. A vault pointer is TERMINAL and never falls through to a literal or disk credential.`, [pointerEnvKey]);
|
|
27425
|
+
}
|
|
27426
|
+
const value = secret.value;
|
|
27427
|
+
if (!value) {
|
|
27428
|
+
throw new CredentialResolutionError(name, `${pointerEnvKey} resolved vault item '${vaultKey}', but it holds no value. A vault pointer is TERMINAL.`, [pointerEnvKey]);
|
|
27429
|
+
}
|
|
27430
|
+
assertUsableCredential(name, `${pointerEnvKey} -> vault:${vaultKey}`, value);
|
|
27431
|
+
return sealCredential({
|
|
27432
|
+
apiKey: value,
|
|
27433
|
+
tier: "pointer",
|
|
27434
|
+
source: `${pointerEnvKey} -> vault:${vaultKey}`,
|
|
27435
|
+
deliberate: true,
|
|
27436
|
+
deprecated: false,
|
|
27437
|
+
diskCandidates: pointerResolution.diskCandidates,
|
|
27438
|
+
warning: null
|
|
27439
|
+
});
|
|
27440
|
+
}
|
|
27323
27441
|
var ASCII_CONTROL_PATTERN = /[\u0000-\u001f\u007f]/;
|
|
27324
27442
|
var DNS_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
27325
27443
|
function isValidDnsDomain(value) {
|
|
@@ -27565,6 +27683,13 @@ function currentCredential(name, apiKey) {
|
|
|
27565
27683
|
}
|
|
27566
27684
|
return explicitCredential(name, apiKey);
|
|
27567
27685
|
}
|
|
27686
|
+
async function resolveRequestCredential(name, apiKey, env = process.env) {
|
|
27687
|
+
const resolved = currentCredential(name, apiKey);
|
|
27688
|
+
if (resolved.tier === "pointer") {
|
|
27689
|
+
return completePointerCredential(name, resolved, env);
|
|
27690
|
+
}
|
|
27691
|
+
return resolved;
|
|
27692
|
+
}
|
|
27568
27693
|
function authFailureGuidance(credential) {
|
|
27569
27694
|
const origin = `The API key for this request came from ${credential.source}`;
|
|
27570
27695
|
if (credential.deliberate) {
|
|
@@ -27720,7 +27845,7 @@ function createHasnaHttpTransport(options) {
|
|
|
27720
27845
|
const retry = resolveRetry(opts.retry);
|
|
27721
27846
|
const methodRetryable = IDEMPOTENT_METHODS.has(upper) || Boolean(opts.idempotencyKey);
|
|
27722
27847
|
const maxAttempts = retry && methodRetryable ? retry.retries + 1 : 1;
|
|
27723
|
-
const credential =
|
|
27848
|
+
const credential = await resolveRequestCredential(options.name, options.apiKey);
|
|
27724
27849
|
let last = null;
|
|
27725
27850
|
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
27726
27851
|
const result = await once(upper, rel, url, body, opts, credential);
|
|
@@ -27885,6 +28010,7 @@ function resolveStorageClient(name, env = process.env, overrides) {
|
|
|
27885
28010
|
}
|
|
27886
28011
|
|
|
27887
28012
|
// ../contracts/dist/client/transport.js
|
|
28013
|
+
import { createRequire as createRequire2 } from "module";
|
|
27888
28014
|
function envToken2(name) {
|
|
27889
28015
|
return name.toUpperCase().replace(/-/g, "_");
|
|
27890
28016
|
}
|
|
@@ -27899,6 +28025,8 @@ var MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
|
|
|
27899
28025
|
var INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
|
|
27900
28026
|
var CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
|
|
27901
28027
|
var DEPRECATION_REGISTRY2 = Symbol.for("hasna:contracts:credentialDeprecationNotices");
|
|
28028
|
+
var SECRETS_PACKAGE_SPECIFIER2 = "@hasna/" + "secrets";
|
|
28029
|
+
var requireSecretsSdk2 = createRequire2(import.meta.url);
|
|
27902
28030
|
var IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
27903
28031
|
var AUTHORITY_OVERRIDE_HEADERS2 = new Set([
|
|
27904
28032
|
"host",
|
|
@@ -27913,15 +28041,15 @@ import { Database } from "bun:sqlite";
|
|
|
27913
28041
|
import { createHash } from "crypto";
|
|
27914
28042
|
import {
|
|
27915
28043
|
copyFileSync,
|
|
27916
|
-
existsSync,
|
|
28044
|
+
existsSync as existsSync2,
|
|
27917
28045
|
mkdirSync,
|
|
27918
28046
|
readFileSync as readFileSync2,
|
|
27919
28047
|
readdirSync,
|
|
27920
28048
|
statSync as statSync2,
|
|
27921
28049
|
writeFileSync
|
|
27922
28050
|
} from "fs";
|
|
27923
|
-
import { dirname, join as
|
|
27924
|
-
import { homedir } from "os";
|
|
28051
|
+
import { dirname, join as join4, resolve as resolve2 } from "path";
|
|
28052
|
+
import { homedir as homedir3 } from "os";
|
|
27925
28053
|
|
|
27926
28054
|
// src/db/migrations.ts
|
|
27927
28055
|
var MIGRATIONS = [
|
|
@@ -28190,10 +28318,116 @@ var MIGRATIONS = [
|
|
|
28190
28318
|
}
|
|
28191
28319
|
];
|
|
28192
28320
|
|
|
28321
|
+
// src/lib/app-home.ts
|
|
28322
|
+
import { existsSync } from "fs";
|
|
28323
|
+
import { homedir as homedir2 } from "os";
|
|
28324
|
+
import { join as join3, resolve } from "path";
|
|
28325
|
+
|
|
28326
|
+
// ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
|
|
28327
|
+
import { homedir } from "os";
|
|
28328
|
+
import { join as join2 } from "path";
|
|
28329
|
+
var KIND_ENV = {
|
|
28330
|
+
config: "HASNA_CONFIG_HOME",
|
|
28331
|
+
data: "HASNA_DATA_HOME",
|
|
28332
|
+
state: "HASNA_STATE_HOME",
|
|
28333
|
+
cache: "HASNA_CACHE_HOME"
|
|
28334
|
+
};
|
|
28335
|
+
var APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
28336
|
+
function assertApp(app) {
|
|
28337
|
+
if (typeof app !== "string" || app.length === 0) {
|
|
28338
|
+
throw new TypeError("paths: app must be a non-empty string");
|
|
28339
|
+
}
|
|
28340
|
+
if (!APP_SLUG_RE.test(app)) {
|
|
28341
|
+
throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
|
|
28342
|
+
}
|
|
28343
|
+
}
|
|
28344
|
+
function envOf(options) {
|
|
28345
|
+
return options.env ?? process.env;
|
|
28346
|
+
}
|
|
28347
|
+
function envValue(options, kind) {
|
|
28348
|
+
const value = envOf(options)[KIND_ENV[kind]];
|
|
28349
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
28350
|
+
}
|
|
28351
|
+
function isMacOS(platform) {
|
|
28352
|
+
return platform === "darwin";
|
|
28353
|
+
}
|
|
28354
|
+
function baseDir(kind, options) {
|
|
28355
|
+
const override = envValue(options, kind);
|
|
28356
|
+
if (override)
|
|
28357
|
+
return override;
|
|
28358
|
+
const home = options.home ?? homedir();
|
|
28359
|
+
const platform = options.platform ?? process.platform;
|
|
28360
|
+
if (isMacOS(platform)) {
|
|
28361
|
+
switch (kind) {
|
|
28362
|
+
case "config":
|
|
28363
|
+
case "data":
|
|
28364
|
+
return join2(home, "Library", "Application Support", "Hasna");
|
|
28365
|
+
case "cache":
|
|
28366
|
+
return join2(home, "Library", "Caches", "Hasna");
|
|
28367
|
+
case "state":
|
|
28368
|
+
return join2(home, "Library", "Logs", "Hasna");
|
|
28369
|
+
}
|
|
28370
|
+
}
|
|
28371
|
+
switch (kind) {
|
|
28372
|
+
case "config":
|
|
28373
|
+
return join2(home, ".config", "hasna");
|
|
28374
|
+
case "data":
|
|
28375
|
+
return join2(home, ".local", "share", "hasna");
|
|
28376
|
+
case "state":
|
|
28377
|
+
return join2(home, ".local", "state", "hasna");
|
|
28378
|
+
case "cache":
|
|
28379
|
+
return join2(home, ".cache", "hasna");
|
|
28380
|
+
}
|
|
28381
|
+
}
|
|
28382
|
+
function resolvePath(kind, options) {
|
|
28383
|
+
assertApp(options.app);
|
|
28384
|
+
const appSegment = options.internal === true ? join2("internal", options.app) : options.app;
|
|
28385
|
+
return join2(baseDir(kind, options), appSegment);
|
|
28386
|
+
}
|
|
28387
|
+
function dataDir(options) {
|
|
28388
|
+
return resolvePath("data", options);
|
|
28389
|
+
}
|
|
28390
|
+
|
|
28391
|
+
// src/lib/app-home.ts
|
|
28392
|
+
var APP = "domains";
|
|
28393
|
+
function effectiveHome(env = process.env) {
|
|
28394
|
+
return env["HOME"] || env["USERPROFILE"] || homedir2();
|
|
28395
|
+
}
|
|
28396
|
+
function legacyHomeDir(env = process.env) {
|
|
28397
|
+
return join3(effectiveHome(env), ".hasna", APP);
|
|
28398
|
+
}
|
|
28399
|
+
function resolverHome(env = process.env) {
|
|
28400
|
+
const home = env["HOME"] || env["USERPROFILE"];
|
|
28401
|
+
return dataDir({ app: APP, home, env });
|
|
28402
|
+
}
|
|
28403
|
+
function adoptResolverHome(resolved, env = process.env) {
|
|
28404
|
+
const dataOverride = env.HASNA_DATA_HOME;
|
|
28405
|
+
if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
|
|
28406
|
+
return true;
|
|
28407
|
+
return existsSync(join3(resolved, "domains.db"));
|
|
28408
|
+
}
|
|
28409
|
+
function exactAppOverride(env = process.env) {
|
|
28410
|
+
const override = env["HASNA_DOMAINS_HOME"] ?? env["DOMAINS_HOME"] ?? env["HASNA_DOMAINS_DIR"] ?? env["DOMAINS_DIR"];
|
|
28411
|
+
return override && override.trim() ? override.trim() : undefined;
|
|
28412
|
+
}
|
|
28413
|
+
function appHome(env = process.env) {
|
|
28414
|
+
const override = exactAppOverride(env);
|
|
28415
|
+
if (override)
|
|
28416
|
+
return resolve(override);
|
|
28417
|
+
const resolved = resolverHome(env);
|
|
28418
|
+
return adoptResolverHome(resolved, env) ? resolve(resolved) : resolve(legacyHomeDir(env));
|
|
28419
|
+
}
|
|
28420
|
+
function getDefaultDbPath(env = process.env) {
|
|
28421
|
+
return join3(appHome(env), `${APP}.db`);
|
|
28422
|
+
}
|
|
28423
|
+
function getDefaultConfigPath(env = process.env) {
|
|
28424
|
+
return join3(appHome(env), "config.json");
|
|
28425
|
+
}
|
|
28426
|
+
|
|
28193
28427
|
// src/db/database.ts
|
|
28194
28428
|
var _db = null;
|
|
28195
28429
|
function canonicalHome(env) {
|
|
28196
|
-
return env["HOME"] || env["USERPROFILE"] ||
|
|
28430
|
+
return env["HOME"] || env["USERPROFILE"] || homedir3();
|
|
28197
28431
|
}
|
|
28198
28432
|
function sha256File(path) {
|
|
28199
28433
|
return createHash("sha256").update(readFileSync2(path)).digest("hex");
|
|
@@ -28201,20 +28435,20 @@ function sha256File(path) {
|
|
|
28201
28435
|
function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
28202
28436
|
const report = { dryRun, wouldCopy: [], copied: [] };
|
|
28203
28437
|
const home = canonicalHome(env);
|
|
28204
|
-
const xdgData = env["XDG_DATA_HOME"]?.trim() ||
|
|
28205
|
-
const oldDir =
|
|
28206
|
-
const oldDb =
|
|
28207
|
-
if (!
|
|
28438
|
+
const xdgData = env["XDG_DATA_HOME"]?.trim() || join4(home, ".local", "share");
|
|
28439
|
+
const oldDir = join4(xdgData, "open-domains");
|
|
28440
|
+
const oldDb = join4(oldDir, "domains.db");
|
|
28441
|
+
if (!existsSync2(oldDb))
|
|
28208
28442
|
return report;
|
|
28209
|
-
const canonicalDir =
|
|
28210
|
-
const newDb =
|
|
28211
|
-
if (
|
|
28443
|
+
const canonicalDir = join4(home, ".hasna", "domains");
|
|
28444
|
+
const newDb = join4(canonicalDir, "domains.db");
|
|
28445
|
+
if (existsSync2(newDb))
|
|
28212
28446
|
return report;
|
|
28213
|
-
if (
|
|
28447
|
+
if (existsSync2(join4(canonicalDir, ".migrated-from-xdg.receipt.json")))
|
|
28214
28448
|
return report;
|
|
28215
28449
|
if (dryRun) {
|
|
28216
28450
|
for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
|
|
28217
|
-
if (
|
|
28451
|
+
if (existsSync2(join4(oldDir, name)) && !existsSync2(join4(canonicalDir, name))) {
|
|
28218
28452
|
report.wouldCopy.push(name);
|
|
28219
28453
|
}
|
|
28220
28454
|
}
|
|
@@ -28223,11 +28457,11 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
|
28223
28457
|
mkdirSync(canonicalDir, { recursive: true });
|
|
28224
28458
|
const copied = [];
|
|
28225
28459
|
for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
|
|
28226
|
-
const from =
|
|
28227
|
-
if (!
|
|
28460
|
+
const from = join4(oldDir, name);
|
|
28461
|
+
if (!existsSync2(from))
|
|
28228
28462
|
continue;
|
|
28229
|
-
const to =
|
|
28230
|
-
if (
|
|
28463
|
+
const to = join4(canonicalDir, name);
|
|
28464
|
+
if (existsSync2(to))
|
|
28231
28465
|
continue;
|
|
28232
28466
|
copyFileSync(from, to);
|
|
28233
28467
|
copied.push({ name, bytes: statSync2(to).size, sha256: sha256File(to) });
|
|
@@ -28236,7 +28470,7 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
|
28236
28470
|
if (statSync2(newDb).size !== statSync2(oldDb).size || sha256File(newDb) !== sha256File(oldDb)) {
|
|
28237
28471
|
throw new Error(`Refusing migration: copied ${newDb} does not byte-match ${oldDb}; the canonical root was not populated.`);
|
|
28238
28472
|
}
|
|
28239
|
-
writeFileSync(
|
|
28473
|
+
writeFileSync(join4(canonicalDir, ".migrated-from-xdg.receipt.json"), `${JSON.stringify({
|
|
28240
28474
|
migratedAt: new Date().toISOString(),
|
|
28241
28475
|
from: oldDir,
|
|
28242
28476
|
to: canonicalDir,
|
|
@@ -28250,26 +28484,26 @@ function getDbPath(env = process.env) {
|
|
|
28250
28484
|
return env["DOMAINS_DB_PATH"];
|
|
28251
28485
|
if (env["HASNA_DOMAINS_DB_PATH"])
|
|
28252
28486
|
return env["HASNA_DOMAINS_DB_PATH"];
|
|
28253
|
-
const explicit = env
|
|
28487
|
+
const explicit = exactAppOverride(env);
|
|
28254
28488
|
if (explicit) {
|
|
28255
|
-
return
|
|
28489
|
+
return join4(explicit, "domains.db");
|
|
28256
28490
|
}
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
|
|
28260
|
-
|
|
28261
|
-
return
|
|
28491
|
+
if (!adoptResolverHome(resolverHome(env), env)) {
|
|
28492
|
+
migrateLegacyDataDir(env);
|
|
28493
|
+
migrateDotfile("domains", legacyHomeDir(env), env);
|
|
28494
|
+
}
|
|
28495
|
+
return getDefaultDbPath(env);
|
|
28262
28496
|
}
|
|
28263
28497
|
function migrateDotfile(name, newDir, env) {
|
|
28264
28498
|
const home = canonicalHome(env);
|
|
28265
|
-
const oldDir =
|
|
28266
|
-
if (!
|
|
28499
|
+
const oldDir = join4(home, `.${name}`);
|
|
28500
|
+
if (!existsSync2(oldDir) || existsSync2(newDir))
|
|
28267
28501
|
return;
|
|
28268
28502
|
mkdirSync(newDir, { recursive: true });
|
|
28269
28503
|
for (const file of readdirSync(oldDir)) {
|
|
28270
|
-
const oldPath =
|
|
28504
|
+
const oldPath = join4(oldDir, file);
|
|
28271
28505
|
if (statSync2(oldPath).isFile())
|
|
28272
|
-
copyFileSync(oldPath,
|
|
28506
|
+
copyFileSync(oldPath, join4(newDir, file));
|
|
28273
28507
|
}
|
|
28274
28508
|
}
|
|
28275
28509
|
function getDatabase() {
|
|
@@ -28277,7 +28511,7 @@ function getDatabase() {
|
|
|
28277
28511
|
return _db;
|
|
28278
28512
|
const dbPath = getDbPath();
|
|
28279
28513
|
if (dbPath !== ":memory:") {
|
|
28280
|
-
const dir = dirname(
|
|
28514
|
+
const dir = dirname(resolve2(dbPath));
|
|
28281
28515
|
mkdirSync(dir, { recursive: true });
|
|
28282
28516
|
}
|
|
28283
28517
|
_db = new Database(dbPath);
|
|
@@ -29168,7 +29402,7 @@ function deleteDomainReputation(id) {
|
|
|
29168
29402
|
}
|
|
29169
29403
|
|
|
29170
29404
|
// src/db/store.ts
|
|
29171
|
-
var
|
|
29405
|
+
var APP2 = "domains";
|
|
29172
29406
|
var DOMAINS_PAGE_SIZE = 1000;
|
|
29173
29407
|
class LocalStore {
|
|
29174
29408
|
transport = "local";
|
|
@@ -29781,7 +30015,7 @@ function assertNoStoreConflict(env) {
|
|
|
29781
30015
|
throw new Error(`Refusing to resolve the hosted domains store while ${pathVar} is set: that variable ` + `names a local sqlite file, so the configuration asks for BOTH stores at once and ` + `nothing here can tell which you meant. Writing to the wrong one is silent \u2014 a plain ` + `\`bun run\` script that set ${pathVar} put 230 rows into the production portfolio on ` + `2026-08-07 while reporting success. Pick one: unset HASNA_DOMAINS_API_URL and ` + `HASNA_DOMAINS_API_KEY to use ${pathVar}; unset ${pathVar} to use the hosted store; or set ` + `${ALLOW_CLOUD_WITH_LOCAL_PATH}=1 if you really intend the hosted store with that variable present.`);
|
|
29782
30016
|
}
|
|
29783
30017
|
function requireHostedClient(env, flip) {
|
|
29784
|
-
const resolved = resolveStorageClient(
|
|
30018
|
+
const resolved = resolveStorageClient(APP2, withoutRetiredModeKeys(env));
|
|
29785
30019
|
if (resolved.transport !== "http") {
|
|
29786
30020
|
throw new Error(`Hosted domains client was requested (${flip.urlSource} + ${flip.keySource}) but ` + `@hasna/contracts resolved transport '${resolved.transport}'. Refusing to read the wrong dataset.`);
|
|
29787
30021
|
}
|
|
@@ -29802,7 +30036,7 @@ import { domainToASCII } from "url";
|
|
|
29802
30036
|
|
|
29803
30037
|
// src/lib/version.ts
|
|
29804
30038
|
import { readFileSync as readFileSync3 } from "fs";
|
|
29805
|
-
import { dirname as dirname2, resolve as
|
|
30039
|
+
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
29806
30040
|
import { fileURLToPath } from "url";
|
|
29807
30041
|
var cachedVersion = null;
|
|
29808
30042
|
function getPackageVersion() {
|
|
@@ -29810,7 +30044,7 @@ function getPackageVersion() {
|
|
|
29810
30044
|
return cachedVersion;
|
|
29811
30045
|
try {
|
|
29812
30046
|
const moduleDir = dirname2(fileURLToPath(import.meta.url));
|
|
29813
|
-
const packageJsonPath =
|
|
30047
|
+
const packageJsonPath = resolve3(moduleDir, "../../package.json");
|
|
29814
30048
|
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
29815
30049
|
cachedVersion = pkg.version ?? "0.0.0";
|
|
29816
30050
|
} catch {
|
|
@@ -39466,24 +39700,24 @@ async function syncAll(dbFns) {
|
|
|
39466
39700
|
|
|
39467
39701
|
// src/lib/config.ts
|
|
39468
39702
|
import { createHash as createHash3 } from "crypto";
|
|
39469
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
39470
|
-
import { homedir as
|
|
39471
|
-
import { dirname as dirname4, join as
|
|
39703
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
39704
|
+
import { homedir as homedir5 } from "os";
|
|
39705
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
39472
39706
|
function canonicalHome2(env) {
|
|
39473
|
-
return env["HOME"] || env["USERPROFILE"] ||
|
|
39707
|
+
return env["HOME"] || env["USERPROFILE"] || homedir5();
|
|
39474
39708
|
}
|
|
39475
39709
|
function migrateLegacyConfig(env = process.env, dryRun = false) {
|
|
39476
39710
|
const report = { dryRun, wouldCopy: false, copied: false };
|
|
39477
39711
|
const home = canonicalHome2(env);
|
|
39478
|
-
const canonicalDir =
|
|
39479
|
-
const newPath =
|
|
39480
|
-
if (
|
|
39712
|
+
const canonicalDir = join6(home, ".hasna", "domains");
|
|
39713
|
+
const newPath = join6(canonicalDir, "config.json");
|
|
39714
|
+
if (existsSync3(newPath))
|
|
39481
39715
|
return report;
|
|
39482
|
-
if (
|
|
39716
|
+
if (existsSync3(join6(canonicalDir, ".migrated-from-xdg-config.receipt.json")))
|
|
39483
39717
|
return report;
|
|
39484
|
-
const xdgConfig = env["XDG_CONFIG_HOME"]?.trim() ||
|
|
39485
|
-
const oldPath =
|
|
39486
|
-
if (!
|
|
39718
|
+
const xdgConfig = env["XDG_CONFIG_HOME"]?.trim() || join6(home, ".config");
|
|
39719
|
+
const oldPath = join6(xdgConfig, "open-domains", "config.json");
|
|
39720
|
+
if (!existsSync3(oldPath))
|
|
39487
39721
|
return report;
|
|
39488
39722
|
report.wouldCopy = true;
|
|
39489
39723
|
if (dryRun)
|
|
@@ -39495,7 +39729,7 @@ function migrateLegacyConfig(env = process.env, dryRun = false) {
|
|
|
39495
39729
|
if (!oldBytes.equals(newBytes)) {
|
|
39496
39730
|
throw new Error(`Refusing migration: copied ${newPath} does not byte-match ${oldPath}; the canonical config was not populated.`);
|
|
39497
39731
|
}
|
|
39498
|
-
writeFileSync2(
|
|
39732
|
+
writeFileSync2(join6(canonicalDir, ".migrated-from-xdg-config.receipt.json"), `${JSON.stringify({
|
|
39499
39733
|
migratedAt: new Date().toISOString(),
|
|
39500
39734
|
from: oldPath,
|
|
39501
39735
|
to: newPath,
|
|
@@ -39511,13 +39745,15 @@ function getConfigPath(env = process.env) {
|
|
|
39511
39745
|
return env["DOMAINS_CONFIG_PATH"];
|
|
39512
39746
|
const dir = env["DOMAINS_CONFIG_DIR"];
|
|
39513
39747
|
if (dir)
|
|
39514
|
-
return
|
|
39515
|
-
|
|
39516
|
-
|
|
39748
|
+
return join6(dir, "config.json");
|
|
39749
|
+
if (!adoptResolverHome(resolverHome(env), env)) {
|
|
39750
|
+
migrateLegacyConfig(env);
|
|
39751
|
+
}
|
|
39752
|
+
return getDefaultConfigPath(env);
|
|
39517
39753
|
}
|
|
39518
39754
|
function loadConfig4(env = process.env) {
|
|
39519
39755
|
const path = getConfigPath(env);
|
|
39520
|
-
if (!
|
|
39756
|
+
if (!existsSync3(path))
|
|
39521
39757
|
return {};
|
|
39522
39758
|
try {
|
|
39523
39759
|
return JSON.parse(readFileSync5(path, "utf-8"));
|