ultraenv 1.0.0 → 1.0.2

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.
Files changed (71) hide show
  1. package/README.md +67 -1857
  2. package/dist/{chunk-GC7RXHLA.js → chunk-2MBSLURI.js} +16 -17
  3. package/dist/{chunk-IGFVP24Q.js → chunk-3AF476D7.js} +1 -1
  4. package/dist/{chunk-N5PAV4NM.js → chunk-5WUBB633.js} +17 -26
  5. package/dist/{chunk-2USZPWLZ.js → chunk-6NFA23AY.js} +28 -39
  6. package/dist/{chunk-AWN6ADV7.js → chunk-6X3BUE5S.js} +45 -54
  7. package/dist/{chunk-NBOABPHM.js → chunk-72UKVOO5.js} +24 -40
  8. package/dist/{chunk-JB7RKV3C.js → chunk-7AHG2IP4.js} +1 -7
  9. package/dist/{chunk-6KS56D6E.js → chunk-7VJ7LK2M.js} +1 -1
  10. package/dist/{chunk-CIFMBJ4H.js → chunk-BNUHE2ZI.js} +57 -21
  11. package/dist/{chunk-HFXQGJY3.js → chunk-CVJPO3QY.js} +13 -27
  12. package/dist/{chunk-IKPTKALB.js → chunk-F7YSINGU.js} +1 -3
  13. package/dist/{chunk-3VYXPTYV.js → chunk-FSKVYBEP.js} +1 -1
  14. package/dist/{chunk-4XUYMRK5.js → chunk-GJC64ZG7.js} +4 -3
  15. package/dist/{chunk-YMMP4VQL.js → chunk-H3QEGEZ6.js} +1 -1
  16. package/dist/{chunk-CHVO6NWI.js → chunk-LFIKYFPS.js} +2 -2
  17. package/dist/{chunk-3UV2QNJL.js → chunk-LJSCUOD4.js} +19 -21
  18. package/dist/{chunk-YVWLXFUT.js → chunk-LQZK6BBQ.js} +2 -2
  19. package/dist/{chunk-5G2DU52U.js → chunk-N7GOHQBF.js} +7 -1
  20. package/dist/{chunk-MSXMESFP.js → chunk-OBLMAUCF.js} +8 -14
  21. package/dist/{chunk-UEWYFN6A.js → chunk-RJTUAMK3.js} +16 -29
  22. package/dist/{chunk-MNVFG7H4.js → chunk-XPZC32UY.js} +16 -25
  23. package/dist/{chunk-WMHN5RW2.js → chunk-YLGJQOMM.js} +3 -9
  24. package/dist/{ci-check-sync-VBMSVWIV.js → ci-check-sync-UO5PARKO.js} +4 -4
  25. package/dist/{ci-scan-24MT5XGS.js → ci-scan-5D7QBN5X.js} +2 -5
  26. package/dist/{ci-setup-C2NKEFRD.js → ci-setup-J34DS6KD.js} +2 -2
  27. package/dist/{ci-validate-7AW24LSQ.js → ci-validate-LWP5NBDN.js} +4 -4
  28. package/dist/cli/index.cjs +470 -390
  29. package/dist/cli/index.js +130 -55
  30. package/dist/comparator-AIRTWBOL.js +13 -0
  31. package/dist/{config-O5YRQP5Z.js → config-67GDO3CW.js} +3 -3
  32. package/dist/{debug-PTPXAF3K.js → debug-6VCX3QSP.js} +6 -6
  33. package/dist/{declaration-LEME4AFZ.js → declaration-YGOVZOXG.js} +3 -3
  34. package/dist/{doctor-FZAUPKHS.js → doctor-FF7QOTP2.js} +7 -5
  35. package/dist/{envs-compare-5K3HESX5.js → envs-compare-P7GPKGQX.js} +4 -4
  36. package/dist/{envs-create-2XXHXMGA.js → envs-create-ISG4SECU.js} +4 -4
  37. package/dist/{envs-list-NQM5252B.js → envs-list-PUW67HOC.js} +5 -5
  38. package/dist/{envs-switch-6L2AQYID.js → envs-switch-P4YDJ6LG.js} +4 -4
  39. package/dist/{envs-validate-FL73Q76T.js → envs-validate-VNKBKYO3.js} +6 -9
  40. package/dist/{fs-VH7ATUS3.js → fs-7HKOZY5K.js} +2 -2
  41. package/dist/{generator-LFZBMZZS.js → generator-O23ATCIY.js} +4 -4
  42. package/dist/{help-3XJBXEHE.js → help-THFLI6YT.js} +108 -26
  43. package/dist/index.cjs +295 -381
  44. package/dist/index.d.cts +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.js +81 -100
  47. package/dist/{init-Y7JQ2KYJ.js → init-KBLVTHQW.js} +15 -11
  48. package/dist/{install-hook-SKXIV6NV.js → install-hook-42F22BLY.js} +2 -2
  49. package/dist/{json-schema-I26YNQBH.js → json-schema-YULPWDKA.js} +3 -3
  50. package/dist/{key-manager-O3G55WPU.js → key-manager-WDWPX3IQ.js} +3 -3
  51. package/dist/middleware/express.cjs +1 -3
  52. package/dist/middleware/express.js +1 -1
  53. package/dist/middleware/fastify.cjs +1 -7
  54. package/dist/middleware/fastify.js +1 -1
  55. package/dist/{module-IDIZPP4M.js → module-FGH2V6N2.js} +3 -3
  56. package/dist/{protect-NCWPM6VC.js → protect-A4G7LQFJ.js} +26 -24
  57. package/dist/{scan-TRLY36TT.js → scan-4BXGHR33.js} +1 -1
  58. package/dist/schema/index.cjs +57 -21
  59. package/dist/schema/index.js +1 -1
  60. package/dist/{sync-TMHMTLH2.js → sync-MYLMDDY6.js} +23 -14
  61. package/dist/{typegen-SQOSXBWM.js → typegen-GLBRHWSK.js} +17 -23
  62. package/dist/{validate-IOAM5HWS.js → validate-J73ETKXD.js} +5 -5
  63. package/dist/{vault-decrypt-U6HJZNBV.js → vault-decrypt-V3GY5HES.js} +7 -7
  64. package/dist/{vault-diff-B3ZOQTWI.js → vault-diff-QVE6S6KP.js} +5 -5
  65. package/dist/{vault-encrypt-GUSLCSKS.js → vault-encrypt-WUBY3OVF.js} +7 -7
  66. package/dist/{vault-init-GUBOTOUL.js → vault-init-EWSAED44.js} +5 -5
  67. package/dist/{vault-rekey-DAHT7JCN.js → vault-rekey-VODMGCNA.js} +7 -7
  68. package/dist/{vault-status-GDLRU2OK.js → vault-status-YXDK6O7X.js} +4 -4
  69. package/dist/{vault-verify-CD76FJSF.js → vault-verify-SSXGTVBK.js} +7 -7
  70. package/package.json +1 -1
  71. package/dist/comparator-RDKX3OI7.js +0 -13
