@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/cli/index.js
CHANGED
|
@@ -2084,6 +2084,7 @@ var require_commander = __commonJS((exports) => {
|
|
|
2084
2084
|
// ../contracts/dist/client/storage.js
|
|
2085
2085
|
import { isIP } from "net";
|
|
2086
2086
|
import { readFileSync, statSync } from "fs";
|
|
2087
|
+
import { createRequire } from "module";
|
|
2087
2088
|
import { join } from "path";
|
|
2088
2089
|
function envToken(name) {
|
|
2089
2090
|
return name.toUpperCase().replace(/-/g, "_");
|
|
@@ -2098,24 +2099,48 @@ function clientTransportEnvKeys(name) {
|
|
|
2098
2099
|
function credentialOverrideEnvKey(name) {
|
|
2099
2100
|
return `HASNA_${envToken(name)}_API_KEY_OVERRIDE`;
|
|
2100
2101
|
}
|
|
2102
|
+
function credentialPointerEnvKey(name) {
|
|
2103
|
+
return `HASNA_${envToken(name)}_API_KEY_REF`;
|
|
2104
|
+
}
|
|
2101
2105
|
function homeDir(env) {
|
|
2102
2106
|
const home = env.HOME?.trim();
|
|
2103
2107
|
return home ? home : null;
|
|
2104
2108
|
}
|
|
2105
|
-
function
|
|
2106
|
-
return profileDiskSources(name, env, null);
|
|
2107
|
-
}
|
|
2108
|
-
function profileDiskSources(name, env, profile) {
|
|
2109
|
+
function credentialDiskSourceList(name, env, profile = null) {
|
|
2109
2110
|
const home = homeDir(env);
|
|
2110
2111
|
if (!home || !SAFE_APP_SLUG.test(name))
|
|
2111
2112
|
return [];
|
|
2112
2113
|
const stem = profile ? `${name}.${profile}` : name;
|
|
2113
2114
|
const configStem = profile ? `${name}-${profile}` : name;
|
|
2114
2115
|
return [
|
|
2115
|
-
|
|
2116
|
-
|
|
2116
|
+
{
|
|
2117
|
+
path: join(home, HASNA_STATE_DIR, FLEET_CREDENTIAL_DIR, `${stem}.env`),
|
|
2118
|
+
tier: "fleet-env",
|
|
2119
|
+
deprecated: false
|
|
2120
|
+
},
|
|
2121
|
+
{
|
|
2122
|
+
path: join(home, HASNA_STATE_DIR, LEGACY_CLOUD_DIR, `${stem}.env`),
|
|
2123
|
+
tier: "legacy-cloud",
|
|
2124
|
+
deprecated: true
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}.env`),
|
|
2128
|
+
tier: "config",
|
|
2129
|
+
deprecated: false
|
|
2130
|
+
},
|
|
2131
|
+
{
|
|
2132
|
+
path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}-cloud.env`),
|
|
2133
|
+
tier: "config-legacy",
|
|
2134
|
+
deprecated: true
|
|
2135
|
+
}
|
|
2117
2136
|
];
|
|
2118
2137
|
}
|
|
2138
|
+
function credentialDiskSources(name, env) {
|
|
2139
|
+
return credentialDiskSourceList(name, env, null).map((s) => s.path);
|
|
2140
|
+
}
|
|
2141
|
+
function profileDiskSources(name, env, profile) {
|
|
2142
|
+
return credentialDiskSourceList(name, env, profile).map((s) => s.path);
|
|
2143
|
+
}
|
|
2119
2144
|
function parseEnvFile(text) {
|
|
2120
2145
|
const values = new Map;
|
|
2121
2146
|
for (const rawLine of text.split(/\r?\n/)) {
|
|
@@ -2182,6 +2207,9 @@ function appConfigDiskValue(name, env, keys) {
|
|
|
2182
2207
|
return null;
|
|
2183
2208
|
}
|
|
2184
2209
|
function assertUsableCredential(appName, source, value) {
|
|
2210
|
+
if (VAULT_POINTER_SHAPE.test(value)) {
|
|
2211
|
+
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]);
|
|
2212
|
+
}
|
|
2185
2213
|
if (!ILLEGAL_IN_HEADER_VALUE.test(value))
|
|
2186
2214
|
return;
|
|
2187
2215
|
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]);
|
|
@@ -2203,6 +2231,14 @@ function sealCredential(fields) {
|
|
|
2203
2231
|
writable: false,
|
|
2204
2232
|
configurable: false
|
|
2205
2233
|
});
|
|
2234
|
+
if (fields.pointerVaultKey !== undefined) {
|
|
2235
|
+
Object.defineProperty(sealed, "pointerVaultKey", {
|
|
2236
|
+
value: fields.pointerVaultKey,
|
|
2237
|
+
enumerable: false,
|
|
2238
|
+
writable: false,
|
|
2239
|
+
configurable: false
|
|
2240
|
+
});
|
|
2241
|
+
}
|
|
2206
2242
|
Object.defineProperty(sealed, INSPECT_CUSTOM, {
|
|
2207
2243
|
value: () => ({ ...visible, apiKey: "[redacted]" }),
|
|
2208
2244
|
enumerable: false,
|
|
@@ -2254,7 +2290,8 @@ function validateAndSealResolvedCredential(appName, credential) {
|
|
|
2254
2290
|
deliberate: credential.deliberate,
|
|
2255
2291
|
deprecated: credential.deprecated,
|
|
2256
2292
|
diskCandidates: credential.diskCandidates,
|
|
2257
|
-
warning: credential.warning
|
|
2293
|
+
warning: credential.warning,
|
|
2294
|
+
...credential.pointerVaultKey !== undefined ? { pointerVaultKey: credential.pointerVaultKey } : {}
|
|
2258
2295
|
});
|
|
2259
2296
|
}
|
|
2260
2297
|
function firstEnvValue(env, keys) {
|
|
@@ -2314,6 +2351,27 @@ function resolveCredential(name, env, options = {}) {
|
|
|
2314
2351
|
warning: null
|
|
2315
2352
|
});
|
|
2316
2353
|
}
|
|
2354
|
+
const pointerKeyName = credentialPointerEnvKey(name);
|
|
2355
|
+
const pointerRaw = env[pointerKeyName];
|
|
2356
|
+
if (pointerRaw !== undefined) {
|
|
2357
|
+
const pointer = pointerRaw.trim();
|
|
2358
|
+
if (!pointer) {
|
|
2359
|
+
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]);
|
|
2360
|
+
}
|
|
2361
|
+
if (!VAULT_POINTER_SHAPE.test(pointer)) {
|
|
2362
|
+
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]);
|
|
2363
|
+
}
|
|
2364
|
+
return sealCredential({
|
|
2365
|
+
apiKey: "",
|
|
2366
|
+
pointerVaultKey: pointer,
|
|
2367
|
+
tier: "pointer",
|
|
2368
|
+
source: pointerKeyName,
|
|
2369
|
+
deliberate: true,
|
|
2370
|
+
deprecated: false,
|
|
2371
|
+
diskCandidates: diskPaths,
|
|
2372
|
+
warning: null
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2317
2375
|
const profile = options.profile?.trim() || env[CREDENTIAL_PROFILE_ENV_KEY]?.trim();
|
|
2318
2376
|
if (profile) {
|
|
2319
2377
|
const profileSource = options.profile?.trim() ? "explicit profile argument" : CREDENTIAL_PROFILE_ENV_KEY;
|
|
@@ -2338,26 +2396,42 @@ function resolveCredential(name, env, options = {}) {
|
|
|
2338
2396
|
}
|
|
2339
2397
|
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);
|
|
2340
2398
|
}
|
|
2341
|
-
const
|
|
2399
|
+
const diskSourceList = credentialDiskSourceList(name, env, null);
|
|
2400
|
+
const diskHits = diskSourceList.map((src) => ({ src, value: readCredentialFile(src.path, apiKeyKeys) })).filter((hit) => hit.value !== null);
|
|
2342
2401
|
if (diskHits.length > 0) {
|
|
2343
2402
|
const winner = diskHits[0];
|
|
2344
|
-
assertUsableCredential(name, winner.path, winner.value);
|
|
2403
|
+
assertUsableCredential(name, winner.src.path, winner.value);
|
|
2345
2404
|
const divergentSources = [
|
|
2346
|
-
...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.path),
|
|
2405
|
+
...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.src.path),
|
|
2347
2406
|
...(() => {
|
|
2348
2407
|
const legacyHit = firstEnvValue(env, apiKeyKeys);
|
|
2349
2408
|
return legacyHit && legacyHit.value !== winner.value ? [legacyHit.key] : [];
|
|
2350
2409
|
})()
|
|
2351
2410
|
];
|
|
2352
|
-
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;
|
|
2411
|
+
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;
|
|
2412
|
+
let deprecated = winner.src.deprecated;
|
|
2413
|
+
let finalWarning = warning;
|
|
2414
|
+
if (winner.src.deprecated) {
|
|
2415
|
+
deprecated = true;
|
|
2416
|
+
const sink = options.onDeprecation ?? defaultDeprecationSink;
|
|
2417
|
+
const notified = deprecationNotified();
|
|
2418
|
+
const noticeKey = `${name}:${winner.src.path}`;
|
|
2419
|
+
if (!notified.has(noticeKey)) {
|
|
2420
|
+
notified.add(noticeKey);
|
|
2421
|
+
const target = diskSourceList[0]?.path ?? "<none>";
|
|
2422
|
+
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.`;
|
|
2423
|
+
sink(message);
|
|
2424
|
+
}
|
|
2425
|
+
finalWarning = [warning, `Legacy credential source: ${winner.src.path}. Removed after ${LEGACY_CLOUD_REMOVAL_DEADLINE}.`].filter(Boolean).join(" ") || null;
|
|
2426
|
+
}
|
|
2353
2427
|
return sealCredential({
|
|
2354
2428
|
apiKey: winner.value,
|
|
2355
|
-
tier:
|
|
2356
|
-
source: winner.path,
|
|
2429
|
+
tier: winner.src.tier,
|
|
2430
|
+
source: winner.src.path,
|
|
2357
2431
|
deliberate: false,
|
|
2358
|
-
deprecated
|
|
2432
|
+
deprecated,
|
|
2359
2433
|
diskCandidates: diskPaths,
|
|
2360
|
-
warning
|
|
2434
|
+
warning: finalWarning
|
|
2361
2435
|
});
|
|
2362
2436
|
}
|
|
2363
2437
|
const legacy = firstEnvValue(env, apiKeyKeys);
|
|
@@ -2383,6 +2457,45 @@ function resolveCredential(name, env, options = {}) {
|
|
|
2383
2457
|
}
|
|
2384
2458
|
return null;
|
|
2385
2459
|
}
|
|
2460
|
+
async function completePointerCredential(name, pointerResolution, env = process.env) {
|
|
2461
|
+
const vaultKey = pointerResolution.pointerVaultKey;
|
|
2462
|
+
const pointerEnvKey = pointerResolution.source;
|
|
2463
|
+
if (!vaultKey) {
|
|
2464
|
+
throw new CredentialResolutionError(name, `Pointer resolution from ${pointerEnvKey} carries no vault item key; this is a defect in the resolver.`, [pointerEnvKey]);
|
|
2465
|
+
}
|
|
2466
|
+
let secretsSdk;
|
|
2467
|
+
try {
|
|
2468
|
+
secretsSdk = requireSecretsSdk(SECRETS_PACKAGE_SPECIFIER);
|
|
2469
|
+
} catch {
|
|
2470
|
+
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]);
|
|
2471
|
+
}
|
|
2472
|
+
let client;
|
|
2473
|
+
try {
|
|
2474
|
+
client = secretsSdk.createSecretsClientFromEnv(env);
|
|
2475
|
+
} catch {
|
|
2476
|
+
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]);
|
|
2477
|
+
}
|
|
2478
|
+
let secret;
|
|
2479
|
+
try {
|
|
2480
|
+
secret = await client.getSecret({ key: vaultKey });
|
|
2481
|
+
} catch {
|
|
2482
|
+
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]);
|
|
2483
|
+
}
|
|
2484
|
+
const value = secret.value;
|
|
2485
|
+
if (!value) {
|
|
2486
|
+
throw new CredentialResolutionError(name, `${pointerEnvKey} resolved vault item '${vaultKey}', but it holds no value. A vault pointer is TERMINAL.`, [pointerEnvKey]);
|
|
2487
|
+
}
|
|
2488
|
+
assertUsableCredential(name, `${pointerEnvKey} -> vault:${vaultKey}`, value);
|
|
2489
|
+
return sealCredential({
|
|
2490
|
+
apiKey: value,
|
|
2491
|
+
tier: "pointer",
|
|
2492
|
+
source: `${pointerEnvKey} -> vault:${vaultKey}`,
|
|
2493
|
+
deliberate: true,
|
|
2494
|
+
deprecated: false,
|
|
2495
|
+
diskCandidates: pointerResolution.diskCandidates,
|
|
2496
|
+
warning: null
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2386
2499
|
function isValidDnsDomain(value) {
|
|
2387
2500
|
if (value.length === 0 || value.length > 253 || ASCII_CONTROL_PATTERN.test(value) || /[^\x00-\x7f]/.test(value)) {
|
|
2388
2501
|
return false;
|
|
@@ -2606,6 +2719,13 @@ function currentCredential(name, apiKey) {
|
|
|
2606
2719
|
}
|
|
2607
2720
|
return explicitCredential(name, apiKey);
|
|
2608
2721
|
}
|
|
2722
|
+
async function resolveRequestCredential(name, apiKey, env = process.env) {
|
|
2723
|
+
const resolved = currentCredential(name, apiKey);
|
|
2724
|
+
if (resolved.tier === "pointer") {
|
|
2725
|
+
return completePointerCredential(name, resolved, env);
|
|
2726
|
+
}
|
|
2727
|
+
return resolved;
|
|
2728
|
+
}
|
|
2609
2729
|
function authFailureGuidance(credential) {
|
|
2610
2730
|
const origin = `The API key for this request came from ${credential.source}`;
|
|
2611
2731
|
if (credential.deliberate) {
|
|
@@ -2751,7 +2871,7 @@ function createHasnaHttpTransport(options) {
|
|
|
2751
2871
|
const retry = resolveRetry(opts.retry);
|
|
2752
2872
|
const methodRetryable = IDEMPOTENT_METHODS.has(upper) || Boolean(opts.idempotencyKey);
|
|
2753
2873
|
const maxAttempts = retry && methodRetryable ? retry.retries + 1 : 1;
|
|
2754
|
-
const credential =
|
|
2874
|
+
const credential = await resolveRequestCredential(options.name, options.apiKey);
|
|
2755
2875
|
let last = null;
|
|
2756
2876
|
for (let attempt = 1;attempt <= maxAttempts; attempt++) {
|
|
2757
2877
|
const result = await once(upper, rel, url, body, opts, credential);
|
|
@@ -2914,7 +3034,7 @@ function resolveStorageClient(name, env = process.env, overrides) {
|
|
|
2914
3034
|
}
|
|
2915
3035
|
return { transport: "sqlite", client: null };
|
|
2916
3036
|
}
|
|
2917
|
-
var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE", CredentialResolutionError, HASNA_STATE_DIR = ".hasna", FLEET_CREDENTIAL_DIR = "cloud", CONFIG_DIR = ".config", CONFIG_NAMESPACE = "hasna", MAX_CREDENTIAL_FILE_BYTES, SAFE_APP_SLUG, SAFE_PROFILE, ILLEGAL_IN_HEADER_VALUE, CREDENTIAL_SHAPED_KEY, INSPECT_CUSTOM, CREDENTIAL_SEAL, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", DEPRECATION_REGISTRY, ASCII_CONTROL_PATTERN, DNS_LABEL_PATTERN, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS, AUTHORITY_OVERRIDE_HEADERS, defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
3037
|
+
var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE", CredentialResolutionError, HASNA_STATE_DIR = ".hasna", FLEET_CREDENTIAL_DIR = "fleet-env", LEGACY_CLOUD_DIR = "cloud", CONFIG_DIR = ".config", CONFIG_NAMESPACE = "hasna", LEGACY_CLOUD_REMOVAL_DEADLINE = "2026-10-01", MAX_CREDENTIAL_FILE_BYTES, SAFE_APP_SLUG, SAFE_PROFILE, ILLEGAL_IN_HEADER_VALUE, VAULT_POINTER_SHAPE, CREDENTIAL_SHAPED_KEY, INSPECT_CUSTOM, CREDENTIAL_SEAL, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", DEPRECATION_REGISTRY, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk, ASCII_CONTROL_PATTERN, DNS_LABEL_PATTERN, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS, AUTHORITY_OVERRIDE_HEADERS, defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2918
3038
|
var init_storage = __esm(() => {
|
|
2919
3039
|
CredentialResolutionError = class CredentialResolutionError extends Error {
|
|
2920
3040
|
appName;
|
|
@@ -2930,10 +3050,13 @@ var init_storage = __esm(() => {
|
|
|
2930
3050
|
SAFE_APP_SLUG = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
2931
3051
|
SAFE_PROFILE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
2932
3052
|
ILLEGAL_IN_HEADER_VALUE = /[^\t\x20-\x7e]/;
|
|
3053
|
+
VAULT_POINTER_SHAPE = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-_.]*){2,}$/;
|
|
2933
3054
|
CREDENTIAL_SHAPED_KEY = /(?:^|_)(?:API_KEY|KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|AUTH)(?:_|$)/;
|
|
2934
3055
|
INSPECT_CUSTOM = Symbol.for("nodejs.util.inspect.custom");
|
|
2935
3056
|
CREDENTIAL_SEAL = Symbol.for("hasna:contracts:sealedCredential");
|
|
2936
3057
|
DEPRECATION_REGISTRY = Symbol.for("hasna:contracts:credentialDeprecationNotices");
|
|
3058
|
+
SECRETS_PACKAGE_SPECIFIER = "@hasna/" + "secrets";
|
|
3059
|
+
requireSecretsSdk = createRequire(import.meta.url);
|
|
2937
3060
|
ASCII_CONTROL_PATTERN = /[\u0000-\u001f\u007f]/;
|
|
2938
3061
|
DNS_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
2939
3062
|
HasnaHttpError = class HasnaHttpError extends Error {
|
|
@@ -2967,6 +3090,7 @@ var init_storage = __esm(() => {
|
|
|
2967
3090
|
});
|
|
2968
3091
|
|
|
2969
3092
|
// ../contracts/dist/client/transport.js
|
|
3093
|
+
import { createRequire as createRequire2 } from "module";
|
|
2970
3094
|
function envToken2(name) {
|
|
2971
3095
|
return name.toUpperCase().replace(/-/g, "_");
|
|
2972
3096
|
}
|
|
@@ -2977,12 +3101,14 @@ function clientTransportEnvKeys2(name) {
|
|
|
2977
3101
|
apiKeyKeys: [`HASNA_${envSegment}_API_KEY`, `${envSegment}_API_KEY`]
|
|
2978
3102
|
};
|
|
2979
3103
|
}
|
|
2980
|
-
var MAX_CREDENTIAL_FILE_BYTES2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, DEPRECATION_REGISTRY2, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2;
|
|
3104
|
+
var MAX_CREDENTIAL_FILE_BYTES2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, DEPRECATION_REGISTRY2, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk2, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2;
|
|
2981
3105
|
var init_transport = __esm(() => {
|
|
2982
3106
|
MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
|
|
2983
3107
|
INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
|
|
2984
3108
|
CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
|
|
2985
3109
|
DEPRECATION_REGISTRY2 = Symbol.for("hasna:contracts:credentialDeprecationNotices");
|
|
3110
|
+
SECRETS_PACKAGE_SPECIFIER2 = "@hasna/" + "secrets";
|
|
3111
|
+
requireSecretsSdk2 = createRequire2(import.meta.url);
|
|
2986
3112
|
IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
2987
3113
|
AUTHORITY_OVERRIDE_HEADERS2 = new Set([
|
|
2988
3114
|
"host",
|
|
@@ -3263,22 +3389,132 @@ var init_migrations = __esm(() => {
|
|
|
3263
3389
|
];
|
|
3264
3390
|
});
|
|
3265
3391
|
|
|
3392
|
+
// ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
|
|
3393
|
+
import { homedir } from "os";
|
|
3394
|
+
import { join as join2 } from "path";
|
|
3395
|
+
function assertApp(app) {
|
|
3396
|
+
if (typeof app !== "string" || app.length === 0) {
|
|
3397
|
+
throw new TypeError("paths: app must be a non-empty string");
|
|
3398
|
+
}
|
|
3399
|
+
if (!APP_SLUG_RE.test(app)) {
|
|
3400
|
+
throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
function envOf(options) {
|
|
3404
|
+
return options.env ?? process.env;
|
|
3405
|
+
}
|
|
3406
|
+
function envValue(options, kind) {
|
|
3407
|
+
const value = envOf(options)[KIND_ENV[kind]];
|
|
3408
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
3409
|
+
}
|
|
3410
|
+
function isMacOS(platform) {
|
|
3411
|
+
return platform === "darwin";
|
|
3412
|
+
}
|
|
3413
|
+
function baseDir(kind, options) {
|
|
3414
|
+
const override = envValue(options, kind);
|
|
3415
|
+
if (override)
|
|
3416
|
+
return override;
|
|
3417
|
+
const home = options.home ?? homedir();
|
|
3418
|
+
const platform = options.platform ?? process.platform;
|
|
3419
|
+
if (isMacOS(platform)) {
|
|
3420
|
+
switch (kind) {
|
|
3421
|
+
case "config":
|
|
3422
|
+
case "data":
|
|
3423
|
+
return join2(home, "Library", "Application Support", "Hasna");
|
|
3424
|
+
case "cache":
|
|
3425
|
+
return join2(home, "Library", "Caches", "Hasna");
|
|
3426
|
+
case "state":
|
|
3427
|
+
return join2(home, "Library", "Logs", "Hasna");
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
switch (kind) {
|
|
3431
|
+
case "config":
|
|
3432
|
+
return join2(home, ".config", "hasna");
|
|
3433
|
+
case "data":
|
|
3434
|
+
return join2(home, ".local", "share", "hasna");
|
|
3435
|
+
case "state":
|
|
3436
|
+
return join2(home, ".local", "state", "hasna");
|
|
3437
|
+
case "cache":
|
|
3438
|
+
return join2(home, ".cache", "hasna");
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
function resolvePath(kind, options) {
|
|
3442
|
+
assertApp(options.app);
|
|
3443
|
+
const appSegment = options.internal === true ? join2("internal", options.app) : options.app;
|
|
3444
|
+
return join2(baseDir(kind, options), appSegment);
|
|
3445
|
+
}
|
|
3446
|
+
function dataDir(options) {
|
|
3447
|
+
return resolvePath("data", options);
|
|
3448
|
+
}
|
|
3449
|
+
var KIND_ENV, APP_SLUG_RE;
|
|
3450
|
+
var init_dist = __esm(() => {
|
|
3451
|
+
KIND_ENV = {
|
|
3452
|
+
config: "HASNA_CONFIG_HOME",
|
|
3453
|
+
data: "HASNA_DATA_HOME",
|
|
3454
|
+
state: "HASNA_STATE_HOME",
|
|
3455
|
+
cache: "HASNA_CACHE_HOME"
|
|
3456
|
+
};
|
|
3457
|
+
APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3458
|
+
});
|
|
3459
|
+
|
|
3460
|
+
// src/lib/app-home.ts
|
|
3461
|
+
import { existsSync } from "fs";
|
|
3462
|
+
import { homedir as homedir2 } from "os";
|
|
3463
|
+
import { join as join3, resolve } from "path";
|
|
3464
|
+
function effectiveHome(env = process.env) {
|
|
3465
|
+
return env["HOME"] || env["USERPROFILE"] || homedir2();
|
|
3466
|
+
}
|
|
3467
|
+
function legacyHomeDir(env = process.env) {
|
|
3468
|
+
return join3(effectiveHome(env), ".hasna", APP);
|
|
3469
|
+
}
|
|
3470
|
+
function resolverHome(env = process.env) {
|
|
3471
|
+
const home = env["HOME"] || env["USERPROFILE"];
|
|
3472
|
+
return dataDir({ app: APP, home, env });
|
|
3473
|
+
}
|
|
3474
|
+
function adoptResolverHome(resolved, env = process.env) {
|
|
3475
|
+
const dataOverride = env.HASNA_DATA_HOME;
|
|
3476
|
+
if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
|
|
3477
|
+
return true;
|
|
3478
|
+
return existsSync(join3(resolved, "domains.db"));
|
|
3479
|
+
}
|
|
3480
|
+
function exactAppOverride(env = process.env) {
|
|
3481
|
+
const override = env["HASNA_DOMAINS_HOME"] ?? env["DOMAINS_HOME"] ?? env["HASNA_DOMAINS_DIR"] ?? env["DOMAINS_DIR"];
|
|
3482
|
+
return override && override.trim() ? override.trim() : undefined;
|
|
3483
|
+
}
|
|
3484
|
+
function appHome(env = process.env) {
|
|
3485
|
+
const override = exactAppOverride(env);
|
|
3486
|
+
if (override)
|
|
3487
|
+
return resolve(override);
|
|
3488
|
+
const resolved = resolverHome(env);
|
|
3489
|
+
return adoptResolverHome(resolved, env) ? resolve(resolved) : resolve(legacyHomeDir(env));
|
|
3490
|
+
}
|
|
3491
|
+
function getDefaultDbPath(env = process.env) {
|
|
3492
|
+
return join3(appHome(env), `${APP}.db`);
|
|
3493
|
+
}
|
|
3494
|
+
function getDefaultConfigPath(env = process.env) {
|
|
3495
|
+
return join3(appHome(env), "config.json");
|
|
3496
|
+
}
|
|
3497
|
+
var APP = "domains";
|
|
3498
|
+
var init_app_home = __esm(() => {
|
|
3499
|
+
init_dist();
|
|
3500
|
+
});
|
|
3501
|
+
|
|
3266
3502
|
// src/db/database.ts
|
|
3267
3503
|
import { Database } from "bun:sqlite";
|
|
3268
3504
|
import { createHash } from "crypto";
|
|
3269
3505
|
import {
|
|
3270
3506
|
copyFileSync,
|
|
3271
|
-
existsSync,
|
|
3507
|
+
existsSync as existsSync2,
|
|
3272
3508
|
mkdirSync,
|
|
3273
3509
|
readFileSync as readFileSync2,
|
|
3274
3510
|
readdirSync,
|
|
3275
3511
|
statSync as statSync2,
|
|
3276
3512
|
writeFileSync
|
|
3277
3513
|
} from "fs";
|
|
3278
|
-
import { dirname, join as
|
|
3279
|
-
import { homedir } from "os";
|
|
3514
|
+
import { dirname, join as join4, resolve as resolve2 } from "path";
|
|
3515
|
+
import { homedir as homedir3 } from "os";
|
|
3280
3516
|
function canonicalHome(env) {
|
|
3281
|
-
return env["HOME"] || env["USERPROFILE"] ||
|
|
3517
|
+
return env["HOME"] || env["USERPROFILE"] || homedir3();
|
|
3282
3518
|
}
|
|
3283
3519
|
function sha256File(path) {
|
|
3284
3520
|
return createHash("sha256").update(readFileSync2(path)).digest("hex");
|
|
@@ -3286,20 +3522,20 @@ function sha256File(path) {
|
|
|
3286
3522
|
function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
3287
3523
|
const report = { dryRun, wouldCopy: [], copied: [] };
|
|
3288
3524
|
const home = canonicalHome(env);
|
|
3289
|
-
const xdgData = env["XDG_DATA_HOME"]?.trim() ||
|
|
3290
|
-
const oldDir =
|
|
3291
|
-
const oldDb =
|
|
3292
|
-
if (!
|
|
3525
|
+
const xdgData = env["XDG_DATA_HOME"]?.trim() || join4(home, ".local", "share");
|
|
3526
|
+
const oldDir = join4(xdgData, "open-domains");
|
|
3527
|
+
const oldDb = join4(oldDir, "domains.db");
|
|
3528
|
+
if (!existsSync2(oldDb))
|
|
3293
3529
|
return report;
|
|
3294
|
-
const canonicalDir =
|
|
3295
|
-
const newDb =
|
|
3296
|
-
if (
|
|
3530
|
+
const canonicalDir = join4(home, ".hasna", "domains");
|
|
3531
|
+
const newDb = join4(canonicalDir, "domains.db");
|
|
3532
|
+
if (existsSync2(newDb))
|
|
3297
3533
|
return report;
|
|
3298
|
-
if (
|
|
3534
|
+
if (existsSync2(join4(canonicalDir, ".migrated-from-xdg.receipt.json")))
|
|
3299
3535
|
return report;
|
|
3300
3536
|
if (dryRun) {
|
|
3301
3537
|
for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
|
|
3302
|
-
if (
|
|
3538
|
+
if (existsSync2(join4(oldDir, name)) && !existsSync2(join4(canonicalDir, name))) {
|
|
3303
3539
|
report.wouldCopy.push(name);
|
|
3304
3540
|
}
|
|
3305
3541
|
}
|
|
@@ -3308,11 +3544,11 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
|
3308
3544
|
mkdirSync(canonicalDir, { recursive: true });
|
|
3309
3545
|
const copied = [];
|
|
3310
3546
|
for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
|
|
3311
|
-
const from =
|
|
3312
|
-
if (!
|
|
3547
|
+
const from = join4(oldDir, name);
|
|
3548
|
+
if (!existsSync2(from))
|
|
3313
3549
|
continue;
|
|
3314
|
-
const to =
|
|
3315
|
-
if (
|
|
3550
|
+
const to = join4(canonicalDir, name);
|
|
3551
|
+
if (existsSync2(to))
|
|
3316
3552
|
continue;
|
|
3317
3553
|
copyFileSync(from, to);
|
|
3318
3554
|
copied.push({ name, bytes: statSync2(to).size, sha256: sha256File(to) });
|
|
@@ -3321,7 +3557,7 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
|
|
|
3321
3557
|
if (statSync2(newDb).size !== statSync2(oldDb).size || sha256File(newDb) !== sha256File(oldDb)) {
|
|
3322
3558
|
throw new Error(`Refusing migration: copied ${newDb} does not byte-match ${oldDb}; the canonical root was not populated.`);
|
|
3323
3559
|
}
|
|
3324
|
-
writeFileSync(
|
|
3560
|
+
writeFileSync(join4(canonicalDir, ".migrated-from-xdg.receipt.json"), `${JSON.stringify({
|
|
3325
3561
|
migratedAt: new Date().toISOString(),
|
|
3326
3562
|
from: oldDir,
|
|
3327
3563
|
to: canonicalDir,
|
|
@@ -3335,26 +3571,26 @@ function getDbPath(env = process.env) {
|
|
|
3335
3571
|
return env["DOMAINS_DB_PATH"];
|
|
3336
3572
|
if (env["HASNA_DOMAINS_DB_PATH"])
|
|
3337
3573
|
return env["HASNA_DOMAINS_DB_PATH"];
|
|
3338
|
-
const explicit = env
|
|
3574
|
+
const explicit = exactAppOverride(env);
|
|
3339
3575
|
if (explicit) {
|
|
3340
|
-
return
|
|
3576
|
+
return join4(explicit, "domains.db");
|
|
3341
3577
|
}
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
return
|
|
3578
|
+
if (!adoptResolverHome(resolverHome(env), env)) {
|
|
3579
|
+
migrateLegacyDataDir(env);
|
|
3580
|
+
migrateDotfile("domains", legacyHomeDir(env), env);
|
|
3581
|
+
}
|
|
3582
|
+
return getDefaultDbPath(env);
|
|
3347
3583
|
}
|
|
3348
3584
|
function migrateDotfile(name, newDir, env) {
|
|
3349
3585
|
const home = canonicalHome(env);
|
|
3350
|
-
const oldDir =
|
|
3351
|
-
if (!
|
|
3586
|
+
const oldDir = join4(home, `.${name}`);
|
|
3587
|
+
if (!existsSync2(oldDir) || existsSync2(newDir))
|
|
3352
3588
|
return;
|
|
3353
3589
|
mkdirSync(newDir, { recursive: true });
|
|
3354
3590
|
for (const file of readdirSync(oldDir)) {
|
|
3355
|
-
const oldPath =
|
|
3591
|
+
const oldPath = join4(oldDir, file);
|
|
3356
3592
|
if (statSync2(oldPath).isFile())
|
|
3357
|
-
copyFileSync(oldPath,
|
|
3593
|
+
copyFileSync(oldPath, join4(newDir, file));
|
|
3358
3594
|
}
|
|
3359
3595
|
}
|
|
3360
3596
|
function getDatabase() {
|
|
@@ -3362,7 +3598,7 @@ function getDatabase() {
|
|
|
3362
3598
|
return _db;
|
|
3363
3599
|
const dbPath = getDbPath();
|
|
3364
3600
|
if (dbPath !== ":memory:") {
|
|
3365
|
-
const dir = dirname(
|
|
3601
|
+
const dir = dirname(resolve2(dbPath));
|
|
3366
3602
|
mkdirSync(dir, { recursive: true });
|
|
3367
3603
|
}
|
|
3368
3604
|
_db = new Database(dbPath);
|
|
@@ -3395,6 +3631,7 @@ function getDatabase() {
|
|
|
3395
3631
|
var _db = null;
|
|
3396
3632
|
var init_database = __esm(() => {
|
|
3397
3633
|
init_migrations();
|
|
3634
|
+
init_app_home();
|
|
3398
3635
|
});
|
|
3399
3636
|
|
|
3400
3637
|
// src/db/domain-records.ts
|
|
@@ -4898,7 +5135,7 @@ function assertNoStoreConflict(env) {
|
|
|
4898
5135
|
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.`);
|
|
4899
5136
|
}
|
|
4900
5137
|
function requireHostedClient(env, flip) {
|
|
4901
|
-
const resolved = resolveStorageClient(
|
|
5138
|
+
const resolved = resolveStorageClient(APP2, withoutRetiredModeKeys(env));
|
|
4902
5139
|
if (resolved.transport !== "http") {
|
|
4903
5140
|
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.`);
|
|
4904
5141
|
}
|
|
@@ -4923,7 +5160,7 @@ function isCloudStore(env = process.env) {
|
|
|
4923
5160
|
requireHostedClient(env, flip);
|
|
4924
5161
|
return true;
|
|
4925
5162
|
}
|
|
4926
|
-
var
|
|
5163
|
+
var APP2 = "domains", DOMAINS_PAGE_SIZE = 1000, RETIRED_MODE_KEYS, ALLOW_CLOUD_IN_TESTS = "HASNA_DOMAINS_ALLOW_CLOUD_IN_TESTS", ALLOW_CLOUD_WITH_LOCAL_PATH = "HASNA_DOMAINS_ALLOW_CLOUD_WITH_LOCAL_PATH", LOCAL_PATH_VARS, warnedCloudDowngrade = false;
|
|
4927
5164
|
var init_store = __esm(() => {
|
|
4928
5165
|
init_storage();
|
|
4929
5166
|
init_transport();
|
|
@@ -4949,14 +5186,14 @@ var init_store = __esm(() => {
|
|
|
4949
5186
|
|
|
4950
5187
|
// src/lib/version.ts
|
|
4951
5188
|
import { readFileSync as readFileSync3 } from "fs";
|
|
4952
|
-
import { dirname as dirname2, resolve as
|
|
5189
|
+
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
4953
5190
|
import { fileURLToPath } from "url";
|
|
4954
5191
|
function getPackageVersion() {
|
|
4955
5192
|
if (cachedVersion)
|
|
4956
5193
|
return cachedVersion;
|
|
4957
5194
|
try {
|
|
4958
5195
|
const moduleDir = dirname2(fileURLToPath(import.meta.url));
|
|
4959
|
-
const packageJsonPath =
|
|
5196
|
+
const packageJsonPath = resolve3(moduleDir, "../../package.json");
|
|
4960
5197
|
const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
|
|
4961
5198
|
cachedVersion = pkg.version ?? "0.0.0";
|
|
4962
5199
|
} catch {
|
|
@@ -7188,7 +7425,7 @@ var require_client = __commonJS((exports) => {
|
|
|
7188
7425
|
};
|
|
7189
7426
|
};
|
|
7190
7427
|
var sleep = (seconds) => {
|
|
7191
|
-
return new Promise((
|
|
7428
|
+
return new Promise((resolve4) => setTimeout(resolve4, seconds * 1000));
|
|
7192
7429
|
};
|
|
7193
7430
|
var waiterServiceDefaults = {
|
|
7194
7431
|
minDelay: 2,
|
|
@@ -7317,8 +7554,8 @@ var require_client = __commonJS((exports) => {
|
|
|
7317
7554
|
};
|
|
7318
7555
|
var abortTimeout = (abortSignal) => {
|
|
7319
7556
|
let onAbort;
|
|
7320
|
-
const promise = new Promise((
|
|
7321
|
-
onAbort = () =>
|
|
7557
|
+
const promise = new Promise((resolve4) => {
|
|
7558
|
+
onAbort = () => resolve4({ state: WaiterState.ABORTED });
|
|
7322
7559
|
if (typeof abortSignal.addEventListener === "function") {
|
|
7323
7560
|
abortSignal.addEventListener("abort", onAbort);
|
|
7324
7561
|
} else {
|
|
@@ -7971,8 +8208,8 @@ var require_client = __commonJS((exports) => {
|
|
|
7971
8208
|
|
|
7972
8209
|
// ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/config/index.js
|
|
7973
8210
|
var require_config = __commonJS((exports) => {
|
|
7974
|
-
var { homedir:
|
|
7975
|
-
var { sep, join:
|
|
8211
|
+
var { homedir: homedir4 } = __require("os");
|
|
8212
|
+
var { sep, join: join5 } = __require("path");
|
|
7976
8213
|
var { createHash: createHash2 } = __require("crypto");
|
|
7977
8214
|
var { readFile: readFile$1 } = __require("fs/promises");
|
|
7978
8215
|
var { IniSectionType } = require_dist_cjs();
|
|
@@ -8121,7 +8358,7 @@ var require_config = __commonJS((exports) => {
|
|
|
8121
8358
|
return `${HOMEDRIVE}${HOMEPATH}`;
|
|
8122
8359
|
const homeDirCacheKey = getHomeDirCacheKey();
|
|
8123
8360
|
if (!homeDirCache[homeDirCacheKey])
|
|
8124
|
-
homeDirCache[homeDirCacheKey] =
|
|
8361
|
+
homeDirCache[homeDirCacheKey] = homedir4();
|
|
8125
8362
|
return homeDirCache[homeDirCacheKey];
|
|
8126
8363
|
};
|
|
8127
8364
|
var ENV_PROFILE = "AWS_PROFILE";
|
|
@@ -8130,7 +8367,7 @@ var require_config = __commonJS((exports) => {
|
|
|
8130
8367
|
var getSSOTokenFilepath = (id) => {
|
|
8131
8368
|
const hasher = createHash2("sha1");
|
|
8132
8369
|
const cacheName = hasher.update(id).digest("hex");
|
|
8133
|
-
return
|
|
8370
|
+
return join5(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
|
|
8134
8371
|
};
|
|
8135
8372
|
var tokenIntercept = {};
|
|
8136
8373
|
var getSSOTokenFromFile = async (id) => {
|
|
@@ -8157,9 +8394,9 @@ var require_config = __commonJS((exports) => {
|
|
|
8157
8394
|
...data.default && { default: data.default }
|
|
8158
8395
|
});
|
|
8159
8396
|
var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
8160
|
-
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] ||
|
|
8397
|
+
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || join5(getHomeDir(), ".aws", "config");
|
|
8161
8398
|
var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
8162
|
-
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] ||
|
|
8399
|
+
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || join5(getHomeDir(), ".aws", "credentials");
|
|
8163
8400
|
var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@+.%:/]+)\2$/;
|
|
8164
8401
|
var profileNameBlockList = ["__proto__", "profile __proto__"];
|
|
8165
8402
|
var parseIni = (iniData) => {
|
|
@@ -8225,11 +8462,11 @@ var require_config = __commonJS((exports) => {
|
|
|
8225
8462
|
const relativeHomeDirPrefix = "~/";
|
|
8226
8463
|
let resolvedFilepath = filepath;
|
|
8227
8464
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
8228
|
-
resolvedFilepath =
|
|
8465
|
+
resolvedFilepath = join5(homeDir2, filepath.slice(2));
|
|
8229
8466
|
}
|
|
8230
8467
|
let resolvedConfigFilepath = configFilepath;
|
|
8231
8468
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
8232
|
-
resolvedConfigFilepath =
|
|
8469
|
+
resolvedConfigFilepath = join5(homeDir2, configFilepath.slice(2));
|
|
8233
8470
|
}
|
|
8234
8471
|
const parsedFiles = await Promise.all([
|
|
8235
8472
|
readFile(resolvedConfigFilepath, {
|
|
@@ -8446,7 +8683,7 @@ var require_config = __commonJS((exports) => {
|
|
|
8446
8683
|
};
|
|
8447
8684
|
var imdsRequest = async (options) => {
|
|
8448
8685
|
const { request } = __require("http");
|
|
8449
|
-
return new Promise((
|
|
8686
|
+
return new Promise((resolve4, reject) => {
|
|
8450
8687
|
const req = request({
|
|
8451
8688
|
hostname: options.hostname,
|
|
8452
8689
|
port: options.port,
|
|
@@ -8474,7 +8711,7 @@ var require_config = __commonJS((exports) => {
|
|
|
8474
8711
|
const chunks = [];
|
|
8475
8712
|
res.on("data", (chunk) => chunks.push(chunk));
|
|
8476
8713
|
res.on("end", () => {
|
|
8477
|
-
|
|
8714
|
+
resolve4(Buffer.concat(chunks));
|
|
8478
8715
|
req.destroy();
|
|
8479
8716
|
});
|
|
8480
8717
|
});
|
|
@@ -10825,7 +11062,7 @@ ${value}\r
|
|
|
10825
11062
|
if (isReadableStream(stream)) {
|
|
10826
11063
|
return headStream$1(stream, bytes);
|
|
10827
11064
|
}
|
|
10828
|
-
return new Promise((
|
|
11065
|
+
return new Promise((resolve4, reject) => {
|
|
10829
11066
|
const collector = new Collector$1;
|
|
10830
11067
|
collector.limit = bytes;
|
|
10831
11068
|
stream.pipe(collector);
|
|
@@ -10836,7 +11073,7 @@ ${value}\r
|
|
|
10836
11073
|
collector.on("error", reject);
|
|
10837
11074
|
collector.on("finish", function() {
|
|
10838
11075
|
const bytes2 = concatBytes(this.buffers);
|
|
10839
|
-
|
|
11076
|
+
resolve4(bytes2);
|
|
10840
11077
|
});
|
|
10841
11078
|
});
|
|
10842
11079
|
};
|
|
@@ -10950,7 +11187,7 @@ ${value}\r
|
|
|
10950
11187
|
if (isReadableStream(stream)) {
|
|
10951
11188
|
return collectReadableStream(stream);
|
|
10952
11189
|
}
|
|
10953
|
-
return new Promise((
|
|
11190
|
+
return new Promise((resolve4, reject) => {
|
|
10954
11191
|
const collector = new Collector;
|
|
10955
11192
|
const nodeStream = stream;
|
|
10956
11193
|
nodeStream.pipe(collector);
|
|
@@ -10961,7 +11198,7 @@ ${value}\r
|
|
|
10961
11198
|
collector.on("error", reject);
|
|
10962
11199
|
collector.on("finish", function() {
|
|
10963
11200
|
const bytes = concatBytes(this.bufferedBytes);
|
|
10964
|
-
|
|
11201
|
+
resolve4(bytes);
|
|
10965
11202
|
});
|
|
10966
11203
|
});
|
|
10967
11204
|
};
|
|
@@ -11153,7 +11390,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
11153
11390
|
callback();
|
|
11154
11391
|
}
|
|
11155
11392
|
}
|
|
11156
|
-
var fileStreamHasher = (hashCtor, fileStream) => new Promise((
|
|
11393
|
+
var fileStreamHasher = (hashCtor, fileStream) => new Promise((resolve4, reject) => {
|
|
11157
11394
|
if (!isReadStream(fileStream)) {
|
|
11158
11395
|
reject(new Error("Unable to calculate hash for non-file streams."));
|
|
11159
11396
|
return;
|
|
@@ -11171,7 +11408,7 @@ var require_checksum = __commonJS((exports) => {
|
|
|
11171
11408
|
});
|
|
11172
11409
|
hashCalculator.on("error", reject);
|
|
11173
11410
|
hashCalculator.on("finish", function() {
|
|
11174
|
-
hash.digest().then(
|
|
11411
|
+
hash.digest().then(resolve4).catch(reject);
|
|
11175
11412
|
});
|
|
11176
11413
|
});
|
|
11177
11414
|
var isReadStream = (stream) => typeof stream.path === "string";
|
|
@@ -11182,14 +11419,14 @@ var require_checksum = __commonJS((exports) => {
|
|
|
11182
11419
|
const hash = new hashCtor;
|
|
11183
11420
|
const hashCalculator = new HashCalculator(hash);
|
|
11184
11421
|
readableStream.pipe(hashCalculator);
|
|
11185
|
-
return new Promise((
|
|
11422
|
+
return new Promise((resolve4, reject) => {
|
|
11186
11423
|
readableStream.on("error", (err) => {
|
|
11187
11424
|
hashCalculator.end();
|
|
11188
11425
|
reject(err);
|
|
11189
11426
|
});
|
|
11190
11427
|
hashCalculator.on("error", reject);
|
|
11191
11428
|
hashCalculator.on("finish", () => {
|
|
11192
|
-
hash.digest().then(
|
|
11429
|
+
hash.digest().then(resolve4).catch(reject);
|
|
11193
11430
|
});
|
|
11194
11431
|
});
|
|
11195
11432
|
};
|
|
@@ -12295,7 +12532,7 @@ var require_event_streams = __commonJS((exports) => {
|
|
|
12295
12532
|
streamEnded = true;
|
|
12296
12533
|
});
|
|
12297
12534
|
while (!generationEnded) {
|
|
12298
|
-
const value = await new Promise((
|
|
12535
|
+
const value = await new Promise((resolve4) => setTimeout(() => resolve4(records.shift()), 0));
|
|
12299
12536
|
if (value) {
|
|
12300
12537
|
yield value;
|
|
12301
12538
|
}
|
|
@@ -13175,8 +13412,8 @@ var require_protocols = __commonJS((exports) => {
|
|
|
13175
13412
|
async build() {
|
|
13176
13413
|
const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
|
|
13177
13414
|
this.path = basePath;
|
|
13178
|
-
for (const
|
|
13179
|
-
|
|
13415
|
+
for (const resolvePath2 of this.resolvePathStack) {
|
|
13416
|
+
resolvePath2(this.path);
|
|
13180
13417
|
}
|
|
13181
13418
|
return new HttpRequest({
|
|
13182
13419
|
protocol,
|
|
@@ -13790,7 +14027,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
13790
14027
|
}
|
|
13791
14028
|
};
|
|
13792
14029
|
}
|
|
13793
|
-
var cooldown = (ms) => new Promise((
|
|
14030
|
+
var cooldown = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
13794
14031
|
var isRetryStrategyV2 = (retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" && typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" && typeof retryStrategy.recordSuccess !== "undefined";
|
|
13795
14032
|
var getRetryErrorInfo = (error, logger) => {
|
|
13796
14033
|
const errorInfo = {
|
|
@@ -13889,7 +14126,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
13889
14126
|
this.refillTokenBucket();
|
|
13890
14127
|
while (amount > this.availableTokens) {
|
|
13891
14128
|
const delay = (amount - this.availableTokens) / this.fillRate * 1000;
|
|
13892
|
-
await new Promise((
|
|
14129
|
+
await new Promise((resolve4) => DefaultRateLimiter.setTimeoutFn(resolve4, delay));
|
|
13893
14130
|
this.refillTokenBucket();
|
|
13894
14131
|
}
|
|
13895
14132
|
this.availableTokens = this.availableTokens - amount;
|
|
@@ -14231,7 +14468,7 @@ var require_retry = __commonJS((exports) => {
|
|
|
14231
14468
|
const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
|
|
14232
14469
|
const delay = Math.max(delayFromResponse || 0, delayFromDecider);
|
|
14233
14470
|
totalDelay += delay;
|
|
14234
|
-
await new Promise((
|
|
14471
|
+
await new Promise((resolve4) => setTimeout(resolve4, delay));
|
|
14235
14472
|
continue;
|
|
14236
14473
|
}
|
|
14237
14474
|
if (!err.$metadata) {
|
|
@@ -17706,7 +17943,7 @@ var init_node_http = () => {};
|
|
|
17706
17943
|
|
|
17707
17944
|
// ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js
|
|
17708
17945
|
function httpRequest(options) {
|
|
17709
|
-
return new Promise((
|
|
17946
|
+
return new Promise((resolve4, reject) => {
|
|
17710
17947
|
const req = node_http.request({
|
|
17711
17948
|
method: "GET",
|
|
17712
17949
|
...options,
|
|
@@ -17731,7 +17968,7 @@ function httpRequest(options) {
|
|
|
17731
17968
|
chunks.push(chunk);
|
|
17732
17969
|
});
|
|
17733
17970
|
res.on("end", () => {
|
|
17734
|
-
|
|
17971
|
+
resolve4(Buffer.concat(chunks));
|
|
17735
17972
|
req.destroy();
|
|
17736
17973
|
});
|
|
17737
17974
|
});
|
|
@@ -17955,9 +18192,9 @@ var import_config6, IMDS_PATH = "/latest/meta-data/iam/security-credentials/", I
|
|
|
17955
18192
|
let fallbackBlockedFromProcessEnv = false;
|
|
17956
18193
|
const configValue = await import_config6.loadConfig({
|
|
17957
18194
|
environmentVariableSelector: (env) => {
|
|
17958
|
-
const
|
|
17959
|
-
fallbackBlockedFromProcessEnv = !!
|
|
17960
|
-
if (
|
|
18195
|
+
const envValue2 = env[AWS_EC2_METADATA_V1_DISABLED];
|
|
18196
|
+
fallbackBlockedFromProcessEnv = !!envValue2 && envValue2 !== "false";
|
|
18197
|
+
if (envValue2 === undefined) {
|
|
17961
18198
|
throw new import_config6.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`, { logger: init.logger });
|
|
17962
18199
|
}
|
|
17963
18200
|
return fallbackBlockedFromProcessEnv;
|
|
@@ -18225,21 +18462,21 @@ var require_dist_cjs4 = __commonJS((exports) => {
|
|
|
18225
18462
|
let sendBody = true;
|
|
18226
18463
|
if (!externalAgent && expect === "100-continue") {
|
|
18227
18464
|
sendBody = await Promise.race([
|
|
18228
|
-
new Promise((
|
|
18229
|
-
timeoutId = Number(timing.setTimeout(() =>
|
|
18465
|
+
new Promise((resolve4) => {
|
|
18466
|
+
timeoutId = Number(timing.setTimeout(() => resolve4(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
|
|
18230
18467
|
}),
|
|
18231
|
-
new Promise((
|
|
18468
|
+
new Promise((resolve4) => {
|
|
18232
18469
|
httpRequest2.on("continue", () => {
|
|
18233
18470
|
timing.clearTimeout(timeoutId);
|
|
18234
|
-
|
|
18471
|
+
resolve4(true);
|
|
18235
18472
|
});
|
|
18236
18473
|
httpRequest2.on("response", () => {
|
|
18237
18474
|
timing.clearTimeout(timeoutId);
|
|
18238
|
-
|
|
18475
|
+
resolve4(false);
|
|
18239
18476
|
});
|
|
18240
18477
|
httpRequest2.on("error", () => {
|
|
18241
18478
|
timing.clearTimeout(timeoutId);
|
|
18242
|
-
|
|
18479
|
+
resolve4(false);
|
|
18243
18480
|
});
|
|
18244
18481
|
})
|
|
18245
18482
|
]);
|
|
@@ -18314,13 +18551,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18314
18551
|
return socketWarningTimestamp;
|
|
18315
18552
|
}
|
|
18316
18553
|
constructor(options) {
|
|
18317
|
-
this.configProvider = new Promise((
|
|
18554
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
18318
18555
|
if (typeof options === "function") {
|
|
18319
18556
|
options().then((_options) => {
|
|
18320
|
-
|
|
18557
|
+
resolve4(this.resolveDefaultConfig(_options));
|
|
18321
18558
|
}).catch(reject);
|
|
18322
18559
|
} else {
|
|
18323
|
-
|
|
18560
|
+
resolve4(this.resolveDefaultConfig(options));
|
|
18324
18561
|
}
|
|
18325
18562
|
});
|
|
18326
18563
|
}
|
|
@@ -18352,7 +18589,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18352
18589
|
timing.clearTimeout(socketTimeoutId);
|
|
18353
18590
|
timing.clearTimeout(keepAliveTimeoutId);
|
|
18354
18591
|
};
|
|
18355
|
-
const
|
|
18592
|
+
const resolve4 = async (arg) => {
|
|
18356
18593
|
await writeRequestBodyPromise;
|
|
18357
18594
|
clearTimeouts();
|
|
18358
18595
|
_resolve(arg);
|
|
@@ -18416,7 +18653,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18416
18653
|
headers: getTransformedHeaders(res.headers),
|
|
18417
18654
|
body: res
|
|
18418
18655
|
});
|
|
18419
|
-
|
|
18656
|
+
resolve4({ response: httpResponse });
|
|
18420
18657
|
});
|
|
18421
18658
|
req.on("error", (err) => {
|
|
18422
18659
|
if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
|
|
@@ -18748,13 +18985,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18748
18985
|
return new NodeHttp2Handler(instanceOrOptions);
|
|
18749
18986
|
}
|
|
18750
18987
|
constructor(options) {
|
|
18751
|
-
this.configProvider = new Promise((
|
|
18988
|
+
this.configProvider = new Promise((resolve4, reject) => {
|
|
18752
18989
|
if (typeof options === "function") {
|
|
18753
18990
|
options().then((opts) => {
|
|
18754
|
-
|
|
18991
|
+
resolve4(opts || {});
|
|
18755
18992
|
}).catch(reject);
|
|
18756
18993
|
} else {
|
|
18757
|
-
|
|
18994
|
+
resolve4(options || {});
|
|
18758
18995
|
}
|
|
18759
18996
|
});
|
|
18760
18997
|
}
|
|
@@ -18779,7 +19016,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18779
19016
|
return new Promise((_resolve, _reject) => {
|
|
18780
19017
|
let fulfilled = false;
|
|
18781
19018
|
let writeRequestBodyPromise = undefined;
|
|
18782
|
-
const
|
|
19019
|
+
const resolve4 = async (arg) => {
|
|
18783
19020
|
await writeRequestBodyPromise;
|
|
18784
19021
|
_resolve(arg);
|
|
18785
19022
|
};
|
|
@@ -18864,7 +19101,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18864
19101
|
body: clientHttp2Stream
|
|
18865
19102
|
});
|
|
18866
19103
|
fulfilled = true;
|
|
18867
|
-
|
|
19104
|
+
resolve4({ response: httpResponse });
|
|
18868
19105
|
if (useIsolatedSession) {
|
|
18869
19106
|
session.close();
|
|
18870
19107
|
}
|
|
@@ -18990,7 +19227,7 @@ var retryWrapper = (toRetry, maxRetries, delayMs) => {
|
|
|
18990
19227
|
try {
|
|
18991
19228
|
return await toRetry();
|
|
18992
19229
|
} catch (e) {
|
|
18993
|
-
await new Promise((
|
|
19230
|
+
await new Promise((resolve4) => setTimeout(resolve4, delayMs));
|
|
18994
19231
|
}
|
|
18995
19232
|
}
|
|
18996
19233
|
return await toRetry();
|
|
@@ -28282,8 +28519,8 @@ var require_signin = __commonJS((exports) => {
|
|
|
28282
28519
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
|
|
28283
28520
|
import { createHash as createHash2, createPrivateKey, createPublicKey, sign } from "crypto";
|
|
28284
28521
|
import { promises as fs2 } from "fs";
|
|
28285
|
-
import { homedir as
|
|
28286
|
-
import { dirname as dirname3, join as
|
|
28522
|
+
import { homedir as homedir4 } from "os";
|
|
28523
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
28287
28524
|
var import_config20, import_protocols3, LoginCredentialsFetcher;
|
|
28288
28525
|
var init_LoginCredentialsFetcher = __esm(() => {
|
|
28289
28526
|
import_config20 = __toESM(require_config(), 1);
|
|
@@ -28450,10 +28687,10 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
28450
28687
|
await fs2.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
|
|
28451
28688
|
}
|
|
28452
28689
|
getTokenFilePath() {
|
|
28453
|
-
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ??
|
|
28690
|
+
const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join5(homedir4(), ".aws", "login", "cache");
|
|
28454
28691
|
const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
|
|
28455
28692
|
const loginSessionSha256 = createHash2("sha256").update(loginSessionBytes).digest("hex");
|
|
28456
|
-
return
|
|
28693
|
+
return join5(directory, `${loginSessionSha256}.json`);
|
|
28457
28694
|
}
|
|
28458
28695
|
derToRawSignature(derSignature) {
|
|
28459
28696
|
let offset = 2;
|
|
@@ -38438,9 +38675,9 @@ __export(exports_config, {
|
|
|
38438
38675
|
applyPurchaseProfile: () => applyPurchaseProfile
|
|
38439
38676
|
});
|
|
38440
38677
|
import { createHash as createHash3 } from "crypto";
|
|
38441
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
38442
|
-
import { homedir as
|
|
38443
|
-
import { dirname as dirname4, join as
|
|
38678
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "fs";
|
|
38679
|
+
import { homedir as homedir5 } from "os";
|
|
38680
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
38444
38681
|
function getPurchaseProfile() {
|
|
38445
38682
|
return process.env["DOMAINS_PURCHASE_AWS_PROFILE"] ?? loadConfig4().purchase_aws_profile ?? undefined;
|
|
38446
38683
|
}
|
|
@@ -38453,20 +38690,20 @@ function applyPurchaseProfile() {
|
|
|
38453
38690
|
return profile;
|
|
38454
38691
|
}
|
|
38455
38692
|
function canonicalHome2(env) {
|
|
38456
|
-
return env["HOME"] || env["USERPROFILE"] ||
|
|
38693
|
+
return env["HOME"] || env["USERPROFILE"] || homedir5();
|
|
38457
38694
|
}
|
|
38458
38695
|
function migrateLegacyConfig(env = process.env, dryRun = false) {
|
|
38459
38696
|
const report = { dryRun, wouldCopy: false, copied: false };
|
|
38460
38697
|
const home = canonicalHome2(env);
|
|
38461
|
-
const canonicalDir =
|
|
38462
|
-
const newPath =
|
|
38463
|
-
if (
|
|
38698
|
+
const canonicalDir = join6(home, ".hasna", "domains");
|
|
38699
|
+
const newPath = join6(canonicalDir, "config.json");
|
|
38700
|
+
if (existsSync3(newPath))
|
|
38464
38701
|
return report;
|
|
38465
|
-
if (
|
|
38702
|
+
if (existsSync3(join6(canonicalDir, ".migrated-from-xdg-config.receipt.json")))
|
|
38466
38703
|
return report;
|
|
38467
|
-
const xdgConfig = env["XDG_CONFIG_HOME"]?.trim() ||
|
|
38468
|
-
const oldPath =
|
|
38469
|
-
if (!
|
|
38704
|
+
const xdgConfig = env["XDG_CONFIG_HOME"]?.trim() || join6(home, ".config");
|
|
38705
|
+
const oldPath = join6(xdgConfig, "open-domains", "config.json");
|
|
38706
|
+
if (!existsSync3(oldPath))
|
|
38470
38707
|
return report;
|
|
38471
38708
|
report.wouldCopy = true;
|
|
38472
38709
|
if (dryRun)
|
|
@@ -38478,7 +38715,7 @@ function migrateLegacyConfig(env = process.env, dryRun = false) {
|
|
|
38478
38715
|
if (!oldBytes.equals(newBytes)) {
|
|
38479
38716
|
throw new Error(`Refusing migration: copied ${newPath} does not byte-match ${oldPath}; the canonical config was not populated.`);
|
|
38480
38717
|
}
|
|
38481
|
-
writeFileSync2(
|
|
38718
|
+
writeFileSync2(join6(canonicalDir, ".migrated-from-xdg-config.receipt.json"), `${JSON.stringify({
|
|
38482
38719
|
migratedAt: new Date().toISOString(),
|
|
38483
38720
|
from: oldPath,
|
|
38484
38721
|
to: newPath,
|
|
@@ -38494,13 +38731,15 @@ function getConfigPath(env = process.env) {
|
|
|
38494
38731
|
return env["DOMAINS_CONFIG_PATH"];
|
|
38495
38732
|
const dir = env["DOMAINS_CONFIG_DIR"];
|
|
38496
38733
|
if (dir)
|
|
38497
|
-
return
|
|
38498
|
-
|
|
38499
|
-
|
|
38734
|
+
return join6(dir, "config.json");
|
|
38735
|
+
if (!adoptResolverHome(resolverHome(env), env)) {
|
|
38736
|
+
migrateLegacyConfig(env);
|
|
38737
|
+
}
|
|
38738
|
+
return getDefaultConfigPath(env);
|
|
38500
38739
|
}
|
|
38501
38740
|
function loadConfig4(env = process.env) {
|
|
38502
38741
|
const path = getConfigPath(env);
|
|
38503
|
-
if (!
|
|
38742
|
+
if (!existsSync3(path))
|
|
38504
38743
|
return {};
|
|
38505
38744
|
try {
|
|
38506
38745
|
return JSON.parse(readFileSync5(path, "utf-8"));
|
|
@@ -38511,7 +38750,7 @@ function loadConfig4(env = process.env) {
|
|
|
38511
38750
|
function saveConfig(config, env = process.env) {
|
|
38512
38751
|
const path = getConfigPath(env);
|
|
38513
38752
|
const dir = dirname4(path);
|
|
38514
|
-
if (!
|
|
38753
|
+
if (!existsSync3(dir))
|
|
38515
38754
|
mkdirSync2(dir, { recursive: true });
|
|
38516
38755
|
writeFileSync2(path, JSON.stringify(config, null, 2), "utf-8");
|
|
38517
38756
|
}
|
|
@@ -38560,7 +38799,9 @@ function getConfigKey(keyPath) {
|
|
|
38560
38799
|
}
|
|
38561
38800
|
return;
|
|
38562
38801
|
}
|
|
38563
|
-
var init_config = () => {
|
|
38802
|
+
var init_config = __esm(() => {
|
|
38803
|
+
init_app_home();
|
|
38804
|
+
});
|
|
38564
38805
|
|
|
38565
38806
|
// src/lib/compact-output.ts
|
|
38566
38807
|
function parseLimit(value, fallback = DEFAULT_LIST_LIMIT, maxLimit = MAX_LIST_LIMIT) {
|
|
@@ -41357,9 +41598,9 @@ __export(exports_commander, {
|
|
|
41357
41598
|
});
|
|
41358
41599
|
import { chmod, mkdir, readFile, rename, writeFile as writeFile2 } from "fs/promises";
|
|
41359
41600
|
import { Buffer as Buffer2 } from "buffer";
|
|
41360
|
-
import { existsSync as
|
|
41361
|
-
import { homedir as
|
|
41362
|
-
import { join as
|
|
41601
|
+
import { existsSync as existsSync5 } from "fs";
|
|
41602
|
+
import { homedir as homedir7 } from "os";
|
|
41603
|
+
import { join as join8 } from "path";
|
|
41363
41604
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
41364
41605
|
import { lookup as dnsLookup } from "dns/promises";
|
|
41365
41606
|
import { isIP as isIP2 } from "net";
|
|
@@ -41464,7 +41705,7 @@ function channelMatchesEvent(channel, event) {
|
|
|
41464
41705
|
return channel.filters.some((filter) => eventMatchesFilter(event, filter));
|
|
41465
41706
|
}
|
|
41466
41707
|
function getEventsDataDir(override) {
|
|
41467
|
-
return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] ||
|
|
41708
|
+
return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join8(homedir7(), ".hasna", "events");
|
|
41468
41709
|
}
|
|
41469
41710
|
function getActiveEventsDirEnv() {
|
|
41470
41711
|
if (process.env[HASNA_EVENTS_DIR_ENV])
|
|
@@ -41480,12 +41721,12 @@ class JsonEventsStore {
|
|
|
41480
41721
|
channelsPath;
|
|
41481
41722
|
eventsPath;
|
|
41482
41723
|
deliveriesPath;
|
|
41483
|
-
constructor(
|
|
41484
|
-
this.dataDir =
|
|
41485
|
-
this.runtime = localJsonRuntime(
|
|
41486
|
-
this.channelsPath =
|
|
41487
|
-
this.eventsPath =
|
|
41488
|
-
this.deliveriesPath =
|
|
41724
|
+
constructor(dataDir2 = getEventsDataDir()) {
|
|
41725
|
+
this.dataDir = dataDir2;
|
|
41726
|
+
this.runtime = localJsonRuntime(dataDir2);
|
|
41727
|
+
this.channelsPath = join8(dataDir2, "channels.json");
|
|
41728
|
+
this.eventsPath = join8(dataDir2, "events.json");
|
|
41729
|
+
this.deliveriesPath = join8(dataDir2, "deliveries.json");
|
|
41489
41730
|
}
|
|
41490
41731
|
async init() {
|
|
41491
41732
|
await mkdir(this.dataDir, { recursive: true, mode: 448 });
|
|
@@ -41602,7 +41843,7 @@ class JsonEventsStore {
|
|
|
41602
41843
|
};
|
|
41603
41844
|
}
|
|
41604
41845
|
async ensureArrayFile(path) {
|
|
41605
|
-
if (!
|
|
41846
|
+
if (!existsSync5(path)) {
|
|
41606
41847
|
await writeFile2(path, `[]
|
|
41607
41848
|
`, { encoding: "utf-8", mode: 384 });
|
|
41608
41849
|
}
|
|
@@ -41632,7 +41873,7 @@ class JsonEventsStore {
|
|
|
41632
41873
|
});
|
|
41633
41874
|
}
|
|
41634
41875
|
}
|
|
41635
|
-
function localJsonRuntime(
|
|
41876
|
+
function localJsonRuntime(dataDir2 = getEventsDataDir()) {
|
|
41636
41877
|
return {
|
|
41637
41878
|
mode: "local-files",
|
|
41638
41879
|
name: "json-events-store",
|
|
@@ -41645,7 +41886,7 @@ function localJsonRuntime(dataDir = getEventsDataDir()) {
|
|
|
41645
41886
|
durable: true,
|
|
41646
41887
|
idempotency: "best-effort-local",
|
|
41647
41888
|
replayCursors: true,
|
|
41648
|
-
description: `Local JSON files in ${
|
|
41889
|
+
description: `Local JSON files in ${dataDir2}; no SQLite, Postgres, S3, or AWS runtime is configured by this store.`
|
|
41649
41890
|
};
|
|
41650
41891
|
}
|
|
41651
41892
|
function encodeLocalJsonEventCursor(offset, options = {}) {
|
|
@@ -41709,8 +41950,8 @@ function assertCursorFilter(name, cursorValue, optionValue) {
|
|
|
41709
41950
|
function findEventByIdentity(events, identity2) {
|
|
41710
41951
|
return events.find((event) => identity2.id !== undefined && event.id === identity2.id || identity2.dedupeKey !== undefined && event.dedupeKey === identity2.dedupeKey);
|
|
41711
41952
|
}
|
|
41712
|
-
async function getEventsStatus(
|
|
41713
|
-
const store = new JsonEventsStore(
|
|
41953
|
+
async function getEventsStatus(dataDir2) {
|
|
41954
|
+
const store = new JsonEventsStore(dataDir2);
|
|
41714
41955
|
await store.init();
|
|
41715
41956
|
const [channels, events, deliveries] = await Promise.all([
|
|
41716
41957
|
store.listChannels(),
|
|
@@ -41752,9 +41993,9 @@ async function getEventsStatus(dataDir) {
|
|
|
41752
41993
|
}
|
|
41753
41994
|
};
|
|
41754
41995
|
}
|
|
41755
|
-
function statusFile(
|
|
41756
|
-
const path =
|
|
41757
|
-
return { path, exists:
|
|
41996
|
+
function statusFile(dataDir2, fileName, records) {
|
|
41997
|
+
const path = join8(dataDir2, fileName);
|
|
41998
|
+
return { path, exists: existsSync5(path), records };
|
|
41758
41999
|
}
|
|
41759
42000
|
function buildSignatureBase(timestamp, body) {
|
|
41760
42001
|
return `${timestamp}.${body}`;
|
|
@@ -42055,7 +42296,7 @@ async function pinnedNativeRequest(target, addresses, method, headers, body, sig
|
|
|
42055
42296
|
callback(null, entries);
|
|
42056
42297
|
}
|
|
42057
42298
|
};
|
|
42058
|
-
return new Promise((
|
|
42299
|
+
return new Promise((resolve4, reject) => {
|
|
42059
42300
|
const request = isHttps ? nodeHttpsRequest(requestOptions, onResponse) : nodeHttpRequest(requestOptions, onResponse);
|
|
42060
42301
|
const onAbort = () => {
|
|
42061
42302
|
const error = new Error("The operation was aborted.");
|
|
@@ -42082,7 +42323,7 @@ async function pinnedNativeRequest(target, addresses, method, headers, body, sig
|
|
|
42082
42323
|
else if (Array.isArray(value))
|
|
42083
42324
|
headersRecord[name] = value.join(", ");
|
|
42084
42325
|
}
|
|
42085
|
-
|
|
42326
|
+
resolve4(new Response(Buffer.concat(chunks), { status: response.statusCode ?? 200, headers: headersRecord }));
|
|
42086
42327
|
});
|
|
42087
42328
|
}
|
|
42088
42329
|
});
|
|
@@ -42179,7 +42420,7 @@ async function dispatchCommand(event, channel) {
|
|
|
42179
42420
|
HASNA_EVENT_SCHEMA_VERSION: event.schemaVersion,
|
|
42180
42421
|
HASNA_EVENT_JSON: eventJson
|
|
42181
42422
|
};
|
|
42182
|
-
return new Promise((
|
|
42423
|
+
return new Promise((resolve4) => {
|
|
42183
42424
|
const child = spawn(channel.command.command, channel.command.args ?? [], {
|
|
42184
42425
|
cwd: channel.command.cwd,
|
|
42185
42426
|
env,
|
|
@@ -42197,7 +42438,7 @@ async function dispatchCommand(event, channel) {
|
|
|
42197
42438
|
});
|
|
42198
42439
|
child.on("error", (error) => {
|
|
42199
42440
|
clearTimeout(timeout);
|
|
42200
|
-
|
|
42441
|
+
resolve4({
|
|
42201
42442
|
attempt: 1,
|
|
42202
42443
|
status: "failed",
|
|
42203
42444
|
startedAt,
|
|
@@ -42210,7 +42451,7 @@ async function dispatchCommand(event, channel) {
|
|
|
42210
42451
|
child.on("close", (code, signal) => {
|
|
42211
42452
|
clearTimeout(timeout);
|
|
42212
42453
|
const success = code === 0;
|
|
42213
|
-
|
|
42454
|
+
resolve4({
|
|
42214
42455
|
attempt: 1,
|
|
42215
42456
|
status: success ? "success" : "failed",
|
|
42216
42457
|
startedAt,
|
|
@@ -45577,15 +45818,15 @@ ${"\u2500".repeat(45)}`);
|
|
|
45577
45818
|
|
|
45578
45819
|
// src/cli/commands/mcp-install.ts
|
|
45579
45820
|
init_stdout();
|
|
45580
|
-
import { existsSync as
|
|
45581
|
-
import { homedir as
|
|
45582
|
-
import { dirname as dirname5, join as
|
|
45821
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
|
45822
|
+
import { homedir as homedir6 } from "os";
|
|
45823
|
+
import { dirname as dirname5, join as join7 } from "path";
|
|
45583
45824
|
import { execSync as execSync2 } from "child_process";
|
|
45584
45825
|
var MCP_SERVER_NAME = "domains";
|
|
45585
45826
|
function getClaudeConfigPaths() {
|
|
45586
45827
|
return {
|
|
45587
|
-
global:
|
|
45588
|
-
project:
|
|
45828
|
+
global: join7(homedir6(), ".claude", "claude_desktop_config.json"),
|
|
45829
|
+
project: join7(process.cwd(), ".claude", "settings.json")
|
|
45589
45830
|
};
|
|
45590
45831
|
}
|
|
45591
45832
|
function getMcpBinaryPath() {
|
|
@@ -45597,12 +45838,12 @@ function getMcpBinaryPath() {
|
|
|
45597
45838
|
}
|
|
45598
45839
|
function ensureConfigDir(configPath) {
|
|
45599
45840
|
const dir = dirname5(configPath);
|
|
45600
|
-
if (!
|
|
45841
|
+
if (!existsSync4(dir)) {
|
|
45601
45842
|
mkdirSync3(dir, { recursive: true });
|
|
45602
45843
|
}
|
|
45603
45844
|
}
|
|
45604
45845
|
function readConfig(configPath) {
|
|
45605
|
-
if (!
|
|
45846
|
+
if (!existsSync4(configPath))
|
|
45606
45847
|
return {};
|
|
45607
45848
|
try {
|
|
45608
45849
|
return JSON.parse(readFileSync7(configPath, "utf-8"));
|
|
@@ -45631,7 +45872,7 @@ function registerMcpCommand(program2) {
|
|
|
45631
45872
|
mcp.command("uninstall").description("Remove domains MCP server from Claude Code config").option("--project", "Remove from project config instead of global").action((opts) => {
|
|
45632
45873
|
const paths = getClaudeConfigPaths();
|
|
45633
45874
|
const configPath = opts.project ? paths.project : paths.global;
|
|
45634
|
-
if (!
|
|
45875
|
+
if (!existsSync4(configPath)) {
|
|
45635
45876
|
printLine("Config file not found \u2014 nothing to remove.");
|
|
45636
45877
|
return;
|
|
45637
45878
|
}
|
|
@@ -45649,7 +45890,7 @@ function registerMcpCommand(program2) {
|
|
|
45649
45890
|
const paths = getClaudeConfigPaths();
|
|
45650
45891
|
const status = [];
|
|
45651
45892
|
for (const [scope, configPath] of [["global", paths.global], ["project", paths.project]]) {
|
|
45652
|
-
if (!
|
|
45893
|
+
if (!existsSync4(configPath)) {
|
|
45653
45894
|
status.push({ scope, config_path: configPath, exists: false, registered: false });
|
|
45654
45895
|
continue;
|
|
45655
45896
|
}
|
|
@@ -46287,6 +46528,20 @@ var PG_MIGRATIONS = [
|
|
|
46287
46528
|
var OWNER_DSN_ENV = "HASNA_DOMAINS_DATABASE_URL_OWNER";
|
|
46288
46529
|
var APP_DSN_ENV = "HASNA_DOMAINS_DATABASE_URL";
|
|
46289
46530
|
var LEGACY_DSN_ENV = "DATABASE_URL";
|
|
46531
|
+
var ACKNOWLEDGED_LEGACY_MIGRATION_IDS = [
|
|
46532
|
+
"domains_apikeys_tenancy_0001",
|
|
46533
|
+
"domains_apikeys_tenancy_0002",
|
|
46534
|
+
"domains_tenancy_0001",
|
|
46535
|
+
"domains_tenancy_0002",
|
|
46536
|
+
"domains_tenancy_0003",
|
|
46537
|
+
"domains_tenancy_0004",
|
|
46538
|
+
"domains_tenancy_0005",
|
|
46539
|
+
"domains_tenancy_0006",
|
|
46540
|
+
"domains_tenancy_0007",
|
|
46541
|
+
"domains_tenancy_0008",
|
|
46542
|
+
"domains_tenancy_0009",
|
|
46543
|
+
"domains_tenancy_0010"
|
|
46544
|
+
];
|
|
46290
46545
|
function buildMigrations() {
|
|
46291
46546
|
const migrations2 = [];
|
|
46292
46547
|
PG_MIGRATIONS.forEach((sql, i4) => {
|
|
@@ -46312,7 +46567,7 @@ async function runMigrations(opts = {}) {
|
|
|
46312
46567
|
try {
|
|
46313
46568
|
const client = wrapExecutor(pool2);
|
|
46314
46569
|
const ledger = new MigrationLedger(client, buildMigrations(), {
|
|
46315
|
-
acknowledgedLegacyIds:
|
|
46570
|
+
acknowledgedLegacyIds: ACKNOWLEDGED_LEGACY_MIGRATION_IDS
|
|
46316
46571
|
});
|
|
46317
46572
|
return await ledger.migrate(opts.dryRun ? { dryRun: true } : {});
|
|
46318
46573
|
} finally {
|
|
@@ -47223,13 +47478,13 @@ async function loadRdapBootstrap(path) {
|
|
|
47223
47478
|
return map;
|
|
47224
47479
|
}
|
|
47225
47480
|
function whoisRaw(server, query2, timeoutMs = 25000) {
|
|
47226
|
-
return new Promise((
|
|
47481
|
+
return new Promise((resolve4) => {
|
|
47227
47482
|
const chunks = [];
|
|
47228
47483
|
let settled = false;
|
|
47229
47484
|
const done = (r4) => {
|
|
47230
47485
|
if (!settled) {
|
|
47231
47486
|
settled = true;
|
|
47232
|
-
|
|
47487
|
+
resolve4(r4);
|
|
47233
47488
|
}
|
|
47234
47489
|
};
|
|
47235
47490
|
const sock = net.createConnection({ host: server, port: 43 });
|