@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/dist/index.js CHANGED
@@ -316,22 +316,129 @@ var init_migrations = __esm(() => {
316
316
  ];
317
317
  });
318
318
 
319
+ // ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
320
+ import { homedir } from "os";
321
+ import { join as join2 } from "path";
322
+ function assertApp(app) {
323
+ if (typeof app !== "string" || app.length === 0) {
324
+ throw new TypeError("paths: app must be a non-empty string");
325
+ }
326
+ if (!APP_SLUG_RE.test(app)) {
327
+ throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
328
+ }
329
+ }
330
+ function envOf(options) {
331
+ return options.env ?? process.env;
332
+ }
333
+ function envValue(options, kind) {
334
+ const value = envOf(options)[KIND_ENV[kind]];
335
+ return typeof value === "string" && value.length > 0 ? value : undefined;
336
+ }
337
+ function isMacOS(platform) {
338
+ return platform === "darwin";
339
+ }
340
+ function baseDir(kind, options) {
341
+ const override = envValue(options, kind);
342
+ if (override)
343
+ return override;
344
+ const home = options.home ?? homedir();
345
+ const platform = options.platform ?? process.platform;
346
+ if (isMacOS(platform)) {
347
+ switch (kind) {
348
+ case "config":
349
+ case "data":
350
+ return join2(home, "Library", "Application Support", "Hasna");
351
+ case "cache":
352
+ return join2(home, "Library", "Caches", "Hasna");
353
+ case "state":
354
+ return join2(home, "Library", "Logs", "Hasna");
355
+ }
356
+ }
357
+ switch (kind) {
358
+ case "config":
359
+ return join2(home, ".config", "hasna");
360
+ case "data":
361
+ return join2(home, ".local", "share", "hasna");
362
+ case "state":
363
+ return join2(home, ".local", "state", "hasna");
364
+ case "cache":
365
+ return join2(home, ".cache", "hasna");
366
+ }
367
+ }
368
+ function resolvePath(kind, options) {
369
+ assertApp(options.app);
370
+ const appSegment = options.internal === true ? join2("internal", options.app) : options.app;
371
+ return join2(baseDir(kind, options), appSegment);
372
+ }
373
+ function dataDir(options) {
374
+ return resolvePath("data", options);
375
+ }
376
+ var KIND_ENV, APP_SLUG_RE;
377
+ var init_dist = __esm(() => {
378
+ KIND_ENV = {
379
+ config: "HASNA_CONFIG_HOME",
380
+ data: "HASNA_DATA_HOME",
381
+ state: "HASNA_STATE_HOME",
382
+ cache: "HASNA_CACHE_HOME"
383
+ };
384
+ APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
385
+ });
386
+
387
+ // src/lib/app-home.ts
388
+ import { existsSync } from "fs";
389
+ import { homedir as homedir2 } from "os";
390
+ import { join as join3, resolve } from "path";
391
+ function effectiveHome(env = process.env) {
392
+ return env["HOME"] || env["USERPROFILE"] || homedir2();
393
+ }
394
+ function legacyHomeDir(env = process.env) {
395
+ return join3(effectiveHome(env), ".hasna", APP);
396
+ }
397
+ function resolverHome(env = process.env) {
398
+ const home = env["HOME"] || env["USERPROFILE"];
399
+ return dataDir({ app: APP, home, env });
400
+ }
401
+ function adoptResolverHome(resolved, env = process.env) {
402
+ const dataOverride = env.HASNA_DATA_HOME;
403
+ if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
404
+ return true;
405
+ return existsSync(join3(resolved, "domains.db"));
406
+ }
407
+ function exactAppOverride(env = process.env) {
408
+ const override = env["HASNA_DOMAINS_HOME"] ?? env["DOMAINS_HOME"] ?? env["HASNA_DOMAINS_DIR"] ?? env["DOMAINS_DIR"];
409
+ return override && override.trim() ? override.trim() : undefined;
410
+ }
411
+ function appHome(env = process.env) {
412
+ const override = exactAppOverride(env);
413
+ if (override)
414
+ return resolve(override);
415
+ const resolved = resolverHome(env);
416
+ return adoptResolverHome(resolved, env) ? resolve(resolved) : resolve(legacyHomeDir(env));
417
+ }
418
+ function getDefaultDbPath(env = process.env) {
419
+ return join3(appHome(env), `${APP}.db`);
420
+ }
421
+ var APP = "domains";
422
+ var init_app_home = __esm(() => {
423
+ init_dist();
424
+ });
425
+
319
426
  // src/db/database.ts
320
427
  import { Database } from "bun:sqlite";
321
428
  import { createHash } from "crypto";
322
429
  import {
323
430
  copyFileSync,
324
- existsSync,
431
+ existsSync as existsSync2,
325
432
  mkdirSync,
326
433
  readFileSync as readFileSync2,
327
434
  readdirSync,
328
435
  statSync as statSync2,
329
436
  writeFileSync
330
437
  } from "fs";
331
- import { dirname, join as join2, resolve } from "path";
332
- import { homedir } from "os";
438
+ import { dirname, join as join4, resolve as resolve2 } from "path";
439
+ import { homedir as homedir3 } from "os";
333
440
  function canonicalHome(env) {
334
- return env["HOME"] || env["USERPROFILE"] || homedir();
441
+ return env["HOME"] || env["USERPROFILE"] || homedir3();
335
442
  }