@@ -317,9 +317,7 @@ function resolveVariables(vars, schema, aliasMap) {
317
317
  result[key] = vars[key];
318
318
  continue;
319
319
  }
320
- const caseInsensitiveKey = Object.keys(vars).find(
321
- (k) => k.toLowerCase() === key.toLowerCase()
322
- );
320
+ const caseInsensitiveKey = Object.keys(vars).find((k) => k.toLowerCase() === key.toLowerCase());
323
321
  if (caseInsensitiveKey !== void 0 && vars[caseInsensitiveKey] !== void 0) {
324
322
  result[key] = vars[caseInsensitiveKey];
325
323
  continue;
@@ -332,9 +330,7 @@ function resolveVariables(vars, schema, aliasMap) {
332
330
  foundAlias = true;
333
331
  break;
334
332
  }
335
- const ciAlias = Object.keys(vars).find(
336
- (k) => k.toLowerCase() === alias.toLowerCase()
337
- );
333
+ const ciAlias = Object.keys(vars).find((k) => k.toLowerCase() === alias.toLowerCase());
338
334
  if (ciAlias !== void 0 && vars[ciAlias] !== void 0) {
339
335
  result[key] = vars[ciAlias];
340
336
  foundAlias = true;
@@ -360,7 +356,10 @@ function validateValue(rawValue, builder) {
360
356
  if (builder.meta.required) {
361
357
  return { success: false, error: "Value is required" };
362
358
  }
363
- return { success: false, error: "Value is undefined and optional (use defineEnv for proper handling)" };
359
+ return {
360
+ success: false,
361
+ error: "Value is undefined and optional (use defineEnv for proper handling)"
362
+ };
364
363
  }
365
364
  return builder._parse(rawValue);
366
365
  }
@@ -1533,7 +1532,10 @@ function parseAndValidateEmail(raw, opts) {
1533
1532
  return { success: false, error: "Email must not be empty" };
1534
1533
  }
1535
1534
  if (trimmed.length > maxLen) {
1536
- return { success: false, error: `Email must be at most ${maxLen} characters, got ${trimmed.length}` };
1535
+ return {
1536
+ success: false,
1537
+ error: `Email must be at most ${maxLen} characters, got ${trimmed.length}`
1538
+ };
1537
1539
  }
1538
1540
  if (!EMAIL_REGEX2.test(trimmed)) {
1539
1541
  return { success: false, error: `"${trimmed}" is not a valid email address` };
@@ -1542,7 +1544,10 @@ function parseAndValidateEmail(raw, opts) {
1542
1544
  const localPart = trimmed.slice(0, atIndex);
1543
1545
  const domain = trimmed.slice(atIndex + 1);
1544
1546
  if (localPart.length > maxLocal) {
1545
- return { success: false, error: `Email local part must be at most ${maxLocal} characters, got ${localPart.length}` };
1547
+ return {
1548
+ success: false,
1549
+ error: `Email local part must be at most ${maxLocal} characters, got ${localPart.length}`
1550
+ };
1546
1551
  }
1547
1552
  if (opts.allowPlusAddressing === false && localPart.includes("+")) {
1548
1553
  return { success: false, error: "Plus addressing (+) is not allowed" };
@@ -1551,7 +1556,10 @@ function parseAndValidateEmail(raw, opts) {
1551
1556
  const tld = domain.split(".").pop() ?? "";
1552
1557
  const allowed = opts.allowedTlds.map((t2) => t2.toLowerCase());
1553
1558
  if (!allowed.includes(tld.toLowerCase())) {
1554
- return { success: false, error: `Email TLD must be one of: ${allowed.join(", ")}. Got ".${tld}"` };
1559
+ return {
1560
+ success: false,
1561
+ error: `Email TLD must be one of: ${allowed.join(", ")}. Got ".${tld}"`
1562
+ };
1555
1563
  }
1556
1564
  }
1557
1565
  if (opts.blockedDomains !== void 0) {
@@ -1586,7 +1594,10 @@ function parseAndValidateIp(raw, opts) {
1586
1594
  }
1587
1595
  if (version === "6" && !isV6) {
1588
1596
  if (opts.allowMappedV4 === false && isMappedV4) {
1589
- return { success: false, error: `"${trimmed}" is an IPv4-mapped IPv6 address, which is not allowed` };
1597
+ return {
1598
+ success: false,
1599
+ error: `"${trimmed}" is an IPv4-mapped IPv6 address, which is not allowed`
1600
+ };
1590
1601
  }
1591
1602
  return { success: false, error: `"${trimmed}" is not a valid IPv6 address` };
1592
1603
  }
@@ -1594,7 +1605,10 @@ function parseAndValidateIp(raw, opts) {
1594
1605
  return { success: false, error: `"${trimmed}" is not a valid IP address` };
1595
1606
  }
1596
1607
  if (version === "6" && isMappedV4 && opts.allowMappedV4 === false) {
1597
- return { success: false, error: `"${trimmed}" is an IPv4-mapped IPv6 address, which is not allowed` };
1608
+ return {
1609
+ success: false,
1610
+ error: `"${trimmed}" is an IPv4-mapped IPv6 address, which is not allowed`
1611
+ };
1598
1612
  }
1599
1613
  return { success: true, value: trimmed };
1600
1614
  }
@@ -1943,7 +1957,9 @@ function createBase64Schema(opts) {
1943
1957
  var SEMVER_CORE = "(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)";
1944
1958
  var SEMVER_PRERELEASE = "(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))";
1945
1959
  var SEMVER_BUILD = "(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))";
1946
- var STRICT_SEMVER_REGEX = new RegExp(`^${SEMVER_CORE}(?:${SEMVER_PRERELEASE})?(?:${SEMVER_BUILD})?$`);
1960
+ var STRICT_SEMVER_REGEX = new RegExp(
1961
+ `^${SEMVER_CORE}(?:${SEMVER_PRERELEASE})?(?:${SEMVER_BUILD})?$`
1962
+ );
1947
1963
  var LOOSE_SEMVER_REGEX = /^v?(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
1948
1964
  function parseAndValidateSemver(raw, opts) {
1949
1965
  const trimmed = raw.trim();
@@ -1965,7 +1981,9 @@ function parseAndValidateSemver(raw, opts) {
1965
1981
  };
1966
1982
  }
1967
1983
  if (!loose) {
1968
- const match = content.match(new RegExp(`^${SEMVER_CORE}(?:${SEMVER_PRERELEASE})?(?:${SEMVER_BUILD})?$`));
1984
+ const match = content.match(
1985
+ new RegExp(`^${SEMVER_CORE}(?:${SEMVER_PRERELEASE})?(?:${SEMVER_BUILD})?$`)
1986
+ );
1969
1987
  if (match) {
1970
1988
  const prerelease = match[4];
1971
1989
  const build = match[5];
@@ -2069,7 +2087,14 @@ function parseAndValidateCron(raw, opts) {
2069
2087
  }
2070
2088
  const fields = trimmed.split(/\s+/);
2071
2089
  if (opts.allowSeconds === true && fields.length === 6) {
2072
- const ranges = [[0, 59], [0, 59], [0, 23], [1, 31], [1, 12], [0, 6]];
2090
+ const ranges = [
2091
+ [0, 59],
2092
+ [0, 59],
2093
+ [0, 23],
2094
+ [1, 31],
2095
+ [1, 12],
2096
+ [0, 6]
2097
+ ];
2073
2098
  for (let i = 0; i < fields.length; i++) {
2074
2099
  const range = ranges[i] ?? [0, 59];
2075
2100
  const error = validateCronField(fields[i] ?? "", range[0] ?? 0, range[1] ?? 0);
@@ -2078,7 +2103,14 @@ function parseAndValidateCron(raw, opts) {
2078
2103
  return { success: true, value: trimmed };
2079
2104
  }
2080
2105
  if (opts.allowYear === true && fields.length === 6) {
2081
- const ranges = [[0, 59], [0, 23], [1, 31], [1, 12], [0, 6], [1970, 2099]];
2106
+ const ranges = [
2107
+ [0, 59],
2108
+ [0, 23],
2109
+ [1, 31],
2110
+ [1, 12],
2111
+ [0, 6],
2112
+ [1970, 2099]
2113
+ ];
2082
2114
  for (let i = 0; i < fields.length; i++) {
2083
2115
  const range = ranges[i] ?? [0, 59];
2084
2116
  const error = validateCronField(fields[i] ?? "", range[0] ?? 0, range[1] ?? 0);
@@ -2087,7 +2119,13 @@ function parseAndValidateCron(raw, opts) {
2087
2119
  return { success: true, value: trimmed };
2088
2120
  }
2089
2121
  if (fields.length === 5) {
2090
- const ranges = [[0, 59], [0, 23], [1, 31], [1, 12], [0, 6]];
2122
+ const ranges = [
2123
+ [0, 59],
2124
+ [0, 23],
2125
+ [1, 31],
2126
+ [1, 12],
2127
+ [0, 6]
2128
+ ];
2091
2129
  for (let i = 0; i < fields.length; i++) {
2092
2130
  const range = ranges[i] ?? [0, 59];
2093
2131
  const error = validateCronField(fields[i] ?? "", range[0] ?? 0, range[1] ?? 0);
@@ -3862,10 +3900,8 @@ function defineEnv(schema, vars, options) {
3862
3900
  const messages = result.errors.map((e) => ` - ${e.field}: ${e.message}`).join("\n");
3863
3901
  const unknownMsg = result.unknown.length > 0 ? `
3864
3902
  Unknown variables: ${result.unknown.join(", ")}` : "";
3865
- throw new Error(
3866
- `Environment validation failed:
3867
- ${messages}${unknownMsg}`
3868
- );
3903
+ throw new Error(`Environment validation failed:
3904
+ ${messages}${unknownMsg}`);
3869
3905
  }
3870
3906
  return result.values;
3871
3907
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ParseError
3
- } from "./chunk-5G2DU52U.js";
3
+ } from "./chunk-N7GOHQBF.js";
4
4
 
5
5
  // src/core/parser.ts
6
6
  var NAME_START_RE = /^[A-Za-z_]/;
@@ -43,14 +43,11 @@ function resolveEscapeSequence(chars, startIndex, filePath, lineNumber) {
43
43
  }
44
44
  return { resolved: String.fromCodePoint(codePoint), charsConsumed: 4 };
45
45
  }
46
- throw new ParseError(
47
- `Invalid hex escape sequence: ${"\\"}x${hex}`,
48
- {
49
- line: lineNumber,
50
- filePath,
51
- hint: "Hex escapes must be exactly 2 hex digits, e.g. \\x0A for newline."
52
- }
53
- );
46
+ throw new ParseError(`Invalid hex escape sequence: ${"\\"}x${hex}`, {
47
+ line: lineNumber,
48
+ filePath,
49
+ hint: "Hex escapes must be exactly 2 hex digits, e.g. \\x0A for newline."
50
+ });
54
51
  }
55
52
  case "u":
56
53
  case "U": {
@@ -65,14 +62,11 @@ function resolveEscapeSequence(chars, startIndex, filePath, lineNumber) {
65
62
  }
66
63
  return { resolved: String.fromCodePoint(codePoint), charsConsumed: 6 };
67
64
  }
68
- throw new ParseError(
69
- `Invalid unicode escape sequence: ${"\\"}u${hexDigits}`,
70
- {
71
- line: lineNumber,
72
- filePath,
73
- hint: 'Unicode escapes must be exactly 4 hex digits, e.g. \\u0041 for "A".'
74
- }
75
- );
65
+ throw new ParseError(`Invalid unicode escape sequence: ${"\\"}u${hexDigits}`, {
66
+ line: lineNumber,
67
+ filePath,
68
+ hint: 'Unicode escapes must be exactly 4 hex digits, e.g. \\u0041 for "A".'
69
+ });
76
70
  }
77
71
  /* v8 ignore start */
78
72
  default: {
@@ -354,11 +348,7 @@ function parseEnvFile(content, filePath) {
354
348
  comment = trimmedAfter.slice(1).trim();
355
349
  }
356
350
  } else if (firstChar === "'") {
357
- const result = parseSingleQuotedValue(
358
- lines,
359
- lineIndex,
360
- valueStartIndex + 1
361
- );
351
+ const result = parseSingleQuotedValue(lines, lineIndex, valueStartIndex + 1);
362
352
  if (!result.closed) {
363
353
  throw new ParseError("Unterminated single-quoted string", {
364
354
  line: oneBasedLine,
@@ -379,11 +369,7 @@ function parseEnvFile(content, filePath) {
379
369
  comment = trimmedAfter.slice(1).trim();
380
370
  }
381
371
  } else if (firstChar === "`") {
382
- const result = parseBacktickQuotedValue(
383
- lines,
384
- lineIndex,
385
- valueStartIndex + 1
386
- );
372
+ const result = parseBacktickQuotedValue(lines, lineIndex, valueStartIndex + 1);
387
373
  if (!result.closed) {
388
374
  throw new ParseError("Unterminated backtick-quoted string", {
389
375
  line: oneBasedLine,
@@ -57,9 +57,7 @@ function buildFilteredEnv(source, prefixes, allowSet, denySet, exposePublic, exp
57
57
  function healthCheckRoute(options = {}) {
58
58
  const { source = process.env, metadata = {} } = options;
59
59
  return (_req, res) => {
60
- const envKeys = Object.keys(source).filter(
61
- (k) => source[k] !== void 0 && source[k] !== ""
62
- );
60
+ const envKeys = Object.keys(source).filter((k) => source[k] !== void 0 && source[k] !== "");
63
61
  const nodeEnv = source["NODE_ENV"] ?? "unknown";
64
62
  const response = {
65
63
  status: "ok",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FileSystemError
3
- } from "./chunk-5G2DU52U.js";
3
+ } from "./chunk-N7GOHQBF.js";
4
4
 
5
5
  // src/utils/fs.ts
6
6
  import { promises as fsp, existsSync, readFileSync as fsReadFileSync } from "fs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  findUpSync
3
- } from "./chunk-3VYXPTYV.js";
3
+ } from "./chunk-FSKVYBEP.js";
4
4
  import {
5
5
  DEFAULT_ENV_DIR,
6
6
  ENCODING,
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-XC65ORJ5.js";
10
10
  import {
11
11
  ConfigError
12
- } from "./chunk-5G2DU52U.js";
12
+ } from "./chunk-N7GOHQBF.js";
13
13
 
14
14
  // src/core/config.ts
15
15
  import { existsSync, readFileSync } from "fs";
@@ -298,7 +298,8 @@ function parseYamlScalar(value) {
298
298
  if (cleanValue === "") return "";
299
299
  if (cleanValue === "true" || cleanValue === "True" || cleanValue === "TRUE") return true;
300
300
  if (cleanValue === "false" || cleanValue === "False" || cleanValue === "FALSE") return false;
301
- if (cleanValue === "null" || cleanValue === "Null" || cleanValue === "NULL" || cleanValue === "~") return null;
301
+ if (cleanValue === "null" || cleanValue === "Null" || cleanValue === "NULL" || cleanValue === "~")
302
+ return null;
302
303
  if (/^-?\d+$/.test(cleanValue)) return parseInt(cleanValue, 10);
303
304
  if (/^-?\d+\.\d+$/.test(cleanValue)) return parseFloat(cleanValue);
304
305
  if (cleanValue.startsWith('"') && cleanValue.endsWith('"') || cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  writeFile
3
- } from "./chunk-3VYXPTYV.js";
3
+ } from "./chunk-FSKVYBEP.js";
4
4
 
5
5
  // src/typegen/module.ts
6
6
  var DEFAULT_HEADER = "// Auto-generated by ultraenv \u2014 DO NOT EDIT";
@@ -5,12 +5,12 @@ import {
5
5
  } from "./chunk-TE7HPLA6.js";
6
6
  import {
7
7
  parseEnvFile
8
- } from "./chunk-HFXQGJY3.js";
8
+ } from "./chunk-CVJPO3QY.js";
9
9
  import {
10
10
  exists,
11
11
  readFile,
12
12
  writeFile
13
- } from "./chunk-3VYXPTYV.js";
13
+ } from "./chunk-FSKVYBEP.js";
14
14
 
15
15
  // src/sync/generator.ts
16
16
  var HEADER = [
@@ -5,14 +5,14 @@ import {
5
5
  } from "./chunk-TE7HPLA6.js";
6
6
  import {
7
7
  parseEnvFile
8
- } from "./chunk-HFXQGJY3.js";
8
+ } from "./chunk-CVJPO3QY.js";
9
9
  import {
10
10
  exists,
11
11
  readFile
12
- } from "./chunk-3VYXPTYV.js";
12
+ } from "./chunk-FSKVYBEP.js";
13
13
  import {
14
14
  FileSystemError
15
- } from "./chunk-5G2DU52U.js";
15
+ } from "./chunk-N7GOHQBF.js";
16
16
 
17
17
  // src/environments/comparator.ts
18
18
  import { resolve, join } from "path";
@@ -128,24 +128,18 @@ async function compareEnvironments(env1, env2, cwd, _schema) {
128
128
  const resolvedEnv1Path = env1.includes("/") || env1.includes("\\") ? resolve(env1) : env1Path;
129
129
  const resolvedEnv2Path = env2.includes("/") || env2.includes("\\") ? resolve(env2) : env2Path;
130
130
  if (!await exists(resolvedEnv1Path)) {
131
- throw new FileSystemError(
132
- `Environment file not found: "${resolvedEnv1Path}"`,
133
- {
134
- path: resolvedEnv1Path,
135
- operation: "read",
136
- hint: `Ensure ".env.${env1}" exists in the project directory.`
137
- }
138
- );
131
+ throw new FileSystemError(`Environment file not found: "${resolvedEnv1Path}"`, {
132
+ path: resolvedEnv1Path,
133
+ operation: "read",
134
+ hint: `Ensure ".env.${env1}" exists in the project directory.`
135
+ });
139
136
  }
140
137
  if (!await exists(resolvedEnv2Path)) {
141
- throw new FileSystemError(
142
- `Environment file not found: "${resolvedEnv2Path}"`,
143
- {
144
- path: resolvedEnv2Path,
145
- operation: "read",
146
- hint: `Ensure ".env.${env2}" exists in the project directory.`
147
- }
148
- );
138
+ throw new FileSystemError(`Environment file not found: "${resolvedEnv2Path}"`, {
139
+ path: resolvedEnv2Path,
140
+ operation: "read",
141
+ hint: `Ensure ".env.${env2}" exists in the project directory.`
142
+ });
149
143
  }
150
144
  const env1Content = await readFile(resolvedEnv1Path);
151
145
  const env2Content = await readFile(resolvedEnv2Path);
@@ -238,14 +232,18 @@ function formatComparison(comparison) {
238
232
  lines.push("");
239
233
  lines.push(`Only in ${comparison.env1Name} (${comparison.onlyInEnv1.length}):`);
240
234
  for (const diff of comparison.onlyInEnv1) {
241
- lines.push(` - ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value1 || "(empty)"}`);
235
+ lines.push(
236
+ ` - ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value1 || "(empty)"}`
237
+ );
242
238
  }
243
239
  }
244
240
  if (comparison.onlyInEnv2.length > 0) {
245
241
  lines.push("");
246
242
  lines.push(`Only in ${comparison.env2Name} (${comparison.onlyInEnv2.length}):`);
247
243
  for (const diff of comparison.onlyInEnv2) {
248
- lines.push(` + ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value2 || "(empty)"}`);
244
+ lines.push(
245
+ ` + ${diff.key}${diff.isSecret ? " [SECRET]" : ""} = ${diff.value2 || "(empty)"}`
246
+ );
249
247
  }
250
248
  }
251
249
  if (comparison.different.length > 0) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  parseEnvFile
3
- } from "./chunk-HFXQGJY3.js";
3
+ } from "./chunk-CVJPO3QY.js";
4
4
  import {
5
5
  readFile
6
- } from "./chunk-3VYXPTYV.js";
6
+ } from "./chunk-FSKVYBEP.js";
7
7
 
8
8
  // src/sync/comparator.ts
9
9
  function parseToVars(content) {
@@ -147,7 +147,13 @@ var FileSystemError = class extends UltraenvError {
147
147
  code;
148
148
  constructor(message, options = {}) {
149
149
  const fsCode = options.code ?? options.cause?.code ?? "UNKNOWN";
150
- const opHint = options.path !== void 0 ? `Could not ${options.operation ?? "access"} "${options.path}".` : "";
150
+ const opHint = options.path !== void 0 ? (
151
+ /* v8 ignore start */
152
+ `Could not ${options.operation ?? "access"} "${options.path}".`
153
+ ) : (
154
+ /* v8 ignore stop */
155
+ ""
156
+ );
151
157
  super(message, {
152
158
  code: `FS_${fsCode}`,
153
159
  hint: options.hint ?? `${opHint} Ensure the file exists and you have the necessary permissions.`,
@@ -217,7 +217,7 @@ var SECRET_PATTERNS = [
217
217
  {
218
218
  id: "google-oauth-client-secret",
219
219
  name: "Google OAuth Client Secret",
220
- pattern: /(?:^|["'\s:=,`]GOCSPX-[A-Za-z0-9_-]{28,})(?:["'\s,`;]|$)/gm,
220
+ pattern: /(?:^|["'\s:=,`])(GOCSPX-[A-Za-z0-9_-]{28,})(?:["'\s,`;]|$)/gm,
221
221
  confidence: 0.9,
222
222
  severity: "critical",
223
223
  description: "Google OAuth Client Secret (new format). Used for OAuth authentication flows.",
@@ -1024,9 +1024,7 @@ function extractCandidates(line) {
1024
1024
  const captured = tokenMatch[1];
1025
1025
  if (captured === void 0) continue;
1026
1026
  const tokenIndex = tokenMatch.index + 1;
1027
- const existing = candidates.some(
1028
- (c) => c.value === captured && c.column === tokenIndex
1029
- );
1027
+ const existing = candidates.some((c) => c.value === captured && c.column === tokenIndex);
1030
1028
  if (!existing) {
1031
1029
  candidates.push({ value: captured, column: tokenMatch.index + 1 });
1032
1030
  }
@@ -1593,15 +1591,9 @@ var DIM = "\x1B[2m";
1593
1591
  function formatTerminal(result) {
1594
1592
  const lines = [];
1595
1593
  const totalCount = result.secrets.length;
1596
- const criticalCount = result.secrets.filter(
1597
- (s) => getSeverity(s.pattern) === "critical"
1598
- ).length;
1599
- const highCount = result.secrets.filter(
1600
- (s) => getSeverity(s.pattern) === "high"
1601
- ).length;
1602
- const mediumCount = result.secrets.filter(
1603
- (s) => getSeverity(s.pattern) === "medium"
1604
- ).length;
1594
+ const criticalCount = result.secrets.filter((s) => getSeverity(s.pattern) === "critical").length;
1595
+ const highCount = result.secrets.filter((s) => getSeverity(s.pattern) === "high").length;
1596
+ const mediumCount = result.secrets.filter((s) => getSeverity(s.pattern) === "medium").length;
1605
1597
  lines.push("");
1606
1598
  lines.push(`${BOLD}=== ultraenv Secret Scan Report ===${RESET}`);
1607
1599
  lines.push("");
@@ -1617,7 +1609,9 @@ function formatTerminal(result) {
1617
1609
  }
1618
1610
  const summaryParts = [];
1619
1611
  if (criticalCount > 0) {
1620
- summaryParts.push(`${SEVERITY_CONFIG.critical.terminalColor}${BOLD}${criticalCount} critical${RESET}`);
1612
+ summaryParts.push(
1613
+ `${SEVERITY_CONFIG.critical.terminalColor}${BOLD}${criticalCount} critical${RESET}`
1614
+ );
1621
1615
  }
1622
1616
  if (highCount > 0) {
1623
1617
  summaryParts.push(`${SEVERITY_CONFIG.high.terminalColor}${BOLD}${highCount} high${RESET}`);
@@ -3,7 +3,7 @@ import {
3
3
  bufferToBase64,
4
4
  deriveKey,
5
5
  encryptValue
6
- } from "./chunk-2USZPWLZ.js";
6
+ } from "./chunk-6NFA23AY.js";
7
7
  import {
8
8
  DEFAULT_KEY_LENGTH,
9
9
  DEFAULT_SALT_LENGTH,
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-XC65ORJ5.js";
12
12
  import {
13
13
  EncryptionError
14
- } from "./chunk-5G2DU52U.js";
14
+ } from "./chunk-N7GOHQBF.js";
15
15
 
16
16
  // src/vault/key-manager.ts
17
17
  import { randomBytes } from "crypto";
@@ -28,10 +28,9 @@ function deriveEnvironmentKey(masterKey, environment) {
28
28
  );
29
29
  }
30
30
  if (environment.length === 0) {
31
- throw new EncryptionError(
32
- "Environment name cannot be empty",
33
- { hint: 'Provide a valid environment name (e.g., "development", "production").' }
34
- );
31
+ throw new EncryptionError("Environment name cannot be empty", {
32
+ hint: 'Provide a valid environment name (e.g., "development", "production").'
33
+ });
35
34
  }
36
35
  if (HKDF_SALT.length < DEFAULT_SALT_LENGTH) {
37
36
  const paddedSalt = Buffer.alloc(DEFAULT_SALT_LENGTH);
@@ -43,12 +42,7 @@ function deriveEnvironmentKey(masterKey, environment) {
43
42
  DEFAULT_KEY_LENGTH
44
43
  );
45
44
  }
46
- return deriveKey(
47
- masterKey,
48
- HKDF_SALT,
49
- `${HKDF_INFO_PREFIX}${environment}`,
50
- DEFAULT_KEY_LENGTH
51
- );
45
+ return deriveKey(masterKey, HKDF_SALT, `${HKDF_INFO_PREFIX}${environment}`, DEFAULT_KEY_LENGTH);
52
46
  }
53
47
  function formatKey(key) {
54
48
  if (key.length === 0) {
@@ -68,21 +62,17 @@ function parseKey(formatted) {
68
62
  }
69
63
  const base64Part = formatted.slice(KEY_PREFIX.length);
70
64
  if (base64Part.length === 0) {
71
- throw new EncryptionError(
72
- "Invalid key format: base64 payload is empty after prefix",
73
- { hint: "The key appears to be truncated. Generate a new key." }
74
- );
65
+ throw new EncryptionError("Invalid key format: base64 payload is empty after prefix", {
66
+ hint: "The key appears to be truncated. Generate a new key."
67
+ });
75
68
  }
76
69
  try {
77
70
  return base64ToBuffer(base64Part);
78
71
  } catch (error) {
79
- throw new EncryptionError(
80
- "Failed to decode key: invalid base64 encoding",
81
- {
82
- cause: error instanceof Error ? error : void 0,
83
- hint: 'The key may be corrupted. Generate a new key with "ultraenv key generate".'
84
- }
85
- );
72
+ throw new EncryptionError("Failed to decode key: invalid base64 encoding", {
73
+ cause: error instanceof Error ? error : void 0,
74
+ hint: 'The key may be corrupted. Generate a new key with "ultraenv key generate".'
75
+ });
86
76
  }
87
77
  }
88
78
  function isValidKeyFormat(formatted) {
@@ -144,12 +134,9 @@ function parseKeysFile(content) {
144
134
  if (!eqMatch) {
145
135
  const plainMatch = line.match(/^ULTRAENV_KEY_([A-Za-z0-9_]+)=(.*)$/);
146
136
  if (!plainMatch) {
147
- throw new EncryptionError(
148
- `Invalid keys file format at line ${i + 1}: "${line}"`,
149
- {
150
- hint: 'Each key entry should be in the format: ULTRAENV_KEY_{ENVIRONMENT}="ultraenv_key_v1_..."'
151
- }
152
- );
137
+ throw new EncryptionError(`Invalid keys file format at line ${i + 1}: "${line}"`, {
138
+ hint: 'Each key entry should be in the format: ULTRAENV_KEY_{ENVIRONMENT}="ultraenv_key_v1_..."'
139
+ });
153
140
  }
154
141
  const envName2 = plainMatch[1].toLowerCase();
155
142
  const keyValue2 = plainMatch[2];
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  parseEnvFile
3
- } from "./chunk-HFXQGJY3.js";
3
+ } from "./chunk-CVJPO3QY.js";
4
4
  import {
5
5
  readFileSync
6
- } from "./chunk-3VYXPTYV.js";
6
+ } from "./chunk-FSKVYBEP.js";
7
7
  import {
8
8
  DEFAULT_ENV_DIR,
9
9
  ENCODING,
@@ -16,7 +16,7 @@ import {
16
16
  FileSystemError,
17
17
  InterpolationError,
18
18
  isUltraenvError
19
- } from "./chunk-5G2DU52U.js";
19
+ } from "./chunk-N7GOHQBF.js";
20
20
 
21
21
  // src/core/interpolation.ts
22
22
  function parseExpression(expr) {
@@ -182,12 +182,9 @@ function expandVariables(vars, env, options) {
182
182
  const resolving = /* @__PURE__ */ new Set();
183
183
  function expandValue(raw, depth) {
184
184
  if (depth > maxDepth) {
185
- throw new InterpolationError(
186
- `Maximum interpolation depth (${maxDepth}) exceeded`,
187
- {
188
- hint: "Check for deeply nested variable references. Consider simplifying your variable definitions."
189
- }
190
- );
185
+ throw new InterpolationError(`Maximum interpolation depth (${maxDepth}) exceeded`, {
186
+ hint: "Check for deeply nested variable references. Consider simplifying your variable definitions."
187
+ });
191
188
  }
192
189
  const result2 = [];
193
190
  let i = 0;
@@ -223,14 +220,11 @@ function expandVariables(vars, env, options) {
223
220
  const parsed = parseExpression(inner);
224
221
  if (resolving.has(parsed.varName)) {
225
222
  const chain = Array.from(resolving).concat(parsed.varName).join(" \u2192 ");
226
- throw new InterpolationError(
227
- `Circular variable reference detected: ${chain}`,
228
- {
229
- variable: parsed.varName,
230
- circular: true,
231
- hint: "Break the cycle by removing one of the circular references."
232
- }
233
- );
223
+ throw new InterpolationError(`Circular variable reference detected: ${chain}`, {
224
+ variable: parsed.varName,
225
+ circular: true,
226
+ hint: "Break the cycle by removing one of the circular references."
227
+ });
234
228
  }
235
229
  resolving.add(parsed.varName);
236
230
  if (parsed.varName in vars && !(parsed.varName in resolvedMap)) {
@@ -261,14 +255,11 @@ function expandVariables(vars, env, options) {
261
255
  const varName = raw.slice(i, nameEnd);
262
256
  if (resolving.has(varName)) {
263
257
  const chain = Array.from(resolving).concat(varName).join(" \u2192 ");
264
- throw new InterpolationError(
265
- `Circular variable reference detected: ${chain}`,
266
- {
267
- variable: varName,
268
- circular: true,
269
- hint: "Break the cycle by removing one of the circular references."
270
- }
271
- );
258
+ throw new InterpolationError(`Circular variable reference detected: ${chain}`, {
259
+ variable: varName,
260
+ circular: true,
261
+ hint: "Break the cycle by removing one of the circular references."
262
+ });
272
263
  }
273
264
  resolving.add(varName);
274
265
  if (varName in vars && !(varName in resolvedMap)) {
@@ -75,18 +75,12 @@ function drawTable(headers, rows, options) {
75
75
  colWidths = naturalWidths.map((w) => Math.min(w, Math.max(avgWidth, 4)));
76
76
  }
77
77
  }
78
- const wrappedHeaders = headers.map(
79
- (h, i) => wrapText(h, colWidths[i] ?? 8)
80
- );
78
+ const wrappedHeaders = headers.map((h, i) => wrapText(h, colWidths[i] ?? 8));
81
79
  const wrappedRows = rows.map(
82
- (row) => row.map(
83
- (cell, i) => wrapText(cell, colWidths[i] ?? 8)
84
- )
80
+ (row) => row.map((cell, i) => wrapText(cell, colWidths[i] ?? 8))
85
81
  );
86
82
  const maxHeaderLines = Math.max(...wrappedHeaders.map((lines2) => lines2.length));
87
- const maxRowLines = rows.length > 0 ? Math.max(...wrappedRows.map(
88
- (row) => Math.max(...row.map((cell) => cell.length))
89
- )) : 1;
83
+ const maxRowLines = rows.length > 0 ? Math.max(...wrappedRows.map((row) => Math.max(...row.map((cell) => cell.length)))) : 1;
90
84
  const maxLines = Math.max(maxHeaderLines, maxRowLines);
91
85
  const lines = [];
92
86
  const separatorParts = colWidths.map((w) => "\u2500".repeat(w + opts.padding * 2));