336
443
  function sha256File(path) {
337
444
  return createHash("sha256").update(readFileSync2(path)).digest("hex");
@@ -339,20 +446,20 @@ function sha256File(path) {
339
446
  function migrateLegacyDataDir(env = process.env, dryRun = false) {
340
447
  const report = { dryRun, wouldCopy: [], copied: [] };
341
448
  const home = canonicalHome(env);
342
- const xdgData = env["XDG_DATA_HOME"]?.trim() || join2(home, ".local", "share");
343
- const oldDir = join2(xdgData, "open-domains");
344
- const oldDb = join2(oldDir, "domains.db");
345
- if (!existsSync(oldDb))
449
+ const xdgData = env["XDG_DATA_HOME"]?.trim() || join4(home, ".local", "share");
450
+ const oldDir = join4(xdgData, "open-domains");
451
+ const oldDb = join4(oldDir, "domains.db");
452
+ if (!existsSync2(oldDb))
346
453
  return report;
347
- const canonicalDir = join2(home, ".hasna", "domains");
348
- const newDb = join2(canonicalDir, "domains.db");
349
- if (existsSync(newDb))
454
+ const canonicalDir = join4(home, ".hasna", "domains");
455
+ const newDb = join4(canonicalDir, "domains.db");
456
+ if (existsSync2(newDb))
350
457
  return report;
351
- if (existsSync(join2(canonicalDir, ".migrated-from-xdg.receipt.json")))
458
+ if (existsSync2(join4(canonicalDir, ".migrated-from-xdg.receipt.json")))
352
459
  return report;
353
460
  if (dryRun) {
354
461
  for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
355
- if (existsSync(join2(oldDir, name)) && !existsSync(join2(canonicalDir, name))) {
462
+ if (existsSync2(join4(oldDir, name)) && !existsSync2(join4(canonicalDir, name))) {
356
463
  report.wouldCopy.push(name);
357
464
  }
358
465
  }
@@ -361,11 +468,11 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
361
468
  mkdirSync(canonicalDir, { recursive: true });
362
469
  const copied = [];
363
470
  for (const name of ["domains.db", "domains.db-wal", "domains.db-shm"]) {
364
- const from = join2(oldDir, name);
365
- if (!existsSync(from))
471
+ const from = join4(oldDir, name);
472
+ if (!existsSync2(from))
366
473
  continue;
367
- const to = join2(canonicalDir, name);
368
- if (existsSync(to))
474
+ const to = join4(canonicalDir, name);
475
+ if (existsSync2(to))
369
476
  continue;
370
477
  copyFileSync(from, to);
371
478
  copied.push({ name, bytes: statSync2(to).size, sha256: sha256File(to) });
@@ -374,7 +481,7 @@ function migrateLegacyDataDir(env = process.env, dryRun = false) {
374
481
  if (statSync2(newDb).size !== statSync2(oldDb).size || sha256File(newDb) !== sha256File(oldDb)) {
375
482
  throw new Error(`Refusing migration: copied ${newDb} does not byte-match ${oldDb}; the canonical root was not populated.`);
376
483
  }
377
- writeFileSync(join2(canonicalDir, ".migrated-from-xdg.receipt.json"), `${JSON.stringify({
484
+ writeFileSync(join4(canonicalDir, ".migrated-from-xdg.receipt.json"), `${JSON.stringify({
378
485
  migratedAt: new Date().toISOString(),
379
486
  from: oldDir,
380
487
  to: canonicalDir,
@@ -388,26 +495,26 @@ function getDbPath(env = process.env) {
388
495
  return env["DOMAINS_DB_PATH"];
389
496
  if (env["HASNA_DOMAINS_DB_PATH"])
390
497
  return env["HASNA_DOMAINS_DB_PATH"];
391
- const explicit = env["DOMAINS_DIR"] ?? env["HASNA_DOMAINS_DIR"];
498
+ const explicit = exactAppOverride(env);
392
499
  if (explicit) {
393
- return join2(explicit, "domains.db");
500
+ return join4(explicit, "domains.db");
394
501
  }
395
- const home = canonicalHome(env);
396
- const canonicalDir = join2(home, ".hasna", "domains");
397
- migrateLegacyDataDir(env);
398
- migrateDotfile("domains", canonicalDir, env);
399
- return join2(canonicalDir, "domains.db");
502
+ if (!adoptResolverHome(resolverHome(env), env)) {
503
+ migrateLegacyDataDir(env);
504
+ migrateDotfile("domains", legacyHomeDir(env), env);
505
+ }
506
+ return getDefaultDbPath(env);
400
507
  }
401
508
  function migrateDotfile(name, newDir, env) {
402
509
  const home = canonicalHome(env);
403
- const oldDir = join2(home, `.${name}`);
404
- if (!existsSync(oldDir) || existsSync(newDir))
510
+ const oldDir = join4(home, `.${name}`);
511
+ if (!existsSync2(oldDir) || existsSync2(newDir))
405
512
  return;
406
513
  mkdirSync(newDir, { recursive: true });
407
514
  for (const file of readdirSync(oldDir)) {
408
- const oldPath = join2(oldDir, file);
515
+ const oldPath = join4(oldDir, file);
409
516
  if (statSync2(oldPath).isFile())
410
- copyFileSync(oldPath, join2(newDir, file));
517
+ copyFileSync(oldPath, join4(newDir, file));
411
518
  }
412
519
  }
413
520
  function getDatabase() {
@@ -415,7 +522,7 @@ function getDatabase() {
415
522
  return _db;
416
523
  const dbPath = getDbPath();
417
524
  if (dbPath !== ":memory:") {
418
- const dir = dirname(resolve(dbPath));
525
+ const dir = dirname(resolve2(dbPath));
419
526
  mkdirSync(dir, { recursive: true });
420
527
  }
421
528
  _db = new Database(dbPath);
@@ -448,6 +555,7 @@ function getDatabase() {
448
555
  var _db = null;
449
556
  var init_database = __esm(() => {
450
557
  init_migrations();
558
+ init_app_home();
451
559
  });
452
560
 
453
561
  // src/db/domain-records.ts
@@ -2163,7 +2271,7 @@ var require_client = __commonJS((exports) => {
2163
2271
  };
2164
2272
  };
2165
2273
  var sleep = (seconds) => {
2166
- return new Promise((resolve3) => setTimeout(resolve3, seconds * 1000));
2274
+ return new Promise((resolve4) => setTimeout(resolve4, seconds * 1000));
2167
2275
  };
2168
2276
  var waiterServiceDefaults = {
2169
2277
  minDelay: 2,
@@ -2292,8 +2400,8 @@ var require_client = __commonJS((exports) => {
2292
2400
  };
2293
2401
  var abortTimeout = (abortSignal) => {
2294
2402
  let onAbort;
2295
- const promise = new Promise((resolve3) => {
2296
- onAbort = () => resolve3({ state: WaiterState.ABORTED });
2403
+ const promise = new Promise((resolve4) => {
2404
+ onAbort = () => resolve4({ state: WaiterState.ABORTED });
2297
2405
  if (typeof abortSignal.addEventListener === "function") {
2298
2406
  abortSignal.addEventListener("abort", onAbort);
2299
2407
  } else {
@@ -2946,8 +3054,8 @@ var require_client = __commonJS((exports) => {
2946
3054
 
2947
3055
  // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/config/index.js
2948
3056
  var require_config = __commonJS((exports) => {
2949
- var { homedir: homedir2 } = __require("os");
2950
- var { sep, join: join3 } = __require("path");
3057
+ var { homedir: homedir4 } = __require("os");
3058
+ var { sep, join: join5 } = __require("path");
2951
3059
  var { createHash: createHash2 } = __require("crypto");
2952
3060
  var { readFile: readFile$1 } = __require("fs/promises");
2953
3061
  var { IniSectionType } = require_dist_cjs();
@@ -3096,7 +3204,7 @@ var require_config = __commonJS((exports) => {
3096
3204
  return `${HOMEDRIVE}${HOMEPATH}`;
3097
3205
  const homeDirCacheKey = getHomeDirCacheKey();
3098
3206
  if (!homeDirCache[homeDirCacheKey])
3099
- homeDirCache[homeDirCacheKey] = homedir2();
3207
+ homeDirCache[homeDirCacheKey] = homedir4();
3100
3208
  return homeDirCache[homeDirCacheKey];
3101
3209
  };
3102
3210
  var ENV_PROFILE = "AWS_PROFILE";
@@ -3105,7 +3213,7 @@ var require_config = __commonJS((exports) => {
3105
3213
  var getSSOTokenFilepath = (id) => {
3106
3214
  const hasher = createHash2("sha1");
3107
3215
  const cacheName = hasher.update(id).digest("hex");
3108
- return join3(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
3216
+ return join5(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
3109
3217
  };
3110
3218
  var tokenIntercept = {};
3111
3219
  var getSSOTokenFromFile = async (id) => {
@@ -3132,9 +3240,9 @@ var require_config = __commonJS((exports) => {
3132
3240
  ...data.default && { default: data.default }
3133
3241
  });
3134
3242
  var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
3135
- var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || join3(getHomeDir(), ".aws", "config");
3243
+ var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || join5(getHomeDir(), ".aws", "config");
3136
3244
  var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
3137
- var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || join3(getHomeDir(), ".aws", "credentials");
3245
+ var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || join5(getHomeDir(), ".aws", "credentials");
3138
3246
  var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@+.%:/]+)\2$/;
3139
3247
  var profileNameBlockList = ["__proto__", "profile __proto__"];
3140
3248
  var parseIni = (iniData) => {
@@ -3200,11 +3308,11 @@ var require_config = __commonJS((exports) => {
3200
3308
  const relativeHomeDirPrefix = "~/";
3201
3309
  let resolvedFilepath = filepath;
3202
3310
  if (filepath.startsWith(relativeHomeDirPrefix)) {
3203
- resolvedFilepath = join3(homeDir2, filepath.slice(2));
3311
+ resolvedFilepath = join5(homeDir2, filepath.slice(2));
3204
3312
  }
3205
3313
  let resolvedConfigFilepath = configFilepath;
3206
3314
  if (configFilepath.startsWith(relativeHomeDirPrefix)) {
3207
- resolvedConfigFilepath = join3(homeDir2, configFilepath.slice(2));
3315
+ resolvedConfigFilepath = join5(homeDir2, configFilepath.slice(2));
3208
3316
  }
3209
3317
  const parsedFiles = await Promise.all([
3210
3318
  readFile(resolvedConfigFilepath, {
@@ -3421,7 +3529,7 @@ var require_config = __commonJS((exports) => {
3421
3529
  };
3422
3530
  var imdsRequest = async (options) => {
3423
3531
  const { request } = __require("http");
3424
- return new Promise((resolve3, reject) => {
3532
+ return new Promise((resolve4, reject) => {
3425
3533
  const req = request({
3426
3534
  hostname: options.hostname,
3427
3535
  port: options.port,
@@ -3449,7 +3557,7 @@ var require_config = __commonJS((exports) => {
3449
3557
  const chunks = [];
3450
3558
  res.on("data", (chunk) => chunks.push(chunk));
3451
3559
  res.on("end", () => {
3452
- resolve3(Buffer.concat(chunks));
3560
+ resolve4(Buffer.concat(chunks));
3453
3561
  req.destroy();
3454
3562
  });
3455
3563
  });
@@ -5800,7 +5908,7 @@ ${value}\r
5800
5908
  if (isReadableStream(stream)) {
5801
5909
  return headStream$1(stream, bytes);
5802
5910
  }
5803
- return new Promise((resolve3, reject) => {
5911
+ return new Promise((resolve4, reject) => {
5804
5912
  const collector = new Collector$1;
5805
5913
  collector.limit = bytes;
5806
5914
  stream.pipe(collector);
@@ -5811,7 +5919,7 @@ ${value}\r
5811
5919
  collector.on("error", reject);
5812
5920
  collector.on("finish", function() {
5813
5921
  const bytes2 = concatBytes(this.buffers);
5814
- resolve3(bytes2);
5922
+ resolve4(bytes2);
5815
5923
  });
5816
5924
  });
5817
5925
  };
@@ -5925,7 +6033,7 @@ ${value}\r
5925
6033
  if (isReadableStream(stream)) {
5926
6034
  return collectReadableStream(stream);
5927
6035
  }
5928
- return new Promise((resolve3, reject) => {
6036
+ return new Promise((resolve4, reject) => {
5929
6037
  const collector = new Collector;
5930
6038
  const nodeStream = stream;
5931
6039
  nodeStream.pipe(collector);
@@ -5936,7 +6044,7 @@ ${value}\r
5936
6044
  collector.on("error", reject);
5937
6045
  collector.on("finish", function() {
5938
6046
  const bytes = concatBytes(this.bufferedBytes);
5939
- resolve3(bytes);
6047
+ resolve4(bytes);
5940
6048
  });
5941
6049
  });
5942
6050
  };
@@ -6128,7 +6236,7 @@ var require_checksum = __commonJS((exports) => {
6128
6236
  callback();
6129
6237
  }
6130
6238
  }
6131
- var fileStreamHasher = (hashCtor, fileStream) => new Promise((resolve3, reject) => {
6239
+ var fileStreamHasher = (hashCtor, fileStream) => new Promise((resolve4, reject) => {
6132
6240
  if (!isReadStream(fileStream)) {
6133
6241
  reject(new Error("Unable to calculate hash for non-file streams."));
6134
6242
  return;
@@ -6146,7 +6254,7 @@ var require_checksum = __commonJS((exports) => {
6146
6254
  });
6147
6255
  hashCalculator.on("error", reject);
6148
6256
  hashCalculator.on("finish", function() {
6149
- hash.digest().then(resolve3).catch(reject);
6257
+ hash.digest().then(resolve4).catch(reject);
6150
6258
  });
6151
6259
  });
6152
6260
  var isReadStream = (stream) => typeof stream.path === "string";
@@ -6157,14 +6265,14 @@ var require_checksum = __commonJS((exports) => {
6157
6265
  const hash = new hashCtor;
6158
6266
  const hashCalculator = new HashCalculator(hash);
6159
6267
  readableStream.pipe(hashCalculator);
6160
- return new Promise((resolve3, reject) => {
6268
+ return new Promise((resolve4, reject) => {
6161
6269
  readableStream.on("error", (err) => {
6162
6270
  hashCalculator.end();
6163
6271
  reject(err);
6164
6272
  });
6165
6273
  hashCalculator.on("error", reject);
6166
6274
  hashCalculator.on("finish", () => {
6167
- hash.digest().then(resolve3).catch(reject);
6275
+ hash.digest().then(resolve4).catch(reject);
6168
6276
  });
6169
6277
  });
6170
6278
  };
@@ -7270,7 +7378,7 @@ var require_event_streams = __commonJS((exports) => {
7270
7378
  streamEnded = true;
7271
7379
  });
7272
7380
  while (!generationEnded) {
7273
- const value = await new Promise((resolve3) => setTimeout(() => resolve3(records.shift()), 0));
7381
+ const value = await new Promise((resolve4) => setTimeout(() => resolve4(records.shift()), 0));
7274
7382
  if (value) {
7275
7383
  yield value;
7276
7384
  }
@@ -8150,8 +8258,8 @@ var require_protocols = __commonJS((exports) => {
8150
8258
  async build() {
8151
8259
  const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
8152
8260
  this.path = basePath;
8153
- for (const resolvePath of this.resolvePathStack) {
8154
- resolvePath(this.path);
8261
+ for (const resolvePath2 of this.resolvePathStack) {
8262
+ resolvePath2(this.path);
8155
8263
  }
8156
8264
  return new HttpRequest({
8157
8265
  protocol,
@@ -8765,7 +8873,7 @@ var require_retry = __commonJS((exports) => {
8765
8873
  }
8766
8874
  };
8767
8875
  }
8768
- var cooldown = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
8876
+ var cooldown = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
8769
8877
  var isRetryStrategyV2 = (retryStrategy) => typeof retryStrategy.acquireInitialRetryToken !== "undefined" && typeof retryStrategy.refreshRetryTokenForRetry !== "undefined" && typeof retryStrategy.recordSuccess !== "undefined";
8770
8878
  var getRetryErrorInfo = (error, logger) => {
8771
8879
  const errorInfo = {
@@ -8864,7 +8972,7 @@ var require_retry = __commonJS((exports) => {
8864
8972
  this.refillTokenBucket();
8865
8973
  while (amount > this.availableTokens) {
8866
8974
  const delay = (amount - this.availableTokens) / this.fillRate * 1000;
8867
- await new Promise((resolve3) => DefaultRateLimiter.setTimeoutFn(resolve3, delay));
8975
+ await new Promise((resolve4) => DefaultRateLimiter.setTimeoutFn(resolve4, delay));
8868
8976
  this.refillTokenBucket();
8869
8977
  }
8870
8978
  this.availableTokens = this.availableTokens - amount;
@@ -9206,7 +9314,7 @@ var require_retry = __commonJS((exports) => {
9206
9314
  const delayFromResponse = getDelayFromRetryAfterHeader(err.$response);
9207
9315
  const delay = Math.max(delayFromResponse || 0, delayFromDecider);
9208
9316
  totalDelay += delay;
9209
- await new Promise((resolve3) => setTimeout(resolve3, delay));
9317
+ await new Promise((resolve4) => setTimeout(resolve4, delay));
9210
9318
  continue;
9211
9319
  }
9212
9320
  if (!err.$metadata) {
@@ -12539,7 +12647,7 @@ var init_node_http = () => {};
12539
12647
 
12540
12648
  // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js
12541
12649
  function httpRequest(options) {
12542
- return new Promise((resolve3, reject) => {
12650
+ return new Promise((resolve4, reject) => {
12543
12651
  const req = node_http.request({
12544
12652
  method: "GET",
12545
12653
  ...options,
@@ -12564,7 +12672,7 @@ function httpRequest(options) {
12564
12672
  chunks.push(chunk);
12565
12673
  });
12566
12674
  res.on("end", () => {
12567
- resolve3(Buffer.concat(chunks));
12675
+ resolve4(Buffer.concat(chunks));
12568
12676
  req.destroy();
12569
12677
  });
12570
12678
  });
@@ -12788,9 +12896,9 @@ var import_config6, IMDS_PATH = "/latest/meta-data/iam/security-credentials/", I
12788
12896
  let fallbackBlockedFromProcessEnv = false;
12789
12897
  const configValue = await import_config6.loadConfig({
12790
12898
  environmentVariableSelector: (env) => {
12791
- const envValue = env[AWS_EC2_METADATA_V1_DISABLED];
12792
- fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false";
12793
- if (envValue === undefined) {
12899
+ const envValue2 = env[AWS_EC2_METADATA_V1_DISABLED];
12900
+ fallbackBlockedFromProcessEnv = !!envValue2 && envValue2 !== "false";
12901
+ if (envValue2 === undefined) {
12794
12902
  throw new import_config6.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`, { logger: init.logger });
12795
12903
  }
12796
12904
  return fallbackBlockedFromProcessEnv;
@@ -13058,21 +13166,21 @@ var require_dist_cjs4 = __commonJS((exports) => {
13058
13166
  let sendBody = true;
13059
13167
  if (!externalAgent && expect === "100-continue") {
13060
13168
  sendBody = await Promise.race([
13061
- new Promise((resolve3) => {
13062
- timeoutId = Number(timing.setTimeout(() => resolve3(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
13169
+ new Promise((resolve4) => {
13170
+ timeoutId = Number(timing.setTimeout(() => resolve4(true), Math.max(MIN_WAIT_TIME, maxContinueTimeoutMs)));
13063
13171
  }),
13064
- new Promise((resolve3) => {
13172
+ new Promise((resolve4) => {
13065
13173
  httpRequest2.on("continue", () => {
13066
13174
  timing.clearTimeout(timeoutId);
13067
- resolve3(true);
13175
+ resolve4(true);
13068
13176
  });
13069
13177
  httpRequest2.on("response", () => {
13070
13178
  timing.clearTimeout(timeoutId);
13071
- resolve3(false);
13179
+ resolve4(false);
13072
13180
  });
13073
13181
  httpRequest2.on("error", () => {
13074
13182
  timing.clearTimeout(timeoutId);
13075
- resolve3(false);
13183
+ resolve4(false);
13076
13184
  });
13077
13185
  })
13078
13186
  ]);
@@ -13147,13 +13255,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13147
13255
  return socketWarningTimestamp;
13148
13256
  }
13149
13257
  constructor(options) {
13150
- this.configProvider = new Promise((resolve3, reject) => {
13258
+ this.configProvider = new Promise((resolve4, reject) => {
13151
13259
  if (typeof options === "function") {
13152
13260
  options().then((_options) => {
13153
- resolve3(this.resolveDefaultConfig(_options));
13261
+ resolve4(this.resolveDefaultConfig(_options));
13154
13262
  }).catch(reject);
13155
13263
  } else {
13156
- resolve3(this.resolveDefaultConfig(options));
13264
+ resolve4(this.resolveDefaultConfig(options));
13157
13265
  }
13158
13266
  });
13159
13267
  }
@@ -13185,7 +13293,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13185
13293
  timing.clearTimeout(socketTimeoutId);
13186
13294
  timing.clearTimeout(keepAliveTimeoutId);
13187
13295
  };
13188
- const resolve3 = async (arg) => {
13296
+ const resolve4 = async (arg) => {
13189
13297
  await writeRequestBodyPromise;
13190
13298
  clearTimeouts();
13191
13299
  _resolve(arg);
@@ -13249,7 +13357,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13249
13357
  headers: getTransformedHeaders(res.headers),
13250
13358
  body: res
13251
13359
  });
13252
- resolve3({ response: httpResponse });
13360
+ resolve4({ response: httpResponse });
13253
13361
  });
13254
13362
  req.on("error", (err) => {
13255
13363
  if (NODEJS_TIMEOUT_ERROR_CODES.includes(err.code)) {
@@ -13581,13 +13689,13 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13581
13689
  return new NodeHttp2Handler(instanceOrOptions);
13582
13690
  }
13583
13691
  constructor(options) {
13584
- this.configProvider = new Promise((resolve3, reject) => {
13692
+ this.configProvider = new Promise((resolve4, reject) => {
13585
13693
  if (typeof options === "function") {
13586
13694
  options().then((opts) => {
13587
- resolve3(opts || {});
13695
+ resolve4(opts || {});
13588
13696
  }).catch(reject);
13589
13697
  } else {
13590
- resolve3(options || {});
13698
+ resolve4(options || {});
13591
13699
  }
13592
13700
  });
13593
13701
  }
@@ -13612,7 +13720,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13612
13720
  return new Promise((_resolve, _reject) => {
13613
13721
  let fulfilled = false;
13614
13722
  let writeRequestBodyPromise = undefined;
13615
- const resolve3 = async (arg) => {
13723
+ const resolve4 = async (arg) => {
13616
13724
  await writeRequestBodyPromise;
13617
13725
  _resolve(arg);
13618
13726
  };
@@ -13697,7 +13805,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
13697
13805
  body: clientHttp2Stream
13698
13806
  });
13699
13807
  fulfilled = true;
13700
- resolve3({ response: httpResponse });
13808
+ resolve4({ response: httpResponse });
13701
13809
  if (useIsolatedSession) {
13702
13810
  session.close();
13703
13811
  }
@@ -13823,7 +13931,7 @@ var retryWrapper = (toRetry, maxRetries, delayMs) => {
13823
13931
  try {
13824
13932
  return await toRetry();
13825
13933
  } catch (e) {
13826
- await new Promise((resolve3) => setTimeout(resolve3, delayMs));
13934
+ await new Promise((resolve4) => setTimeout(resolve4, delayMs));
13827
13935
  }
13828
13936
  }
13829
13937
  return await toRetry();
@@ -23031,8 +23139,8 @@ var require_signin = __commonJS((exports) => {
23031
23139
  // ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
23032
23140
  import { createHash as createHash2, createPrivateKey, createPublicKey, sign } from "crypto";
23033
23141
  import { promises as fs2 } from "fs";
23034
- import { homedir as homedir2 } from "os";
23035
- import { dirname as dirname3, join as join3 } from "path";
23142
+ import { homedir as homedir4 } from "os";
23143
+ import { dirname as dirname3, join as join5 } from "path";
23036
23144
  var import_config20, import_protocols3, LoginCredentialsFetcher;
23037
23145
  var init_LoginCredentialsFetcher = __esm(() => {
23038
23146
  import_config20 = __toESM(require_config(), 1);
@@ -23199,10 +23307,10 @@ var init_LoginCredentialsFetcher = __esm(() => {
23199
23307
  await fs2.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
23200
23308
  }
23201
23309
  getTokenFilePath() {
23202
- const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join3(homedir2(), ".aws", "login", "cache");
23310
+ const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join5(homedir4(), ".aws", "login", "cache");
23203
23311
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
23204
23312
  const loginSessionSha256 = createHash2("sha256").update(loginSessionBytes).digest("hex");
23205
- return join3(directory, `${loginSessionSha256}.json`);
23313
+ return join5(directory, `${loginSessionSha256}.json`);
23206
23314
  }
23207
23315
  derToRawSignature(derSignature) {
23208
23316
  let offset = 2;
@@ -23627,6 +23735,7 @@ var init_dist_es9 = __esm(() => {
23627
23735
  // ../contracts/dist/client/storage.js
23628
23736
  import { isIP } from "net";
23629
23737
  import { readFileSync, statSync } from "fs";
23738
+ import { createRequire } from "module";
23630
23739
  import { join } from "path";
23631
23740
  function envToken(name) {
23632
23741
  return name.toUpperCase().replace(/-/g, "_");
@@ -23642,6 +23751,9 @@ function credentialOverrideEnvKey(name) {
23642
23751
  return `HASNA_${envToken(name)}_API_KEY_OVERRIDE`;
23643
23752
  }
23644
23753
  var CREDENTIAL_PROFILE_ENV_KEY = "HASNA_PROFILE";
23754
+ function credentialPointerEnvKey(name) {
23755
+ return `HASNA_${envToken(name)}_API_KEY_REF`;
23756
+ }
23645
23757
 
23646
23758
  class CredentialResolutionError extends Error {
23647
23759
  appName;
@@ -23654,31 +23766,55 @@ class CredentialResolutionError extends Error {
23654
23766
  }
23655
23767
  }
23656
23768
  var HASNA_STATE_DIR = ".hasna";
23657
- var FLEET_CREDENTIAL_DIR = "cloud";
23769
+ var FLEET_CREDENTIAL_DIR = "fleet-env";
23770
+ var LEGACY_CLOUD_DIR = "cloud";
23658
23771
  var CONFIG_DIR = ".config";
23659
23772
  var CONFIG_NAMESPACE = "hasna";
23773
+ var LEGACY_CLOUD_REMOVAL_DEADLINE = "2026-10-01";
23660
23774
  var MAX_CREDENTIAL_FILE_BYTES = 64 * 1024;
23661
23775
  var SAFE_APP_SLUG = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
23662
23776
  var SAFE_PROFILE = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
23663
23777
  var ILLEGAL_IN_HEADER_VALUE = /[^\t\x20-\x7e]/;
23778
+ var VAULT_POINTER_SHAPE = /^[a-z0-9][a-z0-9-]*(?:\/[a-z0-9][a-z0-9-_.]*){2,}$/;
23664
23779
  function homeDir(env) {
23665
23780
  const home = env.HOME?.trim();
23666
23781
  return home ? home : null;
23667
23782
  }
23668
- function credentialDiskSources(name, env) {
23669
- return profileDiskSources(name, env, null);
23670
- }
23671
- function profileDiskSources(name, env, profile) {
23783
+ function credentialDiskSourceList(name, env, profile = null) {
23672
23784
  const home = homeDir(env);
23673
23785
  if (!home || !SAFE_APP_SLUG.test(name))
23674
23786
  return [];
23675
23787
  const stem = profile ? `${name}.${profile}` : name;
23676
23788
  const configStem = profile ? `${name}-${profile}` : name;
23677
23789
  return [
23678
- join(home, HASNA_STATE_DIR, FLEET_CREDENTIAL_DIR, `${stem}.env`),
23679
- join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}-cloud.env`)
23790
+ {
23791
+ path: join(home, HASNA_STATE_DIR, FLEET_CREDENTIAL_DIR, `${stem}.env`),
23792
+ tier: "fleet-env",
23793
+ deprecated: false
23794
+ },
23795
+ {
23796
+ path: join(home, HASNA_STATE_DIR, LEGACY_CLOUD_DIR, `${stem}.env`),
23797
+ tier: "legacy-cloud",
23798
+ deprecated: true
23799
+ },
23800
+ {
23801
+ path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}.env`),
23802
+ tier: "config",
23803
+ deprecated: false
23804
+ },
23805
+ {
23806
+ path: join(home, CONFIG_DIR, CONFIG_NAMESPACE, `${configStem}-cloud.env`),
23807
+ tier: "config-legacy",
23808
+ deprecated: true
23809
+ }
23680
23810
  ];
23681
23811
  }
23812
+ function credentialDiskSources(name, env) {
23813
+ return credentialDiskSourceList(name, env, null).map((s) => s.path);
23814
+ }
23815
+ function profileDiskSources(name, env, profile) {
23816
+ return credentialDiskSourceList(name, env, profile).map((s) => s.path);
23817
+ }
23682
23818
  function parseEnvFile(text) {
23683
23819
  const values = new Map;
23684
23820
  for (const rawLine of text.split(/\r?\n/)) {
@@ -23746,6 +23882,9 @@ function appConfigDiskValue(name, env, keys) {
23746
23882
  return null;
23747
23883
  }
23748
23884
  function assertUsableCredential(appName, source, value) {
23885
+ if (VAULT_POINTER_SHAPE.test(value)) {
23886
+ 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]);
23887
+ }
23749
23888
  if (!ILLEGAL_IN_HEADER_VALUE.test(value))
23750
23889
  return;
23751
23890
  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]);
@@ -23770,6 +23909,14 @@ function sealCredential(fields) {
23770
23909
  writable: false,
23771
23910
  configurable: false
23772
23911
  });
23912
+ if (fields.pointerVaultKey !== undefined) {
23913
+ Object.defineProperty(sealed, "pointerVaultKey", {
23914
+ value: fields.pointerVaultKey,
23915
+ enumerable: false,
23916
+ writable: false,
23917
+ configurable: false
23918
+ });
23919
+ }
23773
23920
  Object.defineProperty(sealed, INSPECT_CUSTOM, {
23774
23921
  value: () => ({ ...visible, apiKey: "[redacted]" }),
23775
23922
  enumerable: false,
@@ -23821,7 +23968,8 @@ function validateAndSealResolvedCredential(appName, credential) {
23821
23968
  deliberate: credential.deliberate,
23822
23969
  deprecated: credential.deprecated,
23823
23970
  diskCandidates: credential.diskCandidates,
23824
- warning: credential.warning
23971
+ warning: credential.warning,
23972
+ ...credential.pointerVaultKey !== undefined ? { pointerVaultKey: credential.pointerVaultKey } : {}
23825
23973
  });
23826
23974
  }
23827
23975
  function firstEnvValue(env, keys) {
@@ -23882,6 +24030,27 @@ function resolveCredential(name, env, options = {}) {
23882
24030
  warning: null
23883
24031
  });
23884
24032
  }
24033
+ const pointerKeyName = credentialPointerEnvKey(name);
24034
+ const pointerRaw = env[pointerKeyName];
24035
+ if (pointerRaw !== undefined) {
24036
+ const pointer = pointerRaw.trim();
24037
+ if (!pointer) {
24038
+ 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]);
24039
+ }
24040
+ if (!VAULT_POINTER_SHAPE.test(pointer)) {
24041
+ 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]);
24042
+ }
24043
+ return sealCredential({
24044
+ apiKey: "",
24045
+ pointerVaultKey: pointer,
24046
+ tier: "pointer",
24047
+ source: pointerKeyName,
24048
+ deliberate: true,
24049
+ deprecated: false,
24050
+ diskCandidates: diskPaths,
24051
+ warning: null
24052
+ });
24053
+ }
23885
24054
  const profile = options.profile?.trim() || env[CREDENTIAL_PROFILE_ENV_KEY]?.trim();
23886
24055
  if (profile) {
23887
24056
  const profileSource = options.profile?.trim() ? "explicit profile argument" : CREDENTIAL_PROFILE_ENV_KEY;
@@ -23906,26 +24075,42 @@ function resolveCredential(name, env, options = {}) {
23906
24075
  }
23907
24076
  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);
23908
24077
  }
23909
- const diskHits = diskPaths.map((path) => ({ path, value: readCredentialFile(path, apiKeyKeys) })).filter((hit) => hit.value !== null);
24078
+ const diskSourceList = credentialDiskSourceList(name, env, null);
24079
+ const diskHits = diskSourceList.map((src) => ({ src, value: readCredentialFile(src.path, apiKeyKeys) })).filter((hit) => hit.value !== null);
23910
24080
  if (diskHits.length > 0) {
23911
24081
  const winner = diskHits[0];
23912
- assertUsableCredential(name, winner.path, winner.value);
24082
+ assertUsableCredential(name, winner.src.path, winner.value);
23913
24083
  const divergentSources = [
23914
- ...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.path),
24084
+ ...diskHits.slice(1).filter((hit) => hit.value !== winner.value).map((hit) => hit.src.path),
23915
24085
  ...(() => {
23916
24086
  const legacyHit = firstEnvValue(env, apiKeyKeys);
23917
24087
  return legacyHit && legacyHit.value !== winner.value ? [legacyHit.key] : [];
23918
24088
  })()
23919
24089
  ];
23920
- 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;
24090
+ 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;
24091
+ let deprecated = winner.src.deprecated;
24092
+ let finalWarning = warning;
24093
+ if (winner.src.deprecated) {
24094
+ deprecated = true;
24095
+ const sink = options.onDeprecation ?? defaultDeprecationSink;
24096
+ const notified = deprecationNotified();
24097
+ const noticeKey = `${name}:${winner.src.path}`;
24098
+ if (!notified.has(noticeKey)) {
24099
+ notified.add(noticeKey);
24100
+ const target = diskSourceList[0]?.path ?? "<none>";
24101
+ 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.`;
24102
+ sink(message);
24103
+ }
24104
+ finalWarning = [warning, `Legacy credential source: ${winner.src.path}. Removed after ${LEGACY_CLOUD_REMOVAL_DEADLINE}.`].filter(Boolean).join(" ") || null;
24105
+ }
23921
24106
  return sealCredential({
23922
24107
  apiKey: winner.value,
23923
- tier: "disk",
23924
- source: winner.path,
24108
+ tier: winner.src.tier,
24109
+ source: winner.src.path,
23925
24110
  deliberate: false,
23926
- deprecated: false,
24111
+ deprecated,
23927
24112
  diskCandidates: diskPaths,
23928
- warning
24113
+ warning: finalWarning
23929
24114
  });
23930
24115
  }
23931
24116
  const legacy = firstEnvValue(env, apiKeyKeys);
@@ -23951,6 +24136,47 @@ function resolveCredential(name, env, options = {}) {
23951
24136
  }
23952
24137
  return null;
23953
24138
  }
24139
+ var SECRETS_PACKAGE_SPECIFIER = "@hasna/" + "secrets";
24140
+ var requireSecretsSdk = createRequire(import.meta.url);
24141
+ async function completePointerCredential(name, pointerResolution, env = process.env) {
24142
+ const vaultKey = pointerResolution.pointerVaultKey;
24143
+ const pointerEnvKey = pointerResolution.source;
24144
+ if (!vaultKey) {
24145
+ throw new CredentialResolutionError(name, `Pointer resolution from ${pointerEnvKey} carries no vault item key; this is a defect in the resolver.`, [pointerEnvKey]);
24146
+ }
24147
+ let secretsSdk;
24148
+ try {
24149
+ secretsSdk = requireSecretsSdk(SECRETS_PACKAGE_SPECIFIER);
24150
+ } catch {
24151
+ 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]);
24152
+ }
24153
+ let client;
24154
+ try {
24155
+ client = secretsSdk.createSecretsClientFromEnv(env);
24156
+ } catch {
24157
+ 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]);
24158
+ }
24159
+ let secret;
24160
+ try {
24161
+ secret = await client.getSecret({ key: vaultKey });
24162
+ } catch {
24163
+ 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]);
24164
+ }
24165
+ const value = secret.value;
24166
+ if (!value) {
24167
+ throw new CredentialResolutionError(name, `${pointerEnvKey} resolved vault item '${vaultKey}', but it holds no value. A vault pointer is TERMINAL.`, [pointerEnvKey]);
24168
+ }
24169
+ assertUsableCredential(name, `${pointerEnvKey} -> vault:${vaultKey}`, value);
24170
+ return sealCredential({
24171
+ apiKey: value,
24172
+ tier: "pointer",
24173
+ source: `${pointerEnvKey} -> vault:${vaultKey}`,
24174
+ deliberate: true,
24175
+ deprecated: false,
24176
+ diskCandidates: pointerResolution.diskCandidates,
24177
+ warning: null
24178
+ });
24179
+ }
23954
24180
  var ASCII_CONTROL_PATTERN = /[\u0000-\u001f\u007f]/;
23955
24181
  var DNS_LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
23956
24182
  function isValidDnsDomain(value) {
@@ -24196,6 +24422,13 @@ function currentCredential(name, apiKey) {
24196
24422
  }
24197
24423
  return explicitCredential(name, apiKey);
24198
24424
  }
24425
+ async function resolveRequestCredential(name, apiKey, env = process.env) {
24426
+ const resolved = currentCredential(name, apiKey);
24427
+ if (resolved.tier === "pointer") {
24428
+ return completePointerCredential(name, resolved, env);
24429
+ }
24430
+ return resolved;
24431
+ }
24199
24432
  function authFailureGuidance(credential) {
24200
24433
  const origin = `The API key for this request came from ${credential.source}`;
24201
24434
  if (credential.deliberate) {
@@ -24351,7 +24584,7 @@ function createHasnaHttpTransport(options) {
24351
24584
  const retry = resolveRetry(opts.retry);
24352
24585
  const methodRetryable = IDEMPOTENT_METHODS.has(upper) || Boolean(opts.idempotencyKey);
24353
24586
  const maxAttempts = retry && methodRetryable ? retry.retries + 1 : 1;
24354
- const credential = currentCredential(options.name, options.apiKey);
24587
+ const credential = await resolveRequestCredential(options.name, options.apiKey);
24355
24588
  let last = null;
24356
24589
  for (let attempt = 1;attempt <= maxAttempts; attempt++) {
24357
24590
  const result = await once(upper, rel, url, body, opts, credential);
@@ -24516,6 +24749,7 @@ function resolveStorageClient(name, env = process.env, overrides) {
24516
24749
  }
24517
24750
 
24518
24751
  // ../contracts/dist/client/transport.js
24752
+ import { createRequire as createRequire2 } from "module";
24519
24753
  function envToken2(name) {
24520
24754
  return name.toUpperCase().replace(/-/g, "_");
24521
24755
  }
@@ -24530,6 +24764,8 @@ var MAX_CREDENTIAL_FILE_BYTES2 = 64 * 1024;
24530
24764
  var INSPECT_CUSTOM2 = Symbol.for("nodejs.util.inspect.custom");
24531
24765
  var CREDENTIAL_SEAL2 = Symbol.for("hasna:contracts:sealedCredential");
24532
24766
  var DEPRECATION_REGISTRY2 = Symbol.for("hasna:contracts:credentialDeprecationNotices");
24767
+ var SECRETS_PACKAGE_SPECIFIER2 = "@hasna/" + "secrets";
24768
+ var requireSecretsSdk2 = createRequire2(import.meta.url);
24533
24769
  var IDEMPOTENT_METHODS2 = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
24534
24770
  var AUTHORITY_OVERRIDE_HEADERS2 = new Set([
24535
24771
  "host",
@@ -24961,7 +25197,7 @@ function deleteDomainReputation(id) {
24961
25197
  }
24962
25198
 
24963
25199
  // src/db/store.ts
24964
- var APP = "domains";
25200
+ var APP2 = "domains";
24965
25201
  var DOMAINS_PAGE_SIZE = 1000;
24966
25202
  class LocalStore {
24967
25203
  transport = "local";
@@ -25574,7 +25810,7 @@ function assertNoStoreConflict(env) {
25574
25810
  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.`);
25575
25811
  }
25576
25812
  function requireHostedClient(env, flip) {
25577
- const resolved = resolveStorageClient(APP, withoutRetiredModeKeys(env));
25813
+ const resolved = resolveStorageClient(APP2, withoutRetiredModeKeys(env));
25578
25814
  if (resolved.transport !== "http") {
25579
25815
  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.`);
25580
25816
  }
@@ -25609,7 +25845,7 @@ import { domainToASCII } from "url";
25609
25845
 
25610
25846
  // src/lib/version.ts
25611
25847
  import { readFileSync as readFileSync3 } from "fs";
25612
- import { dirname as dirname2, resolve as resolve2 } from "path";
25848
+ import { dirname as dirname2, resolve as resolve3 } from "path";
25613
25849
  import { fileURLToPath } from "url";
25614
25850
  var cachedVersion = null;
25615
25851
  function getPackageVersion() {
@@ -25617,7 +25853,7 @@ function getPackageVersion() {
25617
25853
  return cachedVersion;
25618
25854
  try {
25619
25855
  const moduleDir = dirname2(fileURLToPath(import.meta.url));
25620
- const packageJsonPath = resolve2(moduleDir, "../../package.json");
25856
+ const packageJsonPath = resolve3(moduleDir, "../../package.json");
25621
25857
  const pkg = JSON.parse(readFileSync3(packageJsonPath, "utf8"));
25622
25858
  cachedVersion = pkg.version ?? "0.0.0";
25623
25859
  } catch {