varlock 0.0.14 → 0.1.0

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 (55) hide show
  1. package/README.md +1 -1
  2. package/dist/auto-load.js +3 -2
  3. package/dist/{chunk-QCKADJNV.js → chunk-7L3IF2MK.js} +15 -22
  4. package/dist/chunk-7L3IF2MK.js.map +1 -0
  5. package/dist/{chunk-OJFTFBQG.js → chunk-DTNPJJH4.js} +7 -5
  6. package/dist/chunk-DTNPJJH4.js.map +1 -0
  7. package/dist/{chunk-EQQCW3OI.js → chunk-GY623P3W.js} +4 -4
  8. package/dist/{chunk-EQQCW3OI.js.map → chunk-GY623P3W.js.map} +1 -1
  9. package/dist/{chunk-UPOIK25P.js → chunk-LIIRL4NK.js} +4 -4
  10. package/dist/{chunk-UPOIK25P.js.map → chunk-LIIRL4NK.js.map} +1 -1
  11. package/dist/{chunk-HGJF2DUO.js → chunk-MITVWKKH.js} +4 -4
  12. package/dist/{chunk-HGJF2DUO.js.map → chunk-MITVWKKH.js.map} +1 -1
  13. package/dist/{chunk-FCVBOYES.js → chunk-MLIGQWID.js} +1499 -578
  14. package/dist/chunk-MLIGQWID.js.map +1 -0
  15. package/dist/{chunk-4QTFFYV6.js → chunk-NGDIT6C3.js} +42 -22
  16. package/dist/chunk-NGDIT6C3.js.map +1 -0
  17. package/dist/{chunk-ZYL5D2UA.js → chunk-NMJ5YL5I.js} +10 -6
  18. package/dist/chunk-NMJ5YL5I.js.map +1 -0
  19. package/dist/chunk-QT5E2RY6.js +56 -0
  20. package/dist/chunk-QT5E2RY6.js.map +1 -0
  21. package/dist/cli/cli-executable.js +82 -51
  22. package/dist/cli/cli-executable.js.map +1 -1
  23. package/dist/dotenv-compat.js +3 -2
  24. package/dist/{env-DLUhFCnC.d.ts → env-graph-eF0B8G0j.d.ts} +210 -55
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.js +3 -3
  27. package/dist/init.command-ASK74XBV.js +8 -0
  28. package/dist/{init.command-VK4OGIYP.js.map → init.command-ASK74XBV.js.map} +1 -1
  29. package/dist/lib/exec-sync-varlock.d.ts +14 -0
  30. package/dist/lib/exec-sync-varlock.js +4 -0
  31. package/dist/lib/exec-sync-varlock.js.map +1 -0
  32. package/dist/load.command-VUKBSBEV.js +8 -0
  33. package/dist/{load.command-N7FMBREX.js.map → load.command-VUKBSBEV.js.map} +1 -1
  34. package/dist/plugin-lib.d.ts +9 -0
  35. package/dist/plugin-lib.js +3 -0
  36. package/dist/plugin-lib.js.map +1 -0
  37. package/dist/run.command-XQ64Z2TN.js +8 -0
  38. package/dist/{run.command-LYY2M5AP.js.map → run.command-XQ64Z2TN.js.map} +1 -1
  39. package/dist/runtime/env.d.ts +28 -1
  40. package/dist/telemetry.command-HHZVBFC7.js +8 -0
  41. package/dist/{telemetry.command-QTEDXKIG.js.map → telemetry.command-HHZVBFC7.js.map} +1 -1
  42. package/package.json +22 -10
  43. package/dist/chunk-4QTFFYV6.js.map +0 -1
  44. package/dist/chunk-FCVBOYES.js.map +0 -1
  45. package/dist/chunk-J5SIYSJV.js +0 -146
  46. package/dist/chunk-J5SIYSJV.js.map +0 -1
  47. package/dist/chunk-OJFTFBQG.js.map +0 -1
  48. package/dist/chunk-QCKADJNV.js.map +0 -1
  49. package/dist/chunk-ZYL5D2UA.js.map +0 -1
  50. package/dist/init.command-VK4OGIYP.js +0 -8
  51. package/dist/load.command-N7FMBREX.js +0 -8
  52. package/dist/login.command-GQCJY4NK.js +0 -8
  53. package/dist/login.command-GQCJY4NK.js.map +0 -1
  54. package/dist/run.command-LYY2M5AP.js +0 -8
  55. package/dist/telemetry.command-QTEDXKIG.js +0 -8
@@ -1,91 +1,193 @@
1
1
  import { redactString } from './chunk-FGMXIEFA.js';
2
2
  import { __commonJS, __name, __toESM } from './chunk-XN24GZXQ.js';
3
+ import process2 from 'process';
3
4
  import { exec } from 'child_process';
4
5
  import { promisify } from 'util';
5
6
  import fs, { accessSync } from 'fs';
6
7
  import fs2, { access } from 'fs/promises';
7
8
  import path2 from 'path';
8
- import { ParsedEnvSpecStaticValue, ParsedEnvSpecFunctionCall, ParsedEnvSpecKeyValuePair, parseEnvSpecDotEnvFile } from '@env-spec/parser';
9
- import process2 from 'process';
9
+ import { ParsedEnvSpecFunctionCall, ParsedEnvSpecStaticValue, ParsedEnvSpecFunctionArgs, ParsedEnvSpecKeyValuePair, parseEnvSpecDotEnvFile } from '@env-spec/parser';
10
+ import os from 'os';
11
+ import crypto from 'crypto';
12
+ import https from 'https';
13
+ import semver from 'semver';
14
+ import Debug from 'debug';
10
15
 
11
- // ../../node_modules/.pnpm/ansis@4.1.0/node_modules/ansis/index.cjs
16
+ // ../../node_modules/.pnpm/ansis@4.2.0/node_modules/ansis/index.cjs
12
17
  var require_ansis = __commonJS({
13
- "../../node_modules/.pnpm/ansis@4.1.0/node_modules/ansis/index.cjs"(exports, module) {
18
+ "../../node_modules/.pnpm/ansis@4.2.0/node_modules/ansis/index.cjs"(exports, module) {
14
19
  var e;
15
20
  var t;
16
21
  var r;
17
- var { defineProperty: n, setPrototypeOf: l, create: o, keys: s } = Object;
22
+ var { defineProperty: l, setPrototypeOf: n, create: o, keys: s } = Object;
18
23
  var i = "";
19
24
  var { round: c, max: a2 } = Math;
20
25
  var p = /* @__PURE__ */ __name((e2) => {
21
- let t2 = /([a-f\d]{3,6})/i.exec(e2)?.[1], r2 = t2?.length, n2 = parseInt(6 ^ r2 ? 3 ^ r2 ? "0" : t2[0] + t2[0] + t2[1] + t2[1] + t2[2] + t2[2] : t2, 16);
22
- return [n2 >> 16 & 255, n2 >> 8 & 255, 255 & n2];
26
+ let t2 = /([a-f\d]{3,6})/i.exec(e2)?.[1], r2 = t2?.length, l2 = parseInt(6 ^ r2 ? 3 ^ r2 ? "0" : t2[0] + t2[0] + t2[1] + t2[1] + t2[2] + t2[2] : t2, 16);
27
+ return [l2 >> 16 & 255, l2 >> 8 & 255, 255 & l2];
23
28
  }, "p");
24
29
  var u = /* @__PURE__ */ __name((e2, t2, r2) => e2 ^ t2 || t2 ^ r2 ? 16 + 36 * c(e2 / 51) + 6 * c(t2 / 51) + c(r2 / 51) : 8 > e2 ? 16 : e2 > 248 ? 231 : c(24 * (e2 - 8) / 247) + 232, "u");
25
30
  var d = /* @__PURE__ */ __name((e2) => {
26
- let t2, r2, n2, l2, o2;
27
- return 8 > e2 ? 30 + e2 : 16 > e2 ? e2 - 8 + 90 : (232 > e2 ? (o2 = (e2 -= 16) % 36, t2 = (e2 / 36 | 0) / 5, r2 = (o2 / 6 | 0) / 5, n2 = o2 % 6 / 5) : t2 = r2 = n2 = (10 * (e2 - 232) + 8) / 255, l2 = 2 * a2(t2, r2, n2), l2 ? 30 + (c(n2) << 2 | c(r2) << 1 | c(t2)) + (2 ^ l2 ? 0 : 60) : 30);
31
+ let t2, r2, l2, n2, o2;
32
+ return 8 > e2 ? 30 + e2 : 16 > e2 ? e2 - 8 + 90 : (232 > e2 ? (o2 = (e2 -= 16) % 36, t2 = (e2 / 36 | 0) / 5, r2 = (o2 / 6 | 0) / 5, l2 = o2 % 6 / 5) : t2 = r2 = l2 = (10 * (e2 - 232) + 8) / 255, n2 = 2 * a2(t2, r2, l2), n2 ? 30 + (c(l2) << 2 | c(r2) << 1 | c(t2)) + (2 ^ n2 ? 0 : 60) : 30);
28
33
  }, "d");
29
- var g = (() => {
30
- let r2 = /* @__PURE__ */ __name((e2) => o2.some((t2) => e2.test(t2)), "r"), n2 = globalThis, l2 = n2.process ?? {}, o2 = l2.argv ?? [], i2 = l2.env ?? {}, c2 = -1;
34
+ var f = (() => {
35
+ let r2 = /* @__PURE__ */ __name((e2) => o2.some((t2) => e2.test(t2)), "r"), l2 = globalThis, n2 = l2.process ?? {}, o2 = n2.argv ?? [], i2 = n2.env ?? {}, c2 = -1;
31
36
  try {
32
37
  e = "," + s(i2).join(",");
33
38
  } catch (e2) {
34
39
  i2 = {}, c2 = 0;
35
40
  }
36
41
  let a3 = "FORCE_COLOR", p2 = { false: 0, 0: 0, 1: 1, 2: 2, 3: 3 }[i2[a3]] ?? -1, u2 = a3 in i2 && p2 || r2(/^--color=?(true|always)?$/);
37
- return u2 && (c2 = p2), ~c2 || (c2 = ((r3, n3, l3) => (t = r3.TERM, { "24bit": 3, truecolor: 3, ansi256: 2, ansi: 1 }[r3.COLORTERM] || (r3.CI ? /,GITHUB/.test(e) ? 3 : 1 : n3 && "dumb" !== t ? l3 ? 3 : /-256/.test(t) ? 2 : 1 : 0)))(i2, !!i2.PM2_HOME || i2.NEXT_RUNTIME?.includes("edge") || !!l2.stdout?.isTTY, "win32" === l2.platform)), !p2 || i2.NO_COLOR || r2(/^--(no-color|color=(false|never))$/) ? 0 : n2.window?.chrome || u2 && !c2 ? 3 : c2;
42
+ return u2 && (c2 = p2), ~c2 || (c2 = ((r3, l3, n3) => (t = r3.TERM, { "24bit": 3, truecolor: 3, ansi256: 2, ansi: 1 }[r3.COLORTERM] || (r3.CI ? /,GITHUB/.test(e) ? 3 : 1 : l3 && "dumb" !== t ? n3 ? 3 : /-256/.test(t) ? 2 : 1 : 0)))(i2, !!i2.PM2_HOME || i2.NEXT_RUNTIME?.includes("edge") || !!n2.stdout?.isTTY, "win32" === n2.platform)), !p2 || i2.NO_COLOR || r2(/^--(no-color|color=(false|never))$/) ? 0 : l2.window?.chrome || u2 && !c2 ? 3 : c2;
38
43
  })();
39
- var f = { open: i, close: i };
44
+ var g = { open: i, close: i };
40
45
  var h = 39;
41
46
  var b = 49;
42
47
  var O = {};
43
- var m = /* @__PURE__ */ __name(({ p: e2 }, { open: t2, close: n2 }) => {
48
+ var m = /* @__PURE__ */ __name(({ p: e2 }, { open: t2, close: l2 }) => {
44
49
  let o2 = /* @__PURE__ */ __name((e3, ...r2) => {
45
50
  if (!e3) {
46
- if (t2 && t2 === n2) return t2;
51
+ if (t2 && t2 === l2) return t2;
47
52
  if ((e3 ?? i) === i) return i;
48
53
  }
49
- let l2, s3 = e3.raw ? String.raw({ raw: e3 }, ...r2) : i + e3, c3 = o2.p, a3 = c3.o, p2 = c3.c;
54
+ let n2, s3 = e3.raw ? String.raw({ raw: e3 }, ...r2) : i + e3, c3 = o2.p, a3 = c3.o, p2 = c3.c;
50
55
  if (s3.includes("\x1B")) for (; c3; c3 = c3.p) {
51
- let { open: e4, close: t3 } = c3, r3 = t3.length, n3 = i, o3 = 0;
52
- if (r3) for (; ~(l2 = s3.indexOf(t3, o3)); o3 = l2 + r3) n3 += s3.slice(o3, l2) + e4;
53
- s3 = n3 + s3.slice(o3);
56
+ let { open: e4, close: t3 } = c3, r3 = t3.length, l3 = i, o3 = 0;
57
+ if (r3) for (; ~(n2 = s3.indexOf(t3, o3)); o3 = n2 + r3) l3 += s3.slice(o3, n2) + e4;
58
+ s3 = l3 + s3.slice(o3);
54
59
  }
55
60
  return a3 + (s3.includes("\n") ? s3.replace(/(\r?\n)/g, p2 + "$1" + a3) : s3) + p2;
56
- }, "o"), s2 = t2, c2 = n2;
57
- return e2 && (s2 = e2.o + t2, c2 = n2 + e2.c), l(o2, r), o2.p = { open: t2, close: n2, o: s2, c: c2, p: e2 }, o2.open = s2, o2.close = c2, o2;
61
+ }, "o"), s2 = t2, c2 = l2;
62
+ return e2 && (s2 = e2.o + t2, c2 = l2 + e2.c), n(o2, r), o2.p = { open: t2, close: l2, o: s2, c: c2, p: e2 }, o2.open = s2, o2.close = c2, o2;
58
63
  }, "m");
59
- var w = /* @__PURE__ */ __name(function(e2 = g) {
60
- let t2 = { Ansis: w, level: e2, isSupported: /* @__PURE__ */ __name(() => s2, "isSupported"), strip: /* @__PURE__ */ __name((e3) => e3.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i), "strip"), extend(e3) {
64
+ var w = new (/* @__PURE__ */ __name(function e2(t2 = f) {
65
+ let s2 = { Ansis: e2, level: t2, isSupported: /* @__PURE__ */ __name(() => a3, "isSupported"), strip: /* @__PURE__ */ __name((e3) => e3.replace(/[›][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, i), "strip"), extend(e3) {
61
66
  for (let t3 in e3) {
62
- let r2 = e3[t3], l2 = (typeof r2)[0], o2 = "s" === l2 ? x(...p(r2)) : r2;
63
- O[t3] = "f" === l2 ? { get() {
64
- return (...e4) => m(this, r2(...e4));
65
- } } : { get() {
66
- let e4 = m(this, o2);
67
- return n(this, t3, { value: e4 }), e4;
68
- } };
67
+ let r2 = e3[t3], l2 = (typeof r2)[0];
68
+ "s" === l2 ? (c2(t3, T(...p(r2))), c2(_4(t3), v(...p(r2)))) : c2(t3, r2, "f" === l2);
69
69
  }
70
- return r = o({}, O), l(t2, r), t2;
71
- } }, s2 = e2 > 0, c2 = /* @__PURE__ */ __name((e3, t3) => s2 ? { open: `\x1B[${e3}m`, close: `\x1B[${t3}m` } : f, "c"), a3 = /* @__PURE__ */ __name((e3) => (t3) => e3(...p(t3)), "a"), y2 = /* @__PURE__ */ __name((e3, t3) => (r2, n2, l2) => c2(`${e3}8;2;${r2};${n2};${l2}`, t3), "y"), R = /* @__PURE__ */ __name((e3, t3) => (r2, n2, l2) => c2(((e4, t4, r3) => d(u(e4, t4, r3)))(r2, n2, l2) + e3, t3), "R"), $ = /* @__PURE__ */ __name((e3) => (t3, r2, n2) => e3(u(t3, r2, n2)), "$"), x = y2(3, h), T = y2(4, b), v = /* @__PURE__ */ __name((e3) => c2("38;5;" + e3, h), "v"), C = /* @__PURE__ */ __name((e3) => c2("48;5;" + e3, b), "C");
72
- 2 === e2 ? (x = $(v), T = $(C)) : 1 === e2 && (x = R(0, h), T = R(10, b), v = /* @__PURE__ */ __name((e3) => c2(d(e3), h), "v"), C = /* @__PURE__ */ __name((e3) => c2(d(e3) + 10, b), "C"));
73
- let E, M = { fg: v, bg: C, rgb: x, bgRgb: T, hex: a3(x), bgHex: a3(T), visible: f, reset: c2(0, 0), bold: c2(1, 22), dim: c2(2, 22), italic: c2(3, 23), underline: c2(4, 24), inverse: c2(7, 27), hidden: c2(8, 28), strikethrough: c2(9, 29) }, I = "Bright";
70
+ return r = o({}, O), n(s2, r), s2;
71
+ } }, c2 = /* @__PURE__ */ __name((e3, t3, r2) => {
72
+ O[e3] = { get() {
73
+ let n2 = r2 ? (...e4) => m(this, t3(...e4)) : m(this, t3);
74
+ return l(this, e3, { value: n2 }), n2;
75
+ } };
76
+ }, "c"), a3 = t2 > 0, w2 = /* @__PURE__ */ __name((e3, t3) => a3 ? { open: `\x1B[${e3}m`, close: `\x1B[${t3}m` } : g, "w"), y = /* @__PURE__ */ __name((e3) => (t3) => e3(...p(t3)), "y"), R = /* @__PURE__ */ __name((e3, t3) => (r2, l2, n2) => w2(`${e3}8;2;${r2};${l2};${n2}`, t3), "R"), $ = /* @__PURE__ */ __name((e3, t3) => (r2, l2, n2) => w2(((e4, t4, r3) => d(u(e4, t4, r3)))(r2, l2, n2) + e3, t3), "$"), x = /* @__PURE__ */ __name((e3) => (t3, r2, l2) => e3(u(t3, r2, l2)), "x"), T = R(3, h), v = R(4, b), C = /* @__PURE__ */ __name((e3) => w2("38;5;" + e3, h), "C"), E = /* @__PURE__ */ __name((e3) => w2("48;5;" + e3, b), "E");
77
+ 2 === t2 ? (T = x(C), v = x(E)) : 1 === t2 && (T = $(0, h), v = $(10, b), C = /* @__PURE__ */ __name((e3) => w2(d(e3), h), "C"), E = /* @__PURE__ */ __name((e3) => w2(d(e3) + 10, b), "E"));
78
+ let M, I = { fg: C, bg: E, rgb: T, bgRgb: v, hex: y(T), bgHex: y(v), visible: g, reset: w2(0, 0), bold: w2(1, 22), dim: w2(2, 22), italic: w2(3, 23), underline: w2(4, 24), inverse: w2(7, 27), hidden: w2(8, 28), strikethrough: w2(9, 29) }, _4 = /* @__PURE__ */ __name((e3) => "bg" + e3[0].toUpperCase() + e3.slice(1), "_"), k = "Bright";
74
79
  return "black,red,green,yellow,blue,magenta,cyan,white,gray".split(",").map((e3, t3) => {
75
- E = "bg" + e3[0].toUpperCase() + e3.slice(1), 8 > t3 ? (M[e3 + I] = c2(90 + t3, h), M[E + I] = c2(100 + t3, b)) : t3 = 60, M[e3] = c2(30 + t3, h), M[E] = c2(40 + t3, b);
76
- }), t2.extend(M);
77
- }, "w");
78
- var y = new w();
79
- module.exports = y, y.default = y;
80
+ M = _4(e3), 8 > t3 ? (I[e3 + k] = w2(90 + t3, h), I[M + k] = w2(100 + t3, b)) : t3 = 60, I[e3] = w2(30 + t3, h), I[M] = w2(40 + t3, b);
81
+ }), s2.extend(I);
82
+ }, "e"))();
83
+ module.exports = w, w.default = w;
80
84
  }
81
85
  });
82
86
 
83
- // ../../node_modules/.pnpm/ansis@4.1.0/node_modules/ansis/index.mjs
87
+ // ../../node_modules/.pnpm/ansis@4.2.0/node_modules/ansis/index.mjs
84
88
  var import_index = __toESM(require_ansis(), 1);
85
89
  var ansis_default = import_index.default;
86
90
  var { Ansis, fg, bg, rgb, bgRgb, hex, bgHex, reset, inverse, hidden, visible, bold, dim, italic, underline, strikethrough, black, red, green, yellow, blue, magenta, cyan, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bgGray, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright } = import_index.default;
91
+ var asyncCallbacks = /* @__PURE__ */ new Set();
92
+ var callbacks = /* @__PURE__ */ new Set();
93
+ var isCalled = false;
94
+ var isRegistered = false;
95
+ async function exit(shouldManuallyExit, isSynchronous, signal) {
96
+ if (isCalled) {
97
+ return;
98
+ }
99
+ isCalled = true;
100
+ if (asyncCallbacks.size > 0 && isSynchronous) {
101
+ console.error([
102
+ "SYNCHRONOUS TERMINATION NOTICE:",
103
+ "When explicitly exiting the process via process.exit or via a parent process,",
104
+ "asynchronous tasks in your exitHooks will not run. Either remove these tasks,",
105
+ "use gracefulExit() instead of process.exit(), or ensure your parent process",
106
+ "sends a SIGINT to the process running this code."
107
+ ].join(" "));
108
+ }
109
+ const exitCode = 128 + signal;
110
+ const done = /* @__PURE__ */ __name((force = false) => {
111
+ if (force === true || shouldManuallyExit === true) {
112
+ process2.exit(exitCode);
113
+ }
114
+ }, "done");
115
+ for (const callback of callbacks) {
116
+ callback(exitCode);
117
+ }
118
+ if (isSynchronous) {
119
+ done();
120
+ return;
121
+ }
122
+ const promises = [];
123
+ let forceAfter = 0;
124
+ for (const [callback, wait] of asyncCallbacks) {
125
+ forceAfter = Math.max(forceAfter, wait);
126
+ promises.push(Promise.resolve(callback(exitCode)));
127
+ }
128
+ const asyncTimer = setTimeout(() => {
129
+ done(true);
130
+ }, forceAfter);
131
+ await Promise.all(promises);
132
+ clearTimeout(asyncTimer);
133
+ done();
134
+ }
135
+ __name(exit, "exit");
136
+ function addHook(options) {
137
+ const { onExit, wait, isSynchronous } = options;
138
+ const asyncCallbackConfig = [onExit, wait];
139
+ if (isSynchronous) {
140
+ callbacks.add(onExit);
141
+ } else {
142
+ asyncCallbacks.add(asyncCallbackConfig);
143
+ }
144
+ if (!isRegistered) {
145
+ isRegistered = true;
146
+ process2.once("beforeExit", exit.bind(void 0, true, false, -128));
147
+ process2.once("SIGINT", exit.bind(void 0, true, false, 2));
148
+ process2.once("SIGTERM", exit.bind(void 0, true, false, 15));
149
+ process2.once("exit", exit.bind(void 0, false, true, 0));
150
+ process2.on("message", (message) => {
151
+ if (message === "shutdown") {
152
+ exit(true, true, -128);
153
+ }
154
+ });
155
+ }
156
+ return () => {
157
+ if (isSynchronous) {
158
+ callbacks.delete(onExit);
159
+ } else {
160
+ asyncCallbacks.delete(asyncCallbackConfig);
161
+ }
162
+ };
163
+ }
164
+ __name(addHook, "addHook");
165
+ function asyncExitHook(onExit, options = {}) {
166
+ if (typeof onExit !== "function") {
167
+ throw new TypeError("onExit must be a function");
168
+ }
169
+ if (!(typeof options.wait === "number" && options.wait > 0)) {
170
+ throw new TypeError("wait must be set to a positive numeric value");
171
+ }
172
+ return addHook({
173
+ onExit,
174
+ wait: options.wait,
175
+ isSynchronous: false
176
+ });
177
+ }
178
+ __name(asyncExitHook, "asyncExitHook");
179
+ function gracefulExit(signal = 0) {
180
+ exit(true, false, -128 + signal);
181
+ }
182
+ __name(gracefulExit, "gracefulExit");
183
+
184
+ // ../../node_modules/.pnpm/@sindresorhus+is@7.1.1/node_modules/@sindresorhus/is/distribution/utilities.js
185
+ function keysOf(value) {
186
+ return Object.keys(value);
187
+ }
188
+ __name(keysOf, "keysOf");
87
189
 
88
- // ../../node_modules/.pnpm/@sindresorhus+is@7.0.2/node_modules/@sindresorhus/is/distribution/index.js
190
+ // ../../node_modules/.pnpm/@sindresorhus+is@7.1.1/node_modules/@sindresorhus/is/distribution/index.js
89
191
  var typedArrayTypeNames = [
90
192
  "Int8Array",
91
193
  "Uint8Array",
@@ -198,9 +300,12 @@ function detect(value) {
198
300
  return "Buffer";
199
301
  }
200
302
  const tagType = getObjectType(value);
201
- if (tagType) {
303
+ if (tagType && tagType !== "Object") {
202
304
  return tagType;
203
305
  }
306
+ if (hasPromiseApi(value)) {
307
+ return "Promise";
308
+ }
204
309
  if (value instanceof String || value instanceof Boolean || value instanceof Number) {
205
310
  throw new TypeError("Please don't use object wrappers for primitive types");
206
311
  }
@@ -297,6 +402,7 @@ Object.assign(detect, {
297
402
  urlInstance: isUrlInstance,
298
403
  urlSearchParams: isUrlSearchParams,
299
404
  urlString: isUrlString,
405
+ optional: isOptional,
300
406
  validDate: isValidDate,
301
407
  validLength: isValidLength,
302
408
  weakMap: isWeakMap,
@@ -317,6 +423,10 @@ function isAny(predicate, ...values) {
317
423
  return predicates.some((singlePredicate) => predicateOnArray(Array.prototype.some, singlePredicate, values));
318
424
  }
319
425
  __name(isAny, "isAny");
426
+ function isOptional(value, predicate) {
427
+ return isUndefined(value) || predicate(value);
428
+ }
429
+ __name(isOptional, "isOptional");
320
430
  function isArray(value, assertion) {
321
431
  if (!Array.isArray(value)) {
322
432
  return false;
@@ -380,7 +490,7 @@ function isBuffer(value) {
380
490
  }
381
491
  __name(isBuffer, "isBuffer");
382
492
  function isClass(value) {
383
- return isFunction(value) && value.toString().startsWith("class ");
493
+ return isFunction(value) && /^class(\s+|{)/.test(value.toString());
384
494
  }
385
495
  __name(isClass, "isClass");
386
496
  function isDataView(value) {
@@ -726,10 +836,6 @@ function predicateOnArray(method, predicate, values) {
726
836
  return method.call(values, predicate);
727
837
  }
728
838
  __name(predicateOnArray, "predicateOnArray");
729
- function keysOf(value) {
730
- return Object.keys(value);
731
- }
732
- __name(keysOf, "keysOf");
733
839
 
734
840
  // ../utils/src/my-dash.ts
735
841
  function keyBy(array, key) {
@@ -780,7 +886,7 @@ function mapValues(obj, fn) {
780
886
  }
781
887
  __name(mapValues, "mapValues");
782
888
  function times(count, fn) {
783
- return Array.from({ length: count }, (_3, i) => fn(i));
889
+ return Array.from({ length: count }, (_4, i) => fn(i));
784
890
  }
785
891
  __name(times, "times");
786
892
  function map(array, fn) {
@@ -799,6 +905,14 @@ function pick(obj, keys) {
799
905
  return Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key)));
800
906
  }
801
907
  __name(pick, "pick");
908
+ function uniq(array) {
909
+ return Array.from(new Set(array));
910
+ }
911
+ __name(uniq, "uniq");
912
+ function fromPairs(pairs) {
913
+ return Object.fromEntries(pairs);
914
+ }
915
+ __name(fromPairs, "fromPairs");
802
916
  var _ = {
803
917
  keyBy,
804
918
  sortBy,
@@ -815,6 +929,8 @@ var _ = {
815
929
  flatMap,
816
930
  intersection,
817
931
  pick,
932
+ uniq,
933
+ fromPairs,
818
934
  // type checks
819
935
  isString,
820
936
  isBoolean,
@@ -863,6 +979,9 @@ var VarlockError = class extends Error {
863
979
  if (my_dash_default.isArray(this.more.tip)) return this.more.tip.join("\n");
864
980
  return this.more.tip;
865
981
  }
982
+ get location() {
983
+ return this.more?.location;
984
+ }
866
985
  get code() {
867
986
  return this.more?.code;
868
987
  }
@@ -913,6 +1032,12 @@ var ConfigLoadError = class extends VarlockError {
913
1032
  };
914
1033
  }
915
1034
  };
1035
+ var ParseError = class extends VarlockError {
1036
+ static {
1037
+ __name(this, "ParseError");
1038
+ }
1039
+ static defaultIcon = "\u{1F635}\u200D\u{1F4AB}";
1040
+ };
916
1041
  var SchemaError = class extends VarlockError {
917
1042
  static {
918
1043
  __name(this, "SchemaError");
@@ -975,13 +1100,13 @@ __name(tryCatch, "tryCatch");
975
1100
  var asyncExec = promisify(exec);
976
1101
 
977
1102
  // ../utils/src/git-utils.ts
978
- async function checkIsFileGitIgnored(path3, warnIfNotGitRepo = false) {
1103
+ async function checkIsFileGitIgnored(path4, warnIfNotGitRepo = false) {
979
1104
  try {
980
- await asyncExec(`git check-ignore ${path3} -q`);
1105
+ await asyncExec(`git check-ignore ${path4} -q`);
981
1106
  return true;
982
1107
  } catch (err) {
983
1108
  const stderr = err.stderr;
984
- if (stderr.includes("not found")) return void 0;
1109
+ if (err.status === 127 || stderr.includes("not found")) return void 0;
985
1110
  if (err.code === "ENOENT") return void 0;
986
1111
  if (stderr === "") return false;
987
1112
  if (stderr.includes("not a git repository")) {
@@ -1028,12 +1153,20 @@ var EnvGraphDataType = class {
1028
1153
  get icon() {
1029
1154
  return this.def.icon;
1030
1155
  }
1156
+ get isSensitive() {
1157
+ return this.def.sensitive;
1158
+ }
1159
+ get docsEntries() {
1160
+ return this.def.docs;
1161
+ }
1031
1162
  /** @internal */
1032
1163
  get _rawDef() {
1033
1164
  return this.def;
1034
1165
  }
1035
1166
  coerce(val) {
1036
- return this.def.coerce ? this.def.coerce(val) : val;
1167
+ if (this.def.coerce) return this.def.coerce(val);
1168
+ if (val === void 0) return void 0;
1169
+ return typeof val === "string" ? val : String(val);
1037
1170
  }
1038
1171
  validate(val) {
1039
1172
  return this.def.validate ? this.def.validate(val) : true;
@@ -1260,7 +1393,7 @@ var EmailDataType = createEnvGraphDataType(
1260
1393
  );
1261
1394
  var IP_V4_ADDRESS_REGEX = /^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/;
1262
1395
  var IP_V6_ADDRESS_REGEX = /^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$/;
1263
- var ipAddressDataType = createEnvGraphDataType(
1396
+ var IpAddressDataType = createEnvGraphDataType(
1264
1397
  (settings) => ({
1265
1398
  name: "ip",
1266
1399
  icon: "iconoir:ip-address-tag",
@@ -1350,21 +1483,21 @@ var Md5DataType = createEnvGraphDataType({
1350
1483
  return new ValidationError("Value must be a valid MD5 hash string");
1351
1484
  }
1352
1485
  });
1353
- var BaseDataTypes = {
1354
- string: StringDataType,
1355
- number: NumberDataType,
1356
- boolean: BooleanDataType,
1357
- simpleObject: SimpleObjectDataType,
1358
- enum: EnumDataType,
1359
- email: EmailDataType,
1360
- url: UrlDataType,
1361
- ipAddress: ipAddressDataType,
1362
- port: PortDataType,
1363
- semver: SemverDataType,
1364
- isoDate: IsoDateDataType,
1365
- uuid: UuidDataType,
1366
- md5: Md5DataType
1367
- };
1486
+ var BaseDataTypes = [
1487
+ StringDataType,
1488
+ NumberDataType,
1489
+ BooleanDataType,
1490
+ SimpleObjectDataType,
1491
+ EnumDataType,
1492
+ EmailDataType,
1493
+ UrlDataType,
1494
+ IpAddressDataType,
1495
+ PortDataType,
1496
+ SemverDataType,
1497
+ IsoDateDataType,
1498
+ UuidDataType,
1499
+ Md5DataType
1500
+ ];
1368
1501
 
1369
1502
  // env-graph/lib/simple-queue.ts
1370
1503
  var SimpleQueue = class {
@@ -1403,22 +1536,242 @@ var SimpleQueue = class {
1403
1536
  }
1404
1537
  }
1405
1538
  };
1539
+ var DecoratorInstance = class {
1540
+ static {
1541
+ __name(this, "DecoratorInstance");
1542
+ }
1543
+ get name() {
1544
+ return this.parsedDecorator.name;
1545
+ }
1546
+ get isFunctionCall() {
1547
+ return !!this.parsedDecorator.isBareFnCall;
1548
+ }
1549
+ // decorator value/args are translated into a resolver when we process the decorator
1550
+ _decValueResolver;
1551
+ get decValueResolver() {
1552
+ return this._decValueResolver;
1553
+ }
1554
+ _schemaErrors = [];
1555
+ get schemaErrors() {
1556
+ return [
1557
+ ...this._schemaErrors,
1558
+ ...this._decValueResolver?.schemaErrors || []
1559
+ ];
1560
+ }
1561
+ // error encountered during `execute` function
1562
+ _executionError;
1563
+ decoratorDef;
1564
+ get incompatibleWith() {
1565
+ return this.decoratorDef?.incompatibleWith;
1566
+ }
1567
+ processed = false;
1568
+ processedData;
1569
+ async process() {
1570
+ if (this.processed) return;
1571
+ this.processed = true;
1572
+ if (!this.graph) throw new Error("expected graph to be set");
1573
+ try {
1574
+ const decRegistry = this.isRootDecorator ? this.graph.rootDecoratorsRegistry : this.graph.itemDecoratorsRegistry;
1575
+ this.decoratorDef = decRegistry[this.name];
1576
+ if (!this.decoratorDef) {
1577
+ throw new Error(`Unknown decorator: @${this.name}`);
1578
+ }
1579
+ if (this.decoratorDef.useFnArgsResolver && this.parsedDecorator.value instanceof ParsedEnvSpecFunctionCall) {
1580
+ this._decValueResolver = convertParsedValueToResolvers(
1581
+ this.parsedDecorator.value.data.args,
1582
+ this.dataSource,
1583
+ this.graph.registeredResolverFunctions
1584
+ );
1585
+ } else {
1586
+ this._decValueResolver = convertParsedValueToResolvers(
1587
+ this.parsedDecorator.value,
1588
+ this.dataSource,
1589
+ this.graph.registeredResolverFunctions
1590
+ );
1591
+ }
1592
+ if (this.decValueResolver) {
1593
+ await this.decValueResolver.process(this);
1594
+ this.processedData = await this.decoratorDef.process?.(this.decValueResolver);
1595
+ }
1596
+ } catch (e) {
1597
+ this._schemaErrors.push(e instanceof SchemaError ? e : new SchemaError(e));
1598
+ }
1599
+ }
1600
+ async execute() {
1601
+ await this.decoratorDef.execute?.(this.processedData);
1602
+ }
1603
+ resolvedValue;
1604
+ isResolved = false;
1605
+ async resolve() {
1606
+ if (this.isResolved) return this.resolvedValue;
1607
+ await this.process();
1608
+ if (!this.decValueResolver) throw new Error("expected decorator to have a value resolver");
1609
+ try {
1610
+ this.resolvedValue = await this.decValueResolver.resolve();
1611
+ } catch (err) {
1612
+ this._schemaErrors.push(err);
1613
+ }
1614
+ this.isResolved = true;
1615
+ return this.resolvedValue;
1616
+ }
1617
+ };
1618
+ var ItemDecoratorInstance = class extends DecoratorInstance {
1619
+ constructor(configItem, dataSource, parsedDecorator) {
1620
+ super();
1621
+ this.configItem = configItem;
1622
+ this.dataSource = dataSource;
1623
+ this.parsedDecorator = parsedDecorator;
1624
+ }
1625
+ static {
1626
+ __name(this, "ItemDecoratorInstance");
1627
+ }
1628
+ isRootDecorator = false;
1629
+ get graph() {
1630
+ return this.dataSource.graph;
1631
+ }
1632
+ };
1633
+ var RootDecoratorInstance = class extends DecoratorInstance {
1634
+ constructor(dataSource, parsedDecorator) {
1635
+ super();
1636
+ this.dataSource = dataSource;
1637
+ this.parsedDecorator = parsedDecorator;
1638
+ }
1639
+ static {
1640
+ __name(this, "RootDecoratorInstance");
1641
+ }
1642
+ isRootDecorator = true;
1643
+ get graph() {
1644
+ return this.dataSource.graph;
1645
+ }
1646
+ };
1647
+ var builtInRootDecorators = [
1648
+ {
1649
+ name: "envFlag",
1650
+ deprecated: "use @currentEnv instead"
1651
+ },
1652
+ {
1653
+ name: "currentEnv",
1654
+ incompatibleWith: ["envFlag"]
1655
+ },
1656
+ {
1657
+ name: "defaultRequired",
1658
+ process: /* @__PURE__ */ __name((decVal) => {
1659
+ if (!decVal.isStatic || ![true, false, "infer"].includes(decVal.staticValue)) {
1660
+ throw new Error('@defaultRequired decorator value must be set to a static value of true, false, or "infer"');
1661
+ }
1662
+ }, "process")
1663
+ },
1664
+ {
1665
+ name: "defaultSensitive",
1666
+ process: /* @__PURE__ */ __name((decVal) => {
1667
+ if (decVal.isStatic && !my_dash_default.isBoolean(decVal.staticValue) || !decVal.isStatic && decVal.fnName && decVal.fnName !== "inferFromPrefix") {
1668
+ throw new Error("only true, false, or `inferFromPrefix()` is allowed for @defaultSensitive decorator");
1669
+ }
1670
+ }, "process")
1671
+ },
1672
+ {
1673
+ name: "disable"
1674
+ },
1675
+ {
1676
+ name: "generateTypes",
1677
+ isFunction: true
1678
+ },
1679
+ {
1680
+ name: "import",
1681
+ isFunction: true,
1682
+ process: /* @__PURE__ */ __name((decVal) => {
1683
+ if (!decVal.arrArgs || decVal.arrArgs.length === 0) {
1684
+ throw new Error("@import decorator must have at least one argument - the path to import");
1685
+ }
1686
+ if (decVal.arrArgs.some((a2) => !a2.isStatic)) {
1687
+ throw new Error("@import decorator cannot use any dynamic values - all args must be static");
1688
+ }
1689
+ }, "process")
1690
+ },
1691
+ {
1692
+ name: "plugin",
1693
+ isFunction: true
1694
+ },
1695
+ {
1696
+ name: "redactLogs"
1697
+ },
1698
+ {
1699
+ name: "preventLeaks"
1700
+ }
1701
+ ];
1702
+ var builtInItemDecorators = [
1703
+ {
1704
+ name: "required"
1705
+ },
1706
+ {
1707
+ name: "optional",
1708
+ incompatibleWith: ["required"]
1709
+ },
1710
+ {
1711
+ name: "sensitive"
1712
+ },
1713
+ {
1714
+ name: "type",
1715
+ useFnArgsResolver: true
1716
+ },
1717
+ {
1718
+ name: "example"
1719
+ },
1720
+ {
1721
+ name: "docsUrl",
1722
+ deprecated: "use `docs()` instead"
1723
+ },
1724
+ {
1725
+ name: "docs",
1726
+ isFunction: true
1727
+ },
1728
+ {
1729
+ name: "icon"
1730
+ }
1731
+ ];
1406
1732
 
1407
1733
  // env-graph/lib/resolver.ts
1408
1734
  var execAsync = promisify(exec);
1409
1735
  var Resolver = class {
1410
- constructor(fnArgs) {
1411
- this.fnArgs = fnArgs;
1736
+ constructor(arrArgs, objArgs, dataSource) {
1737
+ this.arrArgs = arrArgs;
1738
+ this.objArgs = objArgs;
1739
+ this.dataSource = dataSource;
1740
+ if (this.def.inferredType) this.inferredType = this.def.inferredType;
1412
1741
  }
1413
1742
  static {
1414
1743
  __name(this, "Resolver");
1415
1744
  }
1416
- static fnName;
1745
+ static def;
1746
+ static get fnName() {
1747
+ return this.def.name;
1748
+ }
1749
+ get def() {
1750
+ return this.constructor.def;
1751
+ }
1752
+ get fnName() {
1753
+ return this.def.name;
1754
+ }
1755
+ get label() {
1756
+ return this.def.label;
1757
+ }
1758
+ get icon() {
1759
+ return this.def.icon;
1760
+ }
1761
+ get isStatic() {
1762
+ return false;
1763
+ }
1764
+ get staticValue() {
1765
+ return void 0;
1766
+ }
1417
1767
  inferredType;
1418
1768
  _schemaErrors = [];
1419
1769
  _depsObj = {};
1420
1770
  get childResolvers() {
1421
- return this.fnArgs.flatMap((r) => my_dash_default.isPlainObject(r) ? my_dash_default.values(r) : r);
1771
+ return [
1772
+ ...this.arrArgs ?? [],
1773
+ ...Object.values(this.objArgs ?? {})
1774
+ ];
1422
1775
  }
1423
1776
  get schemaErrors() {
1424
1777
  return [
@@ -1426,6 +1779,9 @@ var Resolver = class {
1426
1779
  ...this.childResolvers.flatMap((r) => r.schemaErrors)
1427
1780
  ];
1428
1781
  }
1782
+ set schemaErrors(v) {
1783
+ throw new Error("set _schemaErrors instead");
1784
+ }
1429
1785
  get depsObj() {
1430
1786
  const mergedDepsObj = { ...this._depsObj };
1431
1787
  this.childResolvers.forEach((r) => Object.assign(mergedDepsObj, r.depsObj));
@@ -1434,243 +1790,308 @@ var Resolver = class {
1434
1790
  get deps() {
1435
1791
  return Object.keys(this.depsObj);
1436
1792
  }
1437
- configItem;
1438
- async process(configItem) {
1439
- this.configItem = configItem;
1440
- try {
1441
- await this._process(configItem);
1442
- } catch (error) {
1443
- if (error instanceof SchemaError) {
1444
- this._schemaErrors.push(error);
1445
- } else if (error instanceof Error) {
1446
- this._schemaErrors.push(new SchemaError(error));
1447
- } else {
1448
- throw new Error(`Non-error thrown while processing resolver - ${error}`);
1793
+ parent;
1794
+ meta;
1795
+ process(parent) {
1796
+ this.parent = parent;
1797
+ const { argsSchema } = this.def;
1798
+ if (argsSchema?.type === "array" && this.objArgs !== void 0) {
1799
+ this._schemaErrors.push(new SchemaError("Resolver does not support key-value args"));
1800
+ } else if (argsSchema?.type === "object" && this.arrArgs !== void 0) {
1801
+ this._schemaErrors.push(new SchemaError("Resolver expects only key-value args"));
1802
+ }
1803
+ if (argsSchema?.arrayExactLength !== void 0) {
1804
+ if (this.arrArgs?.length !== argsSchema.arrayExactLength) {
1805
+ this._schemaErrors.push(
1806
+ new SchemaError(
1807
+ `expects exactly ${argsSchema.arrayExactLength} argument${argsSchema.arrayExactLength > 1 ? "s" : ""}`
1808
+ )
1809
+ );
1810
+ }
1811
+ }
1812
+ if (argsSchema?.arrayMinLength !== void 0) {
1813
+ if ((this.arrArgs?.length ?? 0) < argsSchema.arrayMinLength) {
1814
+ this._schemaErrors.push(
1815
+ new SchemaError(
1816
+ `expects at least ${argsSchema.arrayMinLength} argument${argsSchema.arrayMinLength > 1 ? "s" : ""}`
1817
+ )
1818
+ );
1819
+ }
1820
+ }
1821
+ if (argsSchema?.arrayMaxLength !== void 0) {
1822
+ if ((this.arrArgs?.length ?? 0) > argsSchema.arrayMaxLength) {
1823
+ this._schemaErrors.push(
1824
+ new SchemaError(`expects at most ${argsSchema.arrayMaxLength} argument${argsSchema.arrayMaxLength > 1 ? "s" : ""}`)
1825
+ );
1826
+ }
1827
+ }
1828
+ if (argsSchema?.objKeyMinLength !== void 0) {
1829
+ const objKeyLengths = Object.keys(this.objArgs || {}).length;
1830
+ if (objKeyLengths < argsSchema.objKeyMinLength) {
1831
+ this._schemaErrors.push(
1832
+ new SchemaError(
1833
+ `expects at least ${argsSchema.objKeyMinLength} key value arg${argsSchema.objKeyMinLength > 1 ? "s" : ""}`
1834
+ )
1835
+ );
1836
+ }
1837
+ }
1838
+ if (this._schemaErrors.length === 0) {
1839
+ try {
1840
+ this.meta = this.def.process?.call(this);
1841
+ } catch (error) {
1842
+ if (error instanceof SchemaError) {
1843
+ this._schemaErrors.push(error);
1844
+ } else if (error instanceof Error) {
1845
+ this._schemaErrors.push(new SchemaError(error));
1846
+ } else {
1847
+ throw new Error(`Non-error thrown while processing resolver - ${error}`);
1848
+ }
1849
+ }
1850
+ }
1851
+ if (!this.def.name.startsWith("\0")) {
1852
+ for (const e of this._schemaErrors) {
1853
+ e.message = `${this.def.name}(): ${e.message}`;
1449
1854
  }
1450
1855
  }
1451
- this.childResolvers.forEach((r) => r.process(configItem));
1856
+ this.childResolvers.forEach((r) => {
1857
+ r.process(parent);
1858
+ });
1452
1859
  }
1453
1860
  // meant to be used by subclass _process methods
1454
1861
  addDep(key) {
1455
- this._depsObj[key] = true;
1456
- if (!this.configItem) throw new Error("expected configItem to be set");
1457
- if (!this.configItem.envGraph.configSchema[key]) {
1458
- this._schemaErrors.push(new SchemaError(`Unknown referenced key: ${key}`));
1862
+ if (!this.envGraph.configSchema[key]) {
1863
+ throw new Error(`invalid dependency: ${key}`);
1459
1864
  }
1865
+ this._depsObj[key] = true;
1866
+ }
1867
+ async getCurrentEnv() {
1868
+ if (!this.dataSource) throw new Error("expected dataSource to be set");
1869
+ await this.dataSource.resolveCurrentEnv();
1870
+ return this.dataSource.envFlagValue ? String(this.dataSource.envFlagValue) : void 0;
1460
1871
  }
1461
1872
  async resolve() {
1462
- const resolvedValue = await this._resolve();
1873
+ const resolvedValue = await this.def.resolve.call(this, this.meta);
1463
1874
  return resolvedValue;
1464
1875
  }
1876
+ get envGraph() {
1877
+ if (this.parent instanceof ConfigItem) {
1878
+ return this.parent.envGraph;
1879
+ } else if (this.parent instanceof DecoratorInstance) {
1880
+ return this.parent.graph;
1881
+ }
1882
+ }
1465
1883
  // meant to be used by subclass _resolve methods
1466
1884
  getDepValue(key) {
1467
- const depItem = this.configItem?.envGraph.configSchema[key];
1468
- if (!depItem) throw new Error(`Expected to find item - ${key}`);
1885
+ const depItem = this.envGraph?.configSchema[key];
1886
+ if (!depItem) throw new Error(`Referenced item "${key}" not found`);
1887
+ if (!depItem.isValid) throw new Error(`Referenced item "${key}" is not valid`);
1469
1888
  return depItem.resolvedValue;
1470
1889
  }
1471
1890
  };
1472
1891
  var StaticValueResolver = class extends Resolver {
1473
- constructor(staticValue) {
1892
+ constructor(_staticValue) {
1474
1893
  super([]);
1475
- this.staticValue = staticValue;
1476
- if (staticValue !== void 0) {
1477
- this.inferredType = typeof staticValue;
1894
+ this._staticValue = _staticValue;
1895
+ if (_staticValue !== void 0) {
1896
+ this.inferredType = typeof _staticValue;
1478
1897
  }
1479
1898
  }
1480
1899
  static {
1481
1900
  __name(this, "StaticValueResolver");
1482
1901
  }
1483
- label = "static";
1484
- icon = "bi:dash";
1485
- async _resolve() {
1486
- return this.staticValue;
1902
+ static def = {
1903
+ name: "\0static",
1904
+ // used internally, so we add the extra \0
1905
+ icon: "bi:dash",
1906
+ async resolve() {
1907
+ return this.staticValue;
1908
+ }
1909
+ };
1910
+ // helper so plugins dont need to import and use instanceof
1911
+ get isStatic() {
1912
+ return true;
1487
1913
  }
1488
- async _process() {
1914
+ get staticValue() {
1915
+ return this._staticValue;
1489
1916
  }
1490
1917
  };
1491
- var ErrorResolver = class extends Resolver {
1918
+ var FunctionArgsResolver = class extends Resolver {
1492
1919
  static {
1493
- __name(this, "ErrorResolver");
1920
+ __name(this, "FunctionArgsResolver");
1921
+ }
1922
+ // we might want to just have a resolve function which resolves all children
1923
+ // but it might be useful to let the decorator do it individually
1924
+ // so that some can be skipped depending on the other args
1925
+ static def = {
1926
+ name: "\0fnArgs",
1927
+ // used internally, so we add the extra \0
1928
+ label: "function args",
1929
+ icon: "bi:dash",
1930
+ // not actualyl used
1931
+ resolve() {
1932
+ return void 0;
1933
+ }
1934
+ };
1935
+ // special helper to resolve all child args
1936
+ async resolve() {
1937
+ const resolvedArrayArgs = [];
1938
+ const resolvedObjArgs = {};
1939
+ for (const arg of this.arrArgs || []) {
1940
+ resolvedArrayArgs.push(await arg.resolve());
1941
+ }
1942
+ for (const key in this.objArgs) {
1943
+ resolvedObjArgs[key] = await this.objArgs[key].resolve();
1944
+ }
1945
+ return {
1946
+ arr: resolvedArrayArgs,
1947
+ obj: resolvedObjArgs
1948
+ };
1494
1949
  }
1950
+ };
1951
+ var ErrorResolver = class extends Resolver {
1495
1952
  constructor(err) {
1496
1953
  super([]);
1954
+ this.err = err;
1497
1955
  this._schemaErrors.push(err);
1498
1956
  }
1499
- label = "error";
1500
- icon = "bi:dash";
1501
- async _resolve() {
1502
- return void 0;
1503
- }
1504
- async _process() {
1505
- }
1506
- };
1507
- var ConcatResolver = class extends Resolver {
1508
1957
  static {
1509
- __name(this, "ConcatResolver");
1958
+ __name(this, "ErrorResolver");
1510
1959
  }
1511
- static fnName = "concat";
1512
- label = "concat";
1513
- icon = "material-symbols:join";
1514
- inferredType = "string";
1515
- async _process() {
1516
- if (this.fnArgs.some((arg) => my_dash_default.isPlainObject(arg))) {
1517
- throw new SchemaError("concat() does not support key-value arguments");
1960
+ static def = {
1961
+ name: "\0error",
1962
+ // used internally, so we add the extra \0
1963
+ icon: "bi:dash",
1964
+ async resolve() {
1965
+ return void 0;
1518
1966
  }
1519
- if (this.fnArgs.length < 2) {
1520
- throw new SchemaError("concat() expects at least two arguments");
1967
+ };
1968
+ };
1969
+ function createResolver(def) {
1970
+ const ResolverClass = class extends Resolver {
1971
+ static {
1972
+ __name(this, "ResolverClass");
1521
1973
  }
1522
- }
1523
- async _resolve() {
1974
+ };
1975
+ ResolverClass.def = def;
1976
+ return ResolverClass;
1977
+ }
1978
+ __name(createResolver, "createResolver");
1979
+ var ConcatResolver = createResolver({
1980
+ name: "concat",
1981
+ icon: "material-symbols:join",
1982
+ inferredType: "string",
1983
+ argsSchema: {
1984
+ type: "array",
1985
+ arrayMinLength: 2
1986
+ },
1987
+ async resolve() {
1524
1988
  const resolvedValues = [];
1525
- for (const arg of this.fnArgs) {
1526
- if (my_dash_default.isPlainObject(arg)) {
1527
- throw new Error("concat() does not support key-value arguments");
1528
- }
1989
+ for (const arg of this.arrArgs ?? []) {
1529
1990
  const resolvedChildValue = await arg.resolve();
1530
1991
  resolvedValues.push(String(resolvedChildValue ?? ""));
1531
1992
  }
1532
1993
  return resolvedValues.join("");
1533
1994
  }
1534
- };
1535
- var FallbackResolver = class extends Resolver {
1536
- static {
1537
- __name(this, "FallbackResolver");
1538
- }
1539
- static fnName = "fallback";
1540
- label = "fallback";
1541
- icon = "memory:table-top-stairs-up";
1542
- async _process() {
1543
- if (this.fnArgs.some((arg) => my_dash_default.isPlainObject(arg))) {
1544
- throw new SchemaError("fallback() does not support key-value arguments");
1545
- }
1546
- if (this.fnArgs.length < 2) {
1547
- throw new SchemaError("fallback() expects at least two arguments");
1548
- }
1549
- }
1550
- async _resolve() {
1551
- for (const arg of this.fnArgs) {
1552
- if (my_dash_default.isPlainObject(arg)) throw new Error("fallback() does not support key-value arguments");
1995
+ });
1996
+ var FallbackResolver = createResolver({
1997
+ name: "fallback",
1998
+ icon: "memory:table-top-stairs-up",
1999
+ argsSchema: {
2000
+ type: "array",
2001
+ arrayMinLength: 2
2002
+ },
2003
+ async resolve() {
2004
+ for (const arg of this.arrArgs ?? []) {
1553
2005
  const resolvedChildValue = await arg.resolve();
1554
2006
  if (resolvedChildValue !== void 0 && resolvedChildValue !== "") {
1555
2007
  return resolvedChildValue;
1556
2008
  }
1557
2009
  }
1558
2010
  }
1559
- };
1560
- var ExecResolver = class _ExecResolver extends Resolver {
1561
- static {
1562
- __name(this, "ExecResolver");
1563
- }
1564
- static fnName = "exec";
1565
- label = "exec";
1566
- icon = "iconoir:terminal";
1567
- async _process() {
1568
- if (this.fnArgs.length !== 1) {
1569
- throw new SchemaError("exec() expects a single child arg");
1570
- }
1571
- if (this.fnArgs.some((arg) => my_dash_default.isPlainObject(arg))) {
1572
- throw new SchemaError("exec() does not support key-value arguments");
1573
- }
1574
- }
1575
- static execQueue = new SimpleQueue();
1576
- async _resolve() {
1577
- if (my_dash_default.isPlainObject(this.fnArgs[0])) throw new Error("exec() does not support key-value arguments");
1578
- const commandStr = await this.fnArgs[0].resolve();
2011
+ });
2012
+ var execQueue = new SimpleQueue();
2013
+ var ExecResolver = createResolver({
2014
+ name: "exec",
2015
+ icon: "iconoir:terminal",
2016
+ argsSchema: {
2017
+ type: "array",
2018
+ arrayExactLength: 1
2019
+ },
2020
+ async resolve() {
2021
+ const commandStr = await this.arrArgs?.[0].resolve();
1579
2022
  if (typeof commandStr !== "string") {
1580
- throw new ResolutionError("exec() expects a string child arg");
2023
+ throw new ResolutionError("exec() expects a string arg");
1581
2024
  }
1582
2025
  try {
1583
- const { stdout } = await _ExecResolver.execQueue.enqueue(() => execAsync(commandStr));
2026
+ const { stdout } = await execQueue.enqueue(() => execAsync(commandStr));
1584
2027
  return stdout.replace(/\n$/, "");
1585
2028
  } catch (err) {
1586
2029
  console.log("exec() failed", err);
1587
2030
  throw new ResolutionError(`exec() command failed: ${commandStr}`);
1588
2031
  }
1589
2032
  }
1590
- };
1591
- var RefResolver = class extends Resolver {
1592
- static {
1593
- __name(this, "RefResolver");
1594
- }
1595
- static fnName = "ref";
1596
- label = "ref";
1597
- icon = "mdi-light:content-duplicate";
1598
- refKey;
1599
- async _process() {
1600
- if (this.fnArgs.length !== 1) {
1601
- throw new SchemaError("ref() expects a single child arg");
1602
- }
1603
- if (!(this.fnArgs[0] instanceof StaticValueResolver)) {
1604
- throw new SchemaError("ref() expects a single static value passed in");
2033
+ });
2034
+ var RefResolver = createResolver({
2035
+ name: "ref",
2036
+ icon: "mdi-light:content-duplicate",
2037
+ argsSchema: {
2038
+ type: "array",
2039
+ arrayExactLength: 1
2040
+ },
2041
+ process() {
2042
+ if (!(this.arrArgs?.[0] instanceof StaticValueResolver)) {
2043
+ throw new SchemaError("expects a single static value passed in");
1605
2044
  }
1606
- const keyName = this.fnArgs[0].staticValue;
1607
- if (typeof keyName !== "string") {
1608
- throw new SchemaError("ref() expects a string keyname passed in");
2045
+ const refKey = this.arrArgs[0].staticValue;
2046
+ if (typeof refKey !== "string") {
2047
+ throw new SchemaError("expects a string keyname passed in");
1609
2048
  }
1610
- this.refKey = keyName;
1611
- this.addDep(keyName);
1612
- }
1613
- async _resolve() {
1614
- if (!this.refKey) throw new Error("expected refKey to be set");
1615
- return this.getDepValue(this.refKey);
1616
- }
1617
- };
1618
- var RegexResolver = class extends Resolver {
1619
- static {
1620
- __name(this, "RegexResolver");
2049
+ this.addDep(refKey);
2050
+ return refKey;
2051
+ },
2052
+ async resolve(refKey) {
2053
+ return this.getDepValue(refKey);
1621
2054
  }
1622
- static fnName = "regex";
1623
- label = "regex";
1624
- icon = "mdi:regex";
1625
- regex;
1626
- async _process() {
1627
- if (this.fnArgs.length !== 1) {
1628
- throw new SchemaError("regex() expects a single child arg");
1629
- }
1630
- if (!(this.fnArgs[0] instanceof StaticValueResolver)) {
1631
- throw new SchemaError("regex() expects a single static value passed in");
2055
+ });
2056
+ var RegexResolver = createResolver({
2057
+ name: "regex",
2058
+ icon: "mdi:regex",
2059
+ argsSchema: {
2060
+ type: "array",
2061
+ arrayExactLength: 1
2062
+ },
2063
+ process() {
2064
+ if (!(this.arrArgs?.[0] instanceof StaticValueResolver)) {
2065
+ throw new SchemaError("expects a single static value passed in");
1632
2066
  }
1633
- const regexStr = this.fnArgs[0].staticValue;
2067
+ const regexStr = this.arrArgs[0].staticValue;
1634
2068
  if (typeof regexStr !== "string") {
1635
- throw new SchemaError("regex() expects a string");
1636
- }
1637
- this.regex = new RegExp(regexStr);
1638
- }
1639
- async _resolve() {
1640
- if (!this.regex) throw new Error("expected regex to be set");
1641
- return this.regex;
1642
- }
1643
- };
1644
- var RemapResolver = class extends Resolver {
1645
- static {
1646
- __name(this, "RemapResolver");
1647
- }
1648
- static fnName = "remap";
1649
- label = "remap";
1650
- icon = "codicon:replace";
1651
- remappings;
1652
- async _process() {
1653
- if (my_dash_default.isPlainObject(this.fnArgs[0])) {
1654
- throw new SchemaError("remap() expects the first arg to be the value to remap");
1655
- }
1656
- if (!my_dash_default.isPlainObject(this.fnArgs[1])) {
1657
- throw new SchemaError("remap() expects the all args after the first to be key-value pairs of remappings");
2069
+ throw new SchemaError("expects a string");
1658
2070
  }
1659
- if (this.fnArgs.length !== 2) {
1660
- throw new SchemaError("remap() should not have any additional non key-value args after remappings");
2071
+ try {
2072
+ return new RegExp(regexStr);
2073
+ } catch (err) {
2074
+ throw new SchemaError(err.message);
1661
2075
  }
1662
- this.remappings = this.fnArgs[1];
2076
+ },
2077
+ async resolve(regex) {
2078
+ return regex;
1663
2079
  }
1664
- async _resolve() {
1665
- if (my_dash_default.isPlainObject(this.fnArgs[0])) {
1666
- throw new SchemaError("remap() expects the first arg to be the value to remap");
1667
- }
1668
- if (!my_dash_default.isPlainObject(this.fnArgs[1])) {
1669
- throw new SchemaError("remap() expects the all args after the first to be key-value pairs of remappings");
1670
- }
1671
- const originalValue = await this.fnArgs[0].resolve();
1672
- if (!this.remappings) throw new Error("expected remappings to be set");
1673
- for (const [remappedVal, matchValResolver] of Object.entries(this.remappings)) {
2080
+ });
2081
+ var RemapResolver = createResolver({
2082
+ name: "remap",
2083
+ icon: "codicon:replace",
2084
+ argsSchema: {
2085
+ type: "mixed",
2086
+ arrayExactLength: 1,
2087
+ objKeyMinLength: 1
2088
+ },
2089
+ process() {
2090
+ return this.objArgs;
2091
+ },
2092
+ async resolve(remappings) {
2093
+ const originalValue = await this.arrArgs[0].resolve();
2094
+ for (const [remappedVal, matchValResolver] of Object.entries(remappings)) {
1674
2095
  const matchVal = await matchValResolver.resolve();
1675
2096
  if (matchVal instanceof RegExp && originalValue !== void 0) {
1676
2097
  if (matchVal.test(String(originalValue))) return remappedVal;
@@ -1680,15 +2101,137 @@ var RemapResolver = class extends Resolver {
1680
2101
  }
1681
2102
  return originalValue;
1682
2103
  }
1683
- };
2104
+ });
2105
+ var ForEnvResolver = createResolver({
2106
+ name: "forEnv",
2107
+ icon: "tabler:flag-question",
2108
+ inferredType: "boolean",
2109
+ argsSchema: {
2110
+ type: "array",
2111
+ arrayMinLength: 1
2112
+ },
2113
+ process() {
2114
+ const matchEnvs = this.arrArgs.map((r) => String(r.staticValue));
2115
+ return matchEnvs;
2116
+ },
2117
+ async resolve(matchEnvs) {
2118
+ const currentEnv = await this.getCurrentEnv();
2119
+ if (!currentEnv) throw new Error("current environment is not set");
2120
+ return currentEnv && matchEnvs.includes(currentEnv || "");
2121
+ }
2122
+ });
2123
+ var EqResolver = createResolver({
2124
+ name: "eq",
2125
+ icon: "material-symbols:equal",
2126
+ inferredType: "boolean",
2127
+ argsSchema: {
2128
+ type: "array",
2129
+ arrayExactLength: 2
2130
+ },
2131
+ process() {
2132
+ return { left: this.arrArgs[0], right: this.arrArgs[1] };
2133
+ },
2134
+ async resolve({ left, right }) {
2135
+ const leftVal = await left.resolve();
2136
+ const rightVal = await right.resolve();
2137
+ return leftVal === rightVal;
2138
+ }
2139
+ });
2140
+ var IfResolver = createResolver({
2141
+ name: "if",
2142
+ icon: "material-symbols:help-center",
2143
+ // question mark
2144
+ argsSchema: {
2145
+ type: "array",
2146
+ arrayMinLength: 2
2147
+ },
2148
+ process() {
2149
+ const condition = this.arrArgs[0];
2150
+ const trueVal = this.arrArgs[1];
2151
+ const falseVal = this.arrArgs[2];
2152
+ if (!falseVal || trueVal.inferredType === falseVal.inferredType) {
2153
+ this.inferredType = trueVal.inferredType;
2154
+ }
2155
+ return { condition, trueVal, falseVal };
2156
+ },
2157
+ async resolve({ condition, trueVal, falseVal }) {
2158
+ const conditionVal = await condition.resolve();
2159
+ if (conditionVal) {
2160
+ return trueVal.resolve();
2161
+ } else {
2162
+ return falseVal?.resolve();
2163
+ }
2164
+ }
2165
+ });
2166
+ var InferFromPrefixResolver = createResolver({
2167
+ name: "inferFromPrefix",
2168
+ icon: "material-symbols:help-center",
2169
+ // question mark
2170
+ argsSchema: {
2171
+ type: "array",
2172
+ arrayExactLength: 1
2173
+ },
2174
+ process() {
2175
+ return this.arrArgs[0].staticValue;
2176
+ },
2177
+ async resolve(_prefix) {
2178
+ return void 0;
2179
+ }
2180
+ });
1684
2181
  var BaseResolvers = [
1685
2182
  ConcatResolver,
1686
2183
  FallbackResolver,
1687
2184
  RefResolver,
1688
2185
  ExecResolver,
1689
2186
  RemapResolver,
1690
- RegexResolver
2187
+ ForEnvResolver,
2188
+ EqResolver,
2189
+ IfResolver,
2190
+ RegexResolver,
2191
+ InferFromPrefixResolver
1691
2192
  ];
2193
+ function convertParsedValueToResolvers(value, dataSource, registeredResolvers) {
2194
+ if (value === void 0) {
2195
+ return void 0;
2196
+ } else if (value instanceof ParsedEnvSpecStaticValue) {
2197
+ return new StaticValueResolver(value.unescapedValue);
2198
+ } else if (value instanceof ParsedEnvSpecFunctionCall || value instanceof ParsedEnvSpecFunctionArgs) {
2199
+ let ResolverFnClass;
2200
+ let argsFromParser;
2201
+ if (value instanceof ParsedEnvSpecFunctionCall) {
2202
+ ResolverFnClass = registeredResolvers[value.name];
2203
+ if (!ResolverFnClass) {
2204
+ return new ErrorResolver(new SchemaError(`Unknown resolver function: ${value.name}()`));
2205
+ }
2206
+ argsFromParser = value.data.args.values;
2207
+ } else {
2208
+ ResolverFnClass = FunctionArgsResolver;
2209
+ argsFromParser = value.values;
2210
+ }
2211
+ let arrArgsAsResolvers;
2212
+ let objArgsAsResolvers;
2213
+ for (const arg of argsFromParser) {
2214
+ if (arg instanceof ParsedEnvSpecKeyValuePair) {
2215
+ objArgsAsResolvers ??= {};
2216
+ const valResolver = convertParsedValueToResolvers(arg.value, dataSource, registeredResolvers);
2217
+ if (!valResolver) throw new Error("Did not expect to find undefined resolver in key-value arg");
2218
+ objArgsAsResolvers[arg.key] = valResolver;
2219
+ } else {
2220
+ if (objArgsAsResolvers) {
2221
+ return new ErrorResolver(new SchemaError("After switching to key-value function args, cannot switch back"));
2222
+ }
2223
+ const argResolver = convertParsedValueToResolvers(arg, dataSource, registeredResolvers);
2224
+ if (!argResolver) throw new Error("Did not expect to find undefined resolver in array arg");
2225
+ arrArgsAsResolvers ??= [];
2226
+ arrArgsAsResolvers.push(argResolver);
2227
+ }
2228
+ }
2229
+ return new ResolverFnClass(arrArgsAsResolvers, objArgsAsResolvers, dataSource);
2230
+ } else {
2231
+ throw new Error("Unknown value type");
2232
+ }
2233
+ }
2234
+ __name(convertParsedValueToResolvers, "convertParsedValueToResolvers");
1692
2235
 
1693
2236
  // env-graph/lib/graph-utils.ts
1694
2237
  function findGraphCycles(graph) {
@@ -1873,6 +2416,21 @@ async function generateTypes(graph, lang, typesPath) {
1873
2416
  }
1874
2417
  __name(generateTypes, "generateTypes");
1875
2418
 
2419
+ // env-graph/lib/error-location.ts
2420
+ function getErrorLocation(source, parserNode) {
2421
+ if (!(source instanceof FileBasedDataSource)) return;
2422
+ if (!parserNode.data || !parserNode.data._location || !my_dash_default.isNumber(parserNode.data._location.start.line)) return;
2423
+ const lineNumber = parserNode.data._location?.start.line;
2424
+ const colNumber = parserNode.data._location?.start.column;
2425
+ return {
2426
+ id: source.fullPath,
2427
+ lineNumber,
2428
+ colNumber,
2429
+ lineStr: source.rawContents?.split("\n")[lineNumber - 1]?.trim() || ""
2430
+ };
2431
+ }
2432
+ __name(getErrorLocation, "getErrorLocation");
2433
+
1876
2434
  // env-graph/lib/env-graph.ts
1877
2435
  var processExists = !!globalThis.process;
1878
2436
  var originalProcessEnv = { ...processExists && process.env };
@@ -1918,15 +2476,41 @@ var EnvGraph2 = class {
1918
2476
  }
1919
2477
  dataTypesRegistry = {};
1920
2478
  registerDataType(factory) {
2479
+ const name = factory.dataTypeName;
2480
+ if (name in this.dataTypesRegistry) {
2481
+ throw new Error(`Data type "${name}" already registered`);
2482
+ }
1921
2483
  this.dataTypesRegistry[factory.dataTypeName] = factory;
1922
2484
  }
2485
+ itemDecoratorsRegistry = {};
2486
+ registerItemDecorator(decoratorDef) {
2487
+ const name = decoratorDef.name;
2488
+ if (name in this.itemDecoratorsRegistry) {
2489
+ throw new Error(`Item decorator "${name}" already registered`);
2490
+ }
2491
+ this.itemDecoratorsRegistry[decoratorDef.name] = decoratorDef;
2492
+ }
2493
+ rootDecoratorsRegistry = {};
2494
+ registerRootDecorator(decoratorDef) {
2495
+ const name = decoratorDef.name;
2496
+ if (name in this.itemDecoratorsRegistry) {
2497
+ throw new Error(`Root decorator "${name}" already registered`);
2498
+ }
2499
+ this.rootDecoratorsRegistry[decoratorDef.name] = decoratorDef;
2500
+ }
1923
2501
  constructor() {
1924
- for (const dataType of my_dash_default.values(BaseDataTypes)) {
2502
+ for (const dataType of BaseDataTypes) {
1925
2503
  this.registerDataType(dataType);
1926
2504
  }
1927
2505
  for (const resolverClass of BaseResolvers) {
1928
2506
  this.registerResolver(resolverClass);
1929
2507
  }
2508
+ for (const rootDec of builtInRootDecorators) {
2509
+ this.registerRootDecorator(rootDec);
2510
+ }
2511
+ for (const itemDec of builtInItemDecorators) {
2512
+ this.registerItemDecorator(itemDec);
2513
+ }
1930
2514
  this.overrideValues = originalProcessEnv;
1931
2515
  }
1932
2516
  async setRootDataSource(source) {
@@ -1936,33 +2520,67 @@ var EnvGraph2 = class {
1936
2520
  await source.finishInit();
1937
2521
  }
1938
2522
  async finishLoad() {
2523
+ for (const source of this.sortedDataSources) {
2524
+ if (!source.isValid) return;
2525
+ }
2526
+ for (const plugin of this.plugins) {
2527
+ if (plugin.loadingError) return;
2528
+ }
2529
+ let processingError = false;
2530
+ for (const source of this.sortedDataSources) {
2531
+ if (source.disabled) continue;
2532
+ for (const decInstance of source.rootDecorators) {
2533
+ await decInstance.process();
2534
+ if (decInstance.schemaErrors.length) processingError = true;
2535
+ }
2536
+ }
1939
2537
  for (const itemKey in this.configSchema) {
1940
2538
  const item = this.configSchema[itemKey];
1941
2539
  await item.process();
2540
+ if (item.errors.length) processingError = true;
1942
2541
  }
2542
+ if (processingError) return;
1943
2543
  const cycles = findGraphCycles(this.graphAdjacencyList);
1944
2544
  for (const cycleItemKeys of cycles) {
1945
2545
  for (const itemKey of cycleItemKeys) {
1946
2546
  const item = this.configSchema[itemKey];
1947
- item.schemaErrors.push(
2547
+ item._schemaErrors.push(
1948
2548
  new SchemaError(
1949
2549
  cycleItemKeys.length === 1 ? "Item cannot have dependency on itself" : `Dependency cycle detected: (${cycleItemKeys.join(", ")})`
1950
2550
  )
1951
2551
  );
1952
2552
  }
1953
2553
  }
2554
+ for (const source of this.sortedDataSources) {
2555
+ if (source.disabled) continue;
2556
+ for (const decInstance of source.rootDecorators) {
2557
+ if (!decInstance.decValueResolver) throw new Error("expected decorator value resolver");
2558
+ await this.resolveEnvValues(decInstance.decValueResolver.deps);
2559
+ try {
2560
+ await decInstance.execute();
2561
+ } catch (err) {
2562
+ decInstance._executionError = new SchemaError(
2563
+ err,
2564
+ { location: getErrorLocation(source, decInstance.parsedDecorator) }
2565
+ );
2566
+ }
2567
+ }
2568
+ }
2569
+ await this.getRootDec("redactLogs")?.resolve();
2570
+ await this.getRootDec("preventLeaks")?.resolve();
1954
2571
  }
1955
2572
  get graphAdjacencyList() {
1956
2573
  const adjList = {};
1957
2574
  for (const itemKey in this.configSchema) {
1958
2575
  const item = this.configSchema[itemKey];
1959
- adjList[itemKey] = item.valueResolver?.deps || [];
2576
+ adjList[itemKey] = item.dependencyKeys;
1960
2577
  }
1961
2578
  return adjList;
1962
2579
  }
1963
- async resolveEnvValues() {
1964
- if (my_dash_default.keys(this.configSchema).length === 0) return;
1965
- const adjList = this.graphAdjacencyList;
2580
+ async resolveEnvValues(keys) {
2581
+ const keysToResolve = keys ?? my_dash_default.keys(this.configSchema);
2582
+ if (!keysToResolve.length) return;
2583
+ const adjList = my_dash_default.pick(this.graphAdjacencyList, keysToResolve);
1966
2584
  const reverseAdjList = {};
1967
2585
  for (const itemKey in adjList) {
1968
2586
  const itemDeps = adjList[itemKey];
@@ -1971,7 +2589,7 @@ var EnvGraph2 = class {
1971
2589
  reverseAdjList[dep].push(itemKey);
1972
2590
  }
1973
2591
  }
1974
- const itemsToResolveStatus = my_dash_default.mapValues(this.configSchema, () => false);
2592
+ const itemsToResolveStatus = my_dash_default.fromPairs(keysToResolve.map((key) => [key, false]));
1975
2593
  const deferred = new Promise((resolve, _reject) => {
1976
2594
  const markItemCompleted = /* @__PURE__ */ __name((itemKey) => {
1977
2595
  delete itemsToResolveStatus[itemKey];
@@ -1987,7 +2605,7 @@ var EnvGraph2 = class {
1987
2605
  markItemCompleted(itemKey);
1988
2606
  return;
1989
2607
  }
1990
- for (const depKey of adjList[itemKey]) {
2608
+ for (const depKey of adjList[itemKey] || []) {
1991
2609
  const depItem = this.configSchema[depKey];
1992
2610
  if (depItem.validationState === "error") {
1993
2611
  item.resolutionError = new ResolutionError(`Dependency ${depKey} is invalid`);
@@ -2036,8 +2654,8 @@ var EnvGraph2 = class {
2036
2654
  isSensitive: item.isSensitive
2037
2655
  };
2038
2656
  }
2039
- serializedGraph.settings.redactLogs = this.getRootDecoratorValue("redactLogs") ?? true;
2040
- serializedGraph.settings.preventLeaks = this.getRootDecoratorValue("preventLeaks") ?? true;
2657
+ serializedGraph.settings.redactLogs = this.getRootDec("redactLogs")?.resolvedValue ?? true;
2658
+ serializedGraph.settings.preventLeaks = this.getRootDec("preventLeaks")?.resolvedValue ?? true;
2041
2659
  return serializedGraph;
2042
2660
  }
2043
2661
  get isInvalid() {
@@ -2046,57 +2664,50 @@ var EnvGraph2 = class {
2046
2664
  async generateTypes(lang, outputPath) {
2047
2665
  await generateTypes(this, lang, outputPath);
2048
2666
  }
2049
- getRootDecoratorValue(decoratorName) {
2667
+ getRootDec(decoratorName) {
2050
2668
  const sources = Array.from(this.sortedDataSources).reverse();
2051
2669
  for (const s of sources) {
2052
2670
  if (s.disabled) continue;
2053
2671
  if (s.isPartialImport) continue;
2054
- const decs = s.getRootDecorators(decoratorName);
2055
- if (decs.length) return decs[0].simplifiedValue;
2672
+ const dec = s.getRootDec(decoratorName);
2673
+ if (dec) return dec;
2056
2674
  }
2057
2675
  return void 0;
2058
2676
  }
2059
- getRootDecorators(decoratorName) {
2677
+ getRootDecFns(decoratorName) {
2678
+ const allDecs = [];
2060
2679
  const sources = Array.from(this.sortedDataSources).reverse();
2061
- const combinedDecsWithSources = [];
2062
2680
  for (const source of sources) {
2063
2681
  if (source.disabled) continue;
2064
2682
  if (source.isPartialImport) continue;
2065
- const decs = source.getRootDecorators(decoratorName);
2066
- combinedDecsWithSources.push([source, decs]);
2683
+ const decs = source.getRootDecFns(decoratorName);
2684
+ allDecs.push(...decs);
2067
2685
  }
2068
- return combinedDecsWithSources;
2686
+ return allDecs;
2069
2687
  }
2688
+ /** plugins installed globally in the graph */
2689
+ plugins = [];
2070
2690
  };
2071
2691
 
2072
2692
  // env-graph/lib/config-item.ts
2073
- var ConfigItem4 = class {
2693
+ var ConfigItem = class {
2694
+ constructor(envGraph, key) {
2695
+ this.envGraph = envGraph;
2696
+ this.key = key;
2697
+ }
2074
2698
  static {
2075
2699
  __name(this, "ConfigItem");
2076
2700
  }
2077
- // annoyingly we cannot use readonly if we want to support `erasableSyntaxOnly`
2078
- #envGraph;
2079
- #key;
2080
- constructor(_envGraph, _key) {
2081
- this.#envGraph = _envGraph;
2082
- this.#key = _key;
2083
- }
2084
- get envGraph() {
2085
- return this.#envGraph;
2086
- }
2087
- get key() {
2088
- return this.#key;
2089
- }
2090
2701
  /**
2091
2702
  * fetch ordered list of definitions for this item, by following up sorted data sources list
2092
2703
  */
2093
2704
  get defs() {
2094
2705
  const defs = [];
2095
- for (const source of this.#envGraph.sortedDataSources) {
2096
- if (!source.configItemDefs[this.#key]) continue;
2706
+ for (const source of this.envGraph.sortedDataSources) {
2707
+ if (!source.configItemDefs[this.key]) continue;
2097
2708
  if (source.disabled) continue;
2098
- if (source.importKeys && !source.importKeys.includes(this.#key)) continue;
2099
- const itemDef = source.configItemDefs[this.#key];
2709
+ if (source.importKeys && !source.importKeys.includes(this.key)) continue;
2710
+ const itemDef = source.configItemDefs[this.key];
2100
2711
  if (itemDef) defs.push({ itemDef, source });
2101
2712
  }
2102
2713
  return defs;
@@ -2107,14 +2718,32 @@ var ConfigItem4 = class {
2107
2718
  }
2108
2719
  }
2109
2720
  get icon() {
2110
- const explicitIcon = this.getDecoratorValueString("icon");
2111
- if (explicitIcon) return explicitIcon;
2721
+ const explicitIconDec = this.getDec("icon");
2722
+ if (explicitIconDec) return explicitIconDec.resolvedValue;
2112
2723
  return this.dataType?.icon;
2113
2724
  }
2114
2725
  get docsLinks() {
2115
2726
  const links = [];
2116
- const docsUrl = this.getDecoratorValueString("docsUrl");
2117
- if (docsUrl) links.push({ url: docsUrl });
2727
+ if (this.dataType?.docsEntries) {
2728
+ for (const entry of this.dataType.docsEntries) {
2729
+ if (my_dash_default.isPlainObject(entry)) links.push(entry);
2730
+ else links.push({ url: entry });
2731
+ }
2732
+ }
2733
+ const docsUrlDec = this.getDec("docsUrl");
2734
+ if (docsUrlDec) {
2735
+ links.push({ url: docsUrlDec.resolvedValue });
2736
+ }
2737
+ const docsDecs = this.getDecFns("docs");
2738
+ for (const docsDec of docsDecs) {
2739
+ const decVal = docsDec.resolvedValue;
2740
+ if (!decVal.arr || !my_dash_default.isArray(decVal.arr)) throw new Error("expected an array of docs() args");
2741
+ if (decVal.arr.length === 1) {
2742
+ links.push({ url: decVal.arr[0] });
2743
+ } else if (decVal.arr.length === 2) {
2744
+ links.push({ url: decVal.arr[1], description: decVal.arr[0] });
2745
+ }
2746
+ }
2118
2747
  return links;
2119
2748
  }
2120
2749
  get valueResolver() {
@@ -2122,61 +2751,114 @@ var ConfigItem4 = class {
2122
2751
  return new StaticValueResolver(this.envGraph.overrideValues[this.key]);
2123
2752
  }
2124
2753
  for (const def of this.defs) {
2125
- if (def.itemDef.resolver) return def.itemDef.resolver;
2126
- }
2127
- }
2128
- getDecorator(decoratorName) {
2129
- for (const def of this.defs) {
2130
- const defDecorators = def.itemDef.decorators || {};
2131
- if (decoratorName in defDecorators) {
2132
- return defDecorators[decoratorName];
2754
+ if (def.itemDef.resolver) {
2755
+ return def.itemDef.resolver;
2133
2756
  }
2134
2757
  }
2135
2758
  }
2136
- getDecoratorValueRaw(decoratorName) {
2137
- for (const def of this.defs) {
2138
- const defDecorators = def.itemDef.decorators || {};
2139
- if (decoratorName in defDecorators) {
2140
- return defDecorators[decoratorName].value;
2759
+ allDecorators = [];
2760
+ effectiveDecorators = {};
2761
+ effectiveDecoratorFns = {};
2762
+ getDec(decoratorName) {
2763
+ return this.effectiveDecorators[decoratorName];
2764
+ }
2765
+ getDecFns(decoratorName) {
2766
+ return this.effectiveDecoratorFns[decoratorName] || [];
2767
+ }
2768
+ async resolveDecorators() {
2769
+ for (const dec of Object.values(this.effectiveDecorators)) {
2770
+ await dec.resolve();
2771
+ }
2772
+ for (const decs of Object.values(this.effectiveDecoratorFns)) {
2773
+ for (const dec of decs) {
2774
+ await dec.resolve();
2141
2775
  }
2142
2776
  }
2143
2777
  }
2144
- getDecoratorValueString(decoratorName) {
2145
- const dec = this.getDecoratorValueRaw(decoratorName);
2146
- if (dec instanceof ParsedEnvSpecStaticValue) return String(dec.value);
2147
- }
2148
2778
  dataType;
2149
- schemaErrors = [];
2779
+ _schemaErrors = [];
2150
2780
  get resolverSchemaErrors() {
2151
2781
  return this.valueResolver?.schemaErrors || [];
2152
2782
  }
2783
+ get decoratorSchemaErrors() {
2784
+ return my_dash_default.values(this.allDecorators).flatMap((d) => d.schemaErrors);
2785
+ }
2786
+ isProcessed = false;
2153
2787
  async process() {
2788
+ if (this.isProcessed) return;
2789
+ this.isProcessed = true;
2154
2790
  for (const def of this.defs) {
2791
+ if (def.itemDef.parsedValue && !def.itemDef.resolver) {
2792
+ def.itemDef.resolver = convertParsedValueToResolvers(
2793
+ def.itemDef.parsedValue,
2794
+ def.source,
2795
+ this.envGraph.registeredResolverFunctions
2796
+ );
2797
+ }
2155
2798
  await def.itemDef.resolver?.process(this);
2156
2799
  }
2157
- const typeDecoratorValue = this.getDecoratorValueRaw("type");
2800
+ for (const def of this.defs) {
2801
+ def.itemDef.decorators = def.itemDef.parsedDecorators?.map((d) => new ItemDecoratorInstance(this, def.source, d));
2802
+ const decKeysInThisDef = /* @__PURE__ */ new Set();
2803
+ const allDecsInThisDef = def.itemDef.decorators?.map((d) => d.name);
2804
+ for (const dec of def.itemDef.decorators || []) {
2805
+ await dec.process();
2806
+ this.allDecorators?.push(dec);
2807
+ if (dec.isFunctionCall) {
2808
+ this.effectiveDecoratorFns[dec.name] ||= [];
2809
+ this.effectiveDecoratorFns[dec.name].push(dec);
2810
+ } else {
2811
+ if (decKeysInThisDef.has(dec.name)) {
2812
+ dec._schemaErrors.push(new SchemaError(`decorator @${dec.name} cannot be used twice in same definition`));
2813
+ continue;
2814
+ }
2815
+ if (dec.incompatibleWith) {
2816
+ for (const otherDecName of dec.incompatibleWith) {
2817
+ if (allDecsInThisDef?.includes(otherDecName)) {
2818
+ dec._schemaErrors.push(new SchemaError(`decorator @${dec.name} is incompatible with @${otherDecName} in the same definition`));
2819
+ continue;
2820
+ }
2821
+ }
2822
+ }
2823
+ this.effectiveDecorators[dec.name] ||= dec;
2824
+ }
2825
+ decKeysInThisDef.add(dec.name);
2826
+ }
2827
+ }
2828
+ const typeDec = this.getDec("type");
2158
2829
  let dataTypeName;
2159
2830
  let dataTypeArgs;
2160
- if (typeDecoratorValue instanceof ParsedEnvSpecStaticValue) {
2161
- dataTypeName = typeDecoratorValue.value;
2162
- } else if (typeDecoratorValue instanceof ParsedEnvSpecFunctionCall) {
2163
- dataTypeName = typeDecoratorValue.name;
2164
- dataTypeArgs = typeDecoratorValue.simplifiedArgs;
2831
+ const typeDecParsedValue = typeDec?.parsedDecorator.value;
2832
+ if (typeDecParsedValue instanceof ParsedEnvSpecStaticValue) {
2833
+ dataTypeName = typeDecParsedValue.value;
2834
+ } else if (typeDecParsedValue instanceof ParsedEnvSpecFunctionCall) {
2835
+ dataTypeName = typeDecParsedValue.name;
2836
+ dataTypeArgs = typeDecParsedValue.simplifiedArgs;
2165
2837
  }
2166
- if (!dataTypeName) {
2167
- if (this.valueResolver?.inferredType) {
2168
- dataTypeName = this.valueResolver.inferredType;
2169
- }
2838
+ if (!dataTypeName && this.valueResolver?.inferredType) {
2839
+ dataTypeName = this.valueResolver.inferredType;
2170
2840
  }
2171
2841
  dataTypeName ||= "string";
2172
2842
  dataTypeArgs ||= [];
2173
2843
  if (!(dataTypeName in this.envGraph.dataTypesRegistry)) {
2174
- this.schemaErrors.push(new SchemaError(`unknown data type: ${dataTypeName}`));
2844
+ this._schemaErrors.push(new SchemaError(`unknown data type: ${dataTypeName}`));
2175
2845
  } else {
2176
2846
  const dataTypeFactory = this.envGraph.dataTypesRegistry[dataTypeName];
2177
2847
  this.dataType = dataTypeFactory(...my_dash_default.isPlainObject(dataTypeArgs) ? [dataTypeArgs] : dataTypeArgs);
2178
2848
  }
2179
- this.processRequired();
2849
+ }
2850
+ get dependencyKeys() {
2851
+ return my_dash_default.uniq([
2852
+ ...this.valueResolver?.deps || [],
2853
+ ...my_dash_default.values(this.effectiveDecorators).flatMap(
2854
+ (dec) => dec.decValueResolver?.deps || []
2855
+ ),
2856
+ ...my_dash_default.values(this.effectiveDecoratorFns).flatMap(
2857
+ (decArr) => decArr.flatMap(
2858
+ (d) => d.decValueResolver?.deps || []
2859
+ )
2860
+ )
2861
+ ]);
2180
2862
  }
2181
2863
  /**
2182
2864
  * special early resolution helper
@@ -2184,18 +2866,14 @@ var ConfigItem4 = class {
2184
2866
  * */
2185
2867
  async earlyResolve() {
2186
2868
  await this.process();
2187
- for (const depKey of this.valueResolver?.deps || []) {
2869
+ for (const depKey of this.dependencyKeys) {
2188
2870
  const depItem = this.envGraph.configSchema[depKey];
2189
2871
  if (!depItem) {
2190
2872
  throw new Error(`eager resolution eror - non-existant dependency: ${depKey}`);
2191
2873
  }
2192
- await depItem.process();
2193
- if (depItem.valueResolver?.deps.length) {
2194
- throw new Error("eager resolution cannot follow a chain of dependencies");
2195
- }
2196
- await depItem.resolve(true);
2874
+ await depItem.earlyResolve();
2197
2875
  }
2198
- await this.resolve(true);
2876
+ await this.resolve();
2199
2877
  }
2200
2878
  _isRequired = true;
2201
2879
  /**
@@ -2203,61 +2881,45 @@ var ConfigItem4 = class {
2203
2881
  * because that will affect type generation (only _always_ required items are never undefined)
2204
2882
  * */
2205
2883
  _isRequiredDynamic = false;
2206
- processRequired() {
2884
+ async processRequired() {
2207
2885
  try {
2208
2886
  for (const def of this.defs) {
2209
- const defDecorators = def.itemDef.decorators || {};
2210
- if ("required" in defDecorators || "optional" in defDecorators) {
2211
- if ("required" in defDecorators && "optional" in defDecorators) {
2212
- throw new SchemaError("@required and @optional cannot both be set");
2213
- }
2214
- const requiredDecoratorVal = defDecorators.required?.value || defDecorators.optional?.value;
2215
- const usingOptional = "optional" in defDecorators;
2216
- if (requiredDecoratorVal instanceof ParsedEnvSpecStaticValue) {
2217
- const staticVal = requiredDecoratorVal.value;
2218
- if (my_dash_default.isBoolean(staticVal)) {
2219
- this._isRequired = usingOptional ? !staticVal : staticVal;
2220
- } else {
2221
- throw new SchemaError("@required/@optional can only be set to true/false if using a static value");
2222
- }
2223
- } else if (requiredDecoratorVal instanceof ParsedEnvSpecFunctionCall) {
2224
- this._isRequiredDynamic = true;
2225
- const requiredFnName = requiredDecoratorVal.name;
2226
- const requiredFnArgs = requiredDecoratorVal.simplifiedArgs;
2227
- if (requiredFnName === "forEnv") {
2228
- const currentEnv = def.source.envFlagValue;
2229
- if (!currentEnv) {
2230
- throw new SchemaError("Cannot set @required using forEnv() because environment flag is not set");
2231
- }
2232
- const envMatches = requiredFnArgs.includes(currentEnv);
2233
- this._isRequired = usingOptional ? !envMatches : envMatches;
2234
- }
2887
+ const requiredDecs = def.itemDef.decorators?.filter((d) => d.name === "required" || d.name === "optional") || [];
2888
+ const requiredDec = requiredDecs[0];
2889
+ if (requiredDec) {
2890
+ const usingOptional = requiredDec.name === "optional";
2891
+ this._isRequiredDynamic = requiredDec.decValueResolver ? requiredDec.decValueResolver.staticValue === void 0 : false;
2892
+ const requiredDecoratorVal = await requiredDec.resolve();
2893
+ if (!my_dash_default.isBoolean(requiredDecoratorVal)) {
2894
+ throw new SchemaError("@required/@optional must resolve to a boolean");
2235
2895
  }
2896
+ this._isRequired = usingOptional ? !requiredDecoratorVal : requiredDecoratorVal;
2236
2897
  return;
2237
2898
  }
2238
- const defaultRequiredValue = def.source.getRootDecoratorSimpleValue("defaultRequired");
2239
- if (defaultRequiredValue !== void 0) {
2240
- if (defaultRequiredValue === "infer") {
2241
- if (def.source.type === "schema") {
2242
- const resolver = def.itemDef.resolver;
2243
- if (resolver === void 0) {
2244
- this._isRequired = false;
2245
- } else if (resolver instanceof StaticValueResolver) {
2246
- this._isRequired = resolver.staticValue !== void 0 && resolver.staticValue !== "";
2899
+ const defaultRequiredDec = def.source.getRootDec("defaultRequired");
2900
+ if (defaultRequiredDec) {
2901
+ const defaultRequiredVal = await defaultRequiredDec.resolve();
2902
+ if (my_dash_default.isBoolean(defaultRequiredVal)) {
2903
+ this._isRequired = defaultRequiredVal;
2904
+ return;
2905
+ } else if (defaultRequiredVal === "infer") {
2906
+ if (def.itemDef.resolver) {
2907
+ if (def.itemDef.resolver instanceof StaticValueResolver) {
2908
+ this._isRequired = def.itemDef.resolver.staticValue !== void 0 && def.itemDef.resolver.staticValue !== "";
2247
2909
  } else {
2248
2910
  this._isRequired = true;
2249
2911
  }
2250
- return;
2251
2912
  } else {
2252
- continue;
2913
+ this._isRequired = false;
2253
2914
  }
2915
+ return;
2916
+ } else {
2917
+ throw new SchemaError('@defaultRequired must resolve to a boolean or "infer"');
2254
2918
  }
2255
- this._isRequired = defaultRequiredValue;
2256
- return;
2257
2919
  }
2258
2920
  }
2259
2921
  } catch (err) {
2260
- this.schemaErrors.push(err instanceof SchemaError ? err : new SchemaError(err));
2922
+ this._schemaErrors.push(err instanceof SchemaError ? err : new SchemaError(err));
2261
2923
  }
2262
2924
  }
2263
2925
  get isRequired() {
@@ -2266,31 +2928,51 @@ var ConfigItem4 = class {
2266
2928
  get isRequiredDynamic() {
2267
2929
  return this._isRequiredDynamic;
2268
2930
  }
2931
+ _isSensitive = true;
2269
2932
  get isSensitive() {
2933
+ return this._isSensitive;
2934
+ }
2935
+ async processSensitive() {
2936
+ const sensitiveFromDataType = this.dataType?.isSensitive;
2270
2937
  for (const def of this.defs) {
2271
- const defDecorators = def.itemDef.decorators || {};
2272
- if ("sensitive" in defDecorators) {
2273
- return defDecorators.sensitive.simplifiedValue;
2938
+ const sensitiveDec = def.itemDef.decorators?.find((d) => d.name === "sensitive");
2939
+ if (sensitiveDec) {
2940
+ const sensitiveDecValue = await sensitiveDec.resolve();
2941
+ if (sensitiveDecValue !== void 0) {
2942
+ this._isSensitive = sensitiveDecValue;
2943
+ return;
2944
+ }
2274
2945
  }
2275
- const defaultSensitiveDec = def.source.getRootDecorators("defaultSensitive")[0];
2946
+ if (sensitiveFromDataType !== void 0) continue;
2947
+ const defaultSensitiveDec = def.source.getRootDec("defaultSensitive");
2276
2948
  if (defaultSensitiveDec) {
2277
- if (defaultSensitiveDec.value instanceof ParsedEnvSpecFunctionCall && defaultSensitiveDec.value.name === "inferFromPrefix") {
2278
- const args = defaultSensitiveDec.value.simplifiedArgs;
2279
- const prefix = Array.isArray(args) && args.length > 0 ? args[0] : void 0;
2280
- if (typeof prefix === "string" && this.key.startsWith(prefix)) {
2281
- return false;
2949
+ if (!defaultSensitiveDec.decValueResolver) throw new Error("expected defaultSensitive to have a value resolver");
2950
+ if (defaultSensitiveDec.decValueResolver.fnName === "inferFromPrefix") {
2951
+ const prefix = defaultSensitiveDec.decValueResolver.arrArgs[0].staticValue;
2952
+ if (!my_dash_default.isString(prefix)) {
2953
+ this._schemaErrors.push(new SchemaError("@defaultSensitive inferFromPrefix() requires a single string argument"));
2954
+ return;
2955
+ }
2956
+ this._isSensitive = !this.key.startsWith(prefix);
2957
+ return;
2958
+ } else {
2959
+ const defaultSensitiveVal = await defaultSensitiveDec.resolve();
2960
+ if (!my_dash_default.isBoolean(defaultSensitiveVal)) {
2961
+ this._schemaErrors.push(new SchemaError("@defaultSensitive must resolve to a boolean value"));
2962
+ } else {
2963
+ this._isSensitive = defaultSensitiveVal;
2964
+ return;
2282
2965
  }
2283
- return true;
2284
2966
  }
2285
- return defaultSensitiveDec.simplifiedValue;
2286
2967
  }
2287
2968
  }
2288
- return true;
2969
+ if (sensitiveFromDataType !== void 0) this._isSensitive = sensitiveFromDataType;
2289
2970
  }
2290
2971
  get errors() {
2291
2972
  return my_dash_default.compact([
2292
- ...this.schemaErrors || [],
2973
+ ...this._schemaErrors || [],
2293
2974
  ...this.resolverSchemaErrors || [],
2975
+ ...this.decoratorSchemaErrors || [],
2294
2976
  this.resolutionError,
2295
2977
  this.coercionError,
2296
2978
  ...this.validationErrors || []
@@ -2314,7 +2996,7 @@ var ConfigItem4 = class {
2314
2996
  return this.resolvedRawValue !== this.resolvedValue;
2315
2997
  }
2316
2998
  async resolve(reset2 = false) {
2317
- if (this.schemaErrors.length) return;
2999
+ if (this._schemaErrors.length) return;
2318
3000
  if (this.resolverSchemaErrors.length) return;
2319
3001
  if (reset2) {
2320
3002
  this.isResolved = false;
@@ -2328,6 +3010,9 @@ var ConfigItem4 = class {
2328
3010
  if (this.isResolved) {
2329
3011
  return;
2330
3012
  }
3013
+ await this.resolveDecorators();
3014
+ await this.processRequired();
3015
+ await this.processSensitive();
2331
3016
  if (!this.valueResolver) {
2332
3017
  this.isResolved = true;
2333
3018
  this.resolvedRawValue = void 0;
@@ -2335,8 +3020,12 @@ var ConfigItem4 = class {
2335
3020
  try {
2336
3021
  this.resolvedRawValue = await this.valueResolver.resolve();
2337
3022
  } catch (err) {
2338
- this.resolutionError = new ResolutionError(`error resolving value: ${err}`);
2339
- this.resolutionError.cause = err;
3023
+ if (err instanceof ResolutionError) {
3024
+ this.resolutionError = err;
3025
+ } else {
3026
+ this.resolutionError = new ResolutionError(`error resolving value: ${err}`);
3027
+ this.resolutionError.cause = err;
3028
+ }
2340
3029
  }
2341
3030
  }
2342
3031
  if (this.resolvedRawValue instanceof RegExp) {
@@ -2369,7 +3058,7 @@ var ConfigItem4 = class {
2369
3058
  return;
2370
3059
  }
2371
3060
  try {
2372
- const validateResult = this.dataType.validate(this.resolvedValue);
3061
+ const validateResult = await this.dataType.validate(this.resolvedValue);
2373
3062
  if (validateResult instanceof Error || my_dash_default.isArray(validateResult) && validateResult[0] instanceof Error) throw validateResult;
2374
3063
  if (validateResult === false) {
2375
3064
  throw new ValidationError("validation failed with `false` return value");
@@ -2396,6 +3085,342 @@ var ConfigItem4 = class {
2396
3085
  return this.validationState === "valid";
2397
3086
  }
2398
3087
  };
3088
+ var importedPluginModulePaths = /* @__PURE__ */ new Set();
3089
+ var VarlockPlugin = class {
3090
+ static {
3091
+ __name(this, "VarlockPlugin");
3092
+ }
3093
+ // helper so end user code can get same error classes
3094
+ ERRORS = {
3095
+ ValidationError,
3096
+ CoercionError,
3097
+ SchemaError,
3098
+ ResolutionError
3099
+ };
3100
+ _packageJson;
3101
+ _name;
3102
+ get name() {
3103
+ return this._packageJson?.name || this._name || "unnamed plugin";
3104
+ }
3105
+ set name(val) {
3106
+ this._name = val;
3107
+ }
3108
+ _version;
3109
+ get version() {
3110
+ return this._packageJson?.version || this._version || "0.0.0";
3111
+ }
3112
+ set version(val) {
3113
+ this._version = val;
3114
+ }
3115
+ _icon;
3116
+ get icon() {
3117
+ return this._icon || "mdi:puzzle";
3118
+ }
3119
+ set icon(val) {
3120
+ this._icon = val;
3121
+ }
3122
+ loadingError;
3123
+ localPath;
3124
+ /** reference to the `@plugin()` decorator instance(s) that installed the plugin */
3125
+ installDecoratorInstances = [];
3126
+ type;
3127
+ constructor(opts) {
3128
+ this.type = opts.type;
3129
+ this.localPath = opts?.localPath;
3130
+ this._packageJson = opts?.packageJson;
3131
+ }
3132
+ // awkwardly using get here to make sure we bind the debug function to this
3133
+ // which lets us destructure it in plugin code
3134
+ debugger;
3135
+ get debug() {
3136
+ return (...args) => {
3137
+ if (!this.debugger) {
3138
+ if (!this.name) throw new Error("expected plugin name to be set before using debug");
3139
+ this.debugger = Debug(`varlock:plugin:${this.name}`);
3140
+ }
3141
+ return this.debugger(...args);
3142
+ };
3143
+ }
3144
+ dataTypes = [];
3145
+ registerDataType(dataTypeDef) {
3146
+ this.debug("registerDataType", dataTypeDef.name);
3147
+ this.dataTypes.push(dataTypeDef);
3148
+ }
3149
+ rootDecorators = [];
3150
+ registerRootDecorator(decoratorDef) {
3151
+ this.debug("registerRootDecorator", decoratorDef.name);
3152
+ this.rootDecorators.push(decoratorDef);
3153
+ }
3154
+ itemDecorators = [];
3155
+ registerItemDecorator(decoratorDef) {
3156
+ this.debug("registerItemDecorator", decoratorDef.name);
3157
+ this.itemDecorators.push(decoratorDef);
3158
+ }
3159
+ resolverFunctions = [];
3160
+ registerResolverFunction(resolverDef) {
3161
+ this.debug("registerResolverFunction", resolverDef.name);
3162
+ this.resolverFunctions.push(resolverDef);
3163
+ }
3164
+ get pluginFilePath() {
3165
+ if (this.type === "single-file") return this.localPath;
3166
+ const pluginExport = this._packageJson?.exports?.["./plugin"] || "";
3167
+ if (!pluginExport) throw new Error("Plugin package.json is missing ./plugin export");
3168
+ return path2.join(this.localPath, pluginExport);
3169
+ }
3170
+ async executePluginModule() {
3171
+ globalThis.plugin = this;
3172
+ try {
3173
+ if (!await pathExists(this.pluginFilePath)) throw new Error(`Plugin file not found: ${this.pluginFilePath}`);
3174
+ importedPluginModulePaths.add(this.pluginFilePath);
3175
+ await import(this.pluginFilePath);
3176
+ } catch (err) {
3177
+ this.loadingError = err;
3178
+ }
3179
+ delete globalThis.plugin;
3180
+ }
3181
+ };
3182
+ async function initPluginFromLocalPath(localPath) {
3183
+ const stats = await fs2.stat(localPath);
3184
+ if (stats.isFile()) {
3185
+ const ext = path2.extname(localPath).toLowerCase();
3186
+ if ([".js", ".cjs", ".mjs"].includes(ext) === false) {
3187
+ throw new SchemaError(`Single-file plugin must be a .js, .cjs, or .mjs file: ${localPath}`);
3188
+ }
3189
+ return new VarlockPlugin({
3190
+ type: "single-file",
3191
+ localPath
3192
+ });
3193
+ } else if (stats.isDirectory()) {
3194
+ const pkgJsonPath = path2.join(localPath, "package.json");
3195
+ if (!await pathExists(pkgJsonPath)) {
3196
+ throw new SchemaError("Plugin is missing package.json file");
3197
+ }
3198
+ const packageJsonContents = JSON.parse(await fs2.readFile(pkgJsonPath, "utf-8"));
3199
+ if (!packageJsonContents.exports?.["./plugin"]) {
3200
+ throw new SchemaError('Plugin is missing "./plugin" export in package.json');
3201
+ }
3202
+ return new VarlockPlugin({
3203
+ type: "package",
3204
+ localPath,
3205
+ packageJson: packageJsonContents
3206
+ });
3207
+ } else {
3208
+ throw new Error(`Invalid plugin path (not a file or directory): ${localPath}`);
3209
+ }
3210
+ }
3211
+ __name(initPluginFromLocalPath, "initPluginFromLocalPath");
3212
+ async function registerPluginInGraph(graph, plugin, pluginDecorator) {
3213
+ let existingPlugin;
3214
+ for (const possibleMatchingPlugin of graph.plugins) {
3215
+ if (plugin.type === "single-file") {
3216
+ if (possibleMatchingPlugin.type === "single-file" && possibleMatchingPlugin.localPath === plugin.localPath) {
3217
+ existingPlugin = possibleMatchingPlugin;
3218
+ }
3219
+ } else if (plugin.type === "package") {
3220
+ if (possibleMatchingPlugin.name === plugin.name) {
3221
+ if (possibleMatchingPlugin.version === plugin.version) {
3222
+ const installedInSources = possibleMatchingPlugin.installDecoratorInstances.map((dec) => dec.dataSource);
3223
+ if (installedInSources.includes(pluginDecorator.dataSource)) {
3224
+ pluginDecorator._schemaErrors.push(new SchemaError(`Plugin ${plugin.name} already installed in this data source`));
3225
+ return;
3226
+ }
3227
+ existingPlugin = possibleMatchingPlugin;
3228
+ } else {
3229
+ pluginDecorator._schemaErrors.push(new SchemaError(`Plugin ${plugin.name} version conflict: tried to install version ${plugin.version} but version ${possibleMatchingPlugin.version} is already installed`));
3230
+ return;
3231
+ }
3232
+ }
3233
+ }
3234
+ }
3235
+ if (existingPlugin) {
3236
+ existingPlugin.installDecoratorInstances.push(pluginDecorator);
3237
+ return;
3238
+ }
3239
+ plugin.installDecoratorInstances.push(pluginDecorator);
3240
+ graph.plugins.push(plugin);
3241
+ await plugin.executePluginModule();
3242
+ for (const rootDec of plugin.rootDecorators || []) {
3243
+ graph.registerRootDecorator(rootDec);
3244
+ }
3245
+ for (const itemDec of plugin.itemDecorators || []) {
3246
+ graph.registerItemDecorator(itemDec);
3247
+ }
3248
+ for (const dataType of plugin.dataTypes || []) {
3249
+ graph.registerDataType(createEnvGraphDataType(dataType));
3250
+ }
3251
+ for (const resolverDef of plugin.resolverFunctions || []) {
3252
+ graph.registerResolver(createResolver(resolverDef));
3253
+ }
3254
+ }
3255
+ __name(registerPluginInGraph, "registerPluginInGraph");
3256
+ async function downloadPlugin(url) {
3257
+ const exec3 = promisify(exec);
3258
+ const cacheDir = path2.join(os.homedir(), ".varlock", "plugins-cache");
3259
+ const indexPath = path2.join(cacheDir, "index.json");
3260
+ await fs2.mkdir(cacheDir, { recursive: true });
3261
+ let index = {};
3262
+ try {
3263
+ const indexRaw = await fs2.readFile(indexPath, "utf-8");
3264
+ index = JSON.parse(indexRaw);
3265
+ } catch {
3266
+ }
3267
+ if (index[url]) {
3268
+ const pluginDir = path2.join(cacheDir, index[url]);
3269
+ if (await fs2.stat(pluginDir).then(() => true, () => false)) {
3270
+ return pluginDir;
3271
+ }
3272
+ }
3273
+ const tmpTgz = path2.join(cacheDir, `tmp-${crypto.randomBytes(8).toString("hex")}.tgz`);
3274
+ await new Promise((resolve, reject) => {
3275
+ const file = fs.createWriteStream(tmpTgz);
3276
+ https.get(url, (res) => {
3277
+ if (res.statusCode !== 200) {
3278
+ reject(new Error(`Failed to download plugin: ${res.statusCode}`));
3279
+ return;
3280
+ }
3281
+ res.pipe(file);
3282
+ file.on("finish", () => file.close(() => resolve()));
3283
+ file.on("error", reject);
3284
+ }).on("error", reject);
3285
+ });
3286
+ const tmpExtractDir = path2.join(cacheDir, `tmp-extract-${crypto.randomBytes(8).toString("hex")}`);
3287
+ await fs2.mkdir(tmpExtractDir);
3288
+ await exec3(`tar -xzf ${tmpTgz} -C ${tmpExtractDir}`);
3289
+ let pkgJsonPath = path2.join(tmpExtractDir, "package", "package.json");
3290
+ let pluginRoot = path2.join(tmpExtractDir, "package");
3291
+ if (!await fs2.stat(pkgJsonPath).then(() => true, () => false)) {
3292
+ pkgJsonPath = path2.join(tmpExtractDir, "package.json");
3293
+ pluginRoot = tmpExtractDir;
3294
+ if (!await fs2.stat(pkgJsonPath).then(() => true, () => false)) {
3295
+ throw new Error("package.json not found in plugin tgz");
3296
+ }
3297
+ }
3298
+ const pkgJson = JSON.parse(await fs2.readFile(pkgJsonPath, "utf-8"));
3299
+ const safePackageName = (pkgJson.name || "").replaceAll("/", "-").replaceAll("@", "");
3300
+ const dirName = `${safePackageName}_${pkgJson.version || ""}_${crypto.randomBytes(4).toString("hex")}`;
3301
+ const finalDir = path2.join(cacheDir, dirName);
3302
+ await fs2.rm(finalDir, { recursive: true, force: true });
3303
+ await fs2.rename(pluginRoot, finalDir);
3304
+ await fs2.rm(tmpTgz, { force: true });
3305
+ await fs2.rm(tmpExtractDir, { recursive: true, force: true });
3306
+ index[url] = dirName;
3307
+ await fs2.writeFile(indexPath, JSON.stringify(index, null, 2));
3308
+ return finalDir;
3309
+ }
3310
+ __name(downloadPlugin, "downloadPlugin");
3311
+ async function processPluginInstallDecorators(dataSource) {
3312
+ const graph = dataSource.graph;
3313
+ if (!graph) throw new Error("Data source not attached to graph");
3314
+ const installPluginDecorators = dataSource.getRootDecFns("plugin");
3315
+ if (installPluginDecorators.length) {
3316
+ if (!(dataSource instanceof FileBasedDataSource)) {
3317
+ dataSource._loadingError = new Error("@plugin can only be used from a file-based data source");
3318
+ return;
3319
+ }
3320
+ const dataSourceDir = path2.dirname(dataSource.fullPath);
3321
+ for (const pluginDecorator of installPluginDecorators) {
3322
+ let pluginSrcPath;
3323
+ try {
3324
+ const installPluginArgs = await pluginDecorator.resolve();
3325
+ const pluginSourceDescriptor = installPluginArgs.arr[0];
3326
+ if (!my_dash_default.isString(pluginSourceDescriptor)) {
3327
+ throw new SchemaError("Bad @plugin - must provide a string source location");
3328
+ }
3329
+ if (pluginSourceDescriptor.startsWith("./") || pluginSourceDescriptor.startsWith("../") || pluginSourceDescriptor.startsWith("/")) {
3330
+ pluginSrcPath = pluginSourceDescriptor.startsWith("/") ? pluginSourceDescriptor : path2.resolve(dataSourceDir, pluginSourceDescriptor);
3331
+ if (!await pathExists(pluginSrcPath)) {
3332
+ throw new SchemaError(`Bad @plugin path: ${pluginSourceDescriptor}`);
3333
+ }
3334
+ } else if (pluginSourceDescriptor.includes(":")) {
3335
+ const protocol = pluginSourceDescriptor.split(":")[0];
3336
+ if (["https", "npm", "jsr", "git"].includes(protocol)) {
3337
+ throw new SchemaError(`@plugin source protocol "${protocol}" is not yet supported`);
3338
+ } else {
3339
+ throw new SchemaError(`Bad @plugin source protocol: ${protocol}`);
3340
+ }
3341
+ } else {
3342
+ const atLocation = pluginSourceDescriptor.indexOf("@", 1);
3343
+ let versionDescriptor;
3344
+ let moduleName;
3345
+ if (atLocation === -1) {
3346
+ moduleName = pluginSourceDescriptor;
3347
+ } else {
3348
+ moduleName = pluginSourceDescriptor.slice(0, atLocation);
3349
+ versionDescriptor = pluginSourceDescriptor.slice(atLocation + 1);
3350
+ }
3351
+ if (!moduleName.startsWith("@varlock/")) {
3352
+ throw new SchemaError(`Plugin "${moduleName}" blocked - only official @varlock/* plugins are supported for now, third-party plugins will be supported in future releases`);
3353
+ }
3354
+ const semverRange = semver.validRange(versionDescriptor);
3355
+ if (versionDescriptor && !semverRange) {
3356
+ throw new SchemaError(`Bad @plugin version descriptor: ${versionDescriptor}`);
3357
+ } else if (semverRange === "*") {
3358
+ throw new SchemaError(`Version descriptor "${versionDescriptor}" is too broad`);
3359
+ } else if (versionDescriptor === "") {
3360
+ throw new SchemaError('Bad @plugin version descriptor - remove "@" or specify a valid version');
3361
+ }
3362
+ let currentDir = dataSourceDir;
3363
+ let nodeModulesPath;
3364
+ while (currentDir) {
3365
+ if (await pathExists(path2.join(currentDir, "package.json"))) {
3366
+ nodeModulesPath = path2.join(currentDir, "node_modules");
3367
+ break;
3368
+ }
3369
+ const parentDir = path2.dirname(currentDir);
3370
+ if (parentDir === currentDir) break;
3371
+ currentDir = parentDir;
3372
+ }
3373
+ if (nodeModulesPath) {
3374
+ const pluginPackagePath = path2.join(nodeModulesPath, moduleName);
3375
+ if (await pathExists(pluginPackagePath)) {
3376
+ const pluginPackageJsonPath = path2.join(pluginPackagePath, "package.json");
3377
+ const packageJsonString = await fs2.readFile(pluginPackageJsonPath, "utf-8");
3378
+ const packageJson = JSON.parse(packageJsonString);
3379
+ const packageVersion = packageJson.version;
3380
+ if (versionDescriptor && !semver.satisfies(packageVersion, versionDescriptor)) {
3381
+ throw new SchemaError(`Installed plugin "${moduleName}" version "${packageVersion}" does not satisfy requested version "${versionDescriptor}"`, {
3382
+ location: getErrorLocation(dataSource, pluginDecorator)
3383
+ });
3384
+ }
3385
+ pluginSrcPath = pluginPackagePath;
3386
+ }
3387
+ }
3388
+ if (!pluginSrcPath) {
3389
+ if (!versionDescriptor) {
3390
+ if (nodeModulesPath) {
3391
+ throw new SchemaError(`Plugin "${moduleName}" unable to resolve - install locally via your package.json file`);
3392
+ } else {
3393
+ throw new SchemaError(`Plugin "${moduleName}" unable to resolve - set a fixed version (e.g., \`@plugin(${moduleName}@1.2.3)\`)`);
3394
+ }
3395
+ } else if (!semver.valid(versionDescriptor)) {
3396
+ throw new SchemaError(`Plugin "${moduleName}" must use a fixed version when not installing via package.json (e.g., \`@plugin(${moduleName}@1.2.3)\`)`, {
3397
+ location: getErrorLocation(dataSource, pluginDecorator)
3398
+ });
3399
+ }
3400
+ const npmInfoUrl = `https://registry.npmjs.org/${moduleName}/${versionDescriptor}`;
3401
+ const npmInfoReq = await fetch(npmInfoUrl);
3402
+ if (!npmInfoReq.ok) {
3403
+ throw new Error(`Failed to fetch plugin "${moduleName}@${versionDescriptor}" from npm: ${npmInfoReq.status} ${npmInfoReq.statusText}`);
3404
+ }
3405
+ const npmInfo = await npmInfoReq.json();
3406
+ const tarballUrl = npmInfo?.dist?.tarball;
3407
+ if (!tarballUrl) {
3408
+ throw new Error(`Failed to find tarball URL for plugin "${moduleName}@${versionDescriptor}" from npm`);
3409
+ }
3410
+ const downloadedPluginPath = await downloadPlugin(tarballUrl);
3411
+ pluginSrcPath = downloadedPluginPath;
3412
+ }
3413
+ }
3414
+ const plugin = await initPluginFromLocalPath(pluginSrcPath);
3415
+ await registerPluginInGraph(graph, plugin, pluginDecorator);
3416
+ } catch (err) {
3417
+ pluginDecorator._schemaErrors.push(err);
3418
+ continue;
3419
+ }
3420
+ }
3421
+ }
3422
+ }
3423
+ __name(processPluginInstallDecorators, "processPluginInstallDecorators");
2399
3424
 
2400
3425
  // env-graph/lib/data-source.ts
2401
3426
  var DATA_SOURCE_TYPES = Object.freeze({
@@ -2416,7 +3441,7 @@ var DATA_SOURCE_TYPES = Object.freeze({
2416
3441
  },
2417
3442
  container: {}
2418
3443
  });
2419
- var EnvGraphDataSource3 = class {
3444
+ var EnvGraphDataSource4 = class {
2420
3445
  static {
2421
3446
  __name(this, "EnvGraphDataSource");
2422
3447
  }
@@ -2488,6 +3513,7 @@ var EnvGraphDataSource3 = class {
2488
3513
  async resolveCurrentEnv() {
2489
3514
  const envFlagItem = this.envFlagConfigItem;
2490
3515
  if (envFlagItem) {
3516
+ if (envFlagItem.resolvedValue) return envFlagItem.resolvedValue;
2491
3517
  await envFlagItem.earlyResolve();
2492
3518
  return envFlagItem.resolvedValue;
2493
3519
  }
@@ -2500,52 +3526,67 @@ var EnvGraphDataSource3 = class {
2500
3526
  if (this.loadingError) {
2501
3527
  return;
2502
3528
  }
2503
- const disableDecorator = this.getRootDecorators("disable")?.[0];
2504
- if (disableDecorator) {
2505
- if (disableDecorator.value instanceof ParsedEnvSpecFunctionCall) {
2506
- if (disableDecorator.value.name === "forEnv") {
2507
- const disableForEnvs = disableDecorator.value.simplifiedArgs;
2508
- if (!my_dash_default.isArray(disableForEnvs)) {
2509
- this._loadingError = new Error("expected disable decorator args to be array");
2510
- return;
2511
- }
2512
- const currentEnv = await this.resolveCurrentEnv();
2513
- if (disableForEnvs.includes(currentEnv)) {
2514
- this._disabled = true;
2515
- }
2516
- } else {
2517
- this._loadingError = new Error(`unknown disable decorator function: ${disableDecorator.name}`);
2518
- return;
2519
- }
2520
- } else if (disableDecorator.simplifiedValue) {
2521
- this._disabled = true;
2522
- }
2523
- }
2524
- if (this.disabled) return;
2525
- const envFlagDecoratorValue = this.getRootDecoratorSimpleValue("envFlag");
2526
- if (envFlagDecoratorValue) {
2527
- if (!this.configItemDefs[envFlagDecoratorValue]) {
2528
- this._loadingError = new Error(`@envFlag key ${envFlagDecoratorValue} must be an item within this schema`);
3529
+ const disabledDec = this.getRootDec("disable");
3530
+ if (disabledDec) {
3531
+ const disabledVal = await disabledDec.resolve();
3532
+ if (!my_dash_default.isBoolean(disabledVal)) {
3533
+ this._loadingError = new Error("expected @disable to be boolean value");
2529
3534
  return;
2530
3535
  }
2531
- this.setEnvFlag(envFlagDecoratorValue);
3536
+ this._disabled = disabledVal;
2532
3537
  }
3538
+ if (this.disabled) return;
2533
3539
  for (const itemKey of this.importKeys || my_dash_default.keys(this.configItemDefs)) {
2534
3540
  const itemDef = this.configItemDefs[itemKey];
2535
3541
  if (!itemDef) continue;
2536
- this.graph.configSchema[itemKey] ??= new ConfigItem4(this.graph, itemKey);
2537
- }
2538
- const importDecorators = this.getRootDecorators("import");
2539
- if (importDecorators.length) {
2540
- for (const importDecorator of importDecorators) {
2541
- const importArgs = importDecorator.bareFnArgs?.simplifiedValues;
2542
- if (!my_dash_default.isArray(importArgs)) {
2543
- throw new Error("expected @import args to be array");
2544
- }
2545
- const importPath = importArgs[0];
2546
- if (!importPath) throw new Error("@import decorator must have a value");
2547
- if (!my_dash_default.isString(importPath)) throw new Error("expected @import path to be string");
2548
- const importKeys = importArgs.slice(1);
3542
+ this.graph.configSchema[itemKey] ??= new ConfigItem(this.graph, itemKey);
3543
+ }
3544
+ const currentEnvDec = this.getRootDec("currentEnv");
3545
+ const envFlagDec = this.getRootDec("envFlag");
3546
+ if (currentEnvDec && envFlagDec) {
3547
+ this._loadingError = new Error("Cannot use both @currentEnv and @envFlag decorators");
3548
+ }
3549
+ let envFlagItemKey;
3550
+ if (currentEnvDec) {
3551
+ await currentEnvDec.process();
3552
+ if (!currentEnvDec.decValueResolver) {
3553
+ throw new Error("No resolver found for @currentEnv decorator");
3554
+ }
3555
+ if (currentEnvDec.decValueResolver.fnName !== "ref") {
3556
+ throw new Error("Expected @currentEnv decorator to be set to direct reference - ie `$APP_ENV`");
3557
+ }
3558
+ const refArgValue = currentEnvDec.decValueResolver.arrArgs?.[0]?.staticValue;
3559
+ if (!refArgValue || !my_dash_default.isString(refArgValue)) {
3560
+ throw new Error("@currentEnv ref must be set to a string");
3561
+ }
3562
+ envFlagItemKey = refArgValue;
3563
+ } else if (envFlagDec) {
3564
+ await envFlagDec.process();
3565
+ if (!envFlagDec.decValueResolver) throw new Error("@envFlag resolver not set");
3566
+ if (!envFlagDec.decValueResolver.staticValue) {
3567
+ throw new Error("Expected @envFlag decorator to be static value");
3568
+ }
3569
+ envFlagItemKey = String(envFlagDec.decValueResolver.staticValue);
3570
+ }
3571
+ if (envFlagItemKey) {
3572
+ if (!this.configItemDefs[envFlagItemKey]) {
3573
+ this._loadingError = new Error(`environment flag "${envFlagItemKey}" must be defined within this schema`);
3574
+ return;
3575
+ }
3576
+ this.setEnvFlag(envFlagItemKey);
3577
+ }
3578
+ const defaultSensitiveDec = this.getRootDec("defaultSensitive");
3579
+ await defaultSensitiveDec?.process();
3580
+ const defaultRequiredDec = this.getRootDec("defaultRequired");
3581
+ await defaultRequiredDec?.process();
3582
+ await processPluginInstallDecorators(this);
3583
+ if (!this.isValid) return;
3584
+ const importDecs = this.getRootDecFns("import");
3585
+ if (importDecs.length) {
3586
+ for (const importDec of importDecs) {
3587
+ const importArgs = await importDec.resolve();
3588
+ const importPath = importArgs.arr[0];
3589
+ const importKeys = importArgs.arr.slice(1);
2549
3590
  if (!importKeys.every(my_dash_default.isString)) {
2550
3591
  throw new Error("expected @import keys to all be strings");
2551
3592
  }
@@ -2576,7 +3617,7 @@ var EnvGraphDataSource3 = class {
2576
3617
  await this.addChild(source, { isImport: true, importKeys });
2577
3618
  }
2578
3619
  } else {
2579
- const fsStat = await tryCatch(async () => fs2.stat(importPath), (_err) => {
3620
+ const fsStat = await tryCatch(async () => fs2.stat(fullImportPath), (_err) => {
2580
3621
  });
2581
3622
  if (!fsStat) {
2582
3623
  this._loadingError = new Error(`Import path does not exist: ${fullImportPath}`);
@@ -2634,8 +3675,18 @@ var EnvGraphDataSource3 = class {
2634
3675
  get loadingError() {
2635
3676
  return this._loadingError;
2636
3677
  }
3678
+ _schemaErrors = [];
3679
+ get schemaErrors() {
3680
+ return my_dash_default.compact([
3681
+ ...this._schemaErrors,
3682
+ ...this.rootDecorators.flatMap((d) => d.schemaErrors)
3683
+ ]);
3684
+ }
3685
+ get resolutionErrors() {
3686
+ return my_dash_default.compact([...this.rootDecorators.flatMap((d) => d._executionError)]);
3687
+ }
2637
3688
  get isValid() {
2638
- return !this.loadingError;
3689
+ return !this.loadingError && !this.schemaErrors.length && !this.resolutionErrors.length;
2639
3690
  }
2640
3691
  configItemDefs = {};
2641
3692
  decorators = [];
@@ -2648,18 +3699,15 @@ var EnvGraphDataSource3 = class {
2648
3699
  if (decorators.length > 1) throw new Error(`Multiple ${decName} decorators found`);
2649
3700
  return decorators[0].simplifiedValue;
2650
3701
  }
2651
- };
2652
- var EnvSourceParseError = class extends Error {
2653
- static {
2654
- __name(this, "EnvSourceParseError");
3702
+ rootDecorators = [];
3703
+ getRootDec(decName) {
3704
+ return this.rootDecorators.find((d) => d.name === decName && !d.isFunctionCall);
2655
3705
  }
2656
- location;
2657
- constructor(message, _location) {
2658
- super(message);
2659
- this.location = _location;
3706
+ getRootDecFns(decName) {
3707
+ return this.rootDecorators.filter((d) => d.name === decName && d.isFunctionCall);
2660
3708
  }
2661
3709
  };
2662
- var FileBasedDataSource = class extends EnvGraphDataSource3 {
3710
+ var FileBasedDataSource = class extends EnvGraphDataSource4 {
2663
3711
  static {
2664
3712
  __name(this, "FileBasedDataSource");
2665
3713
  }
@@ -2670,8 +3718,9 @@ var FileBasedDataSource = class extends EnvGraphDataSource3 {
2670
3718
  get typeLabel() {
2671
3719
  return this.constructor.format;
2672
3720
  }
3721
+ relativePath;
2673
3722
  get label() {
2674
- return this.fileName;
3723
+ return this.relativePath;
2675
3724
  }
2676
3725
  static format = "unknown";
2677
3726
  // no abstract static
@@ -2683,6 +3732,7 @@ var FileBasedDataSource = class extends EnvGraphDataSource3 {
2683
3732
  super();
2684
3733
  this.fullPath = fullPath;
2685
3734
  this.fileName = path2.basename(fullPath);
3735
+ this.relativePath = path2.relative(process.cwd(), fullPath);
2686
3736
  if (opts?.overrideContents) {
2687
3737
  this.rawContents = opts.overrideContents;
2688
3738
  this.isGitIgnored = opts.overrideGitIgnored;
@@ -2730,51 +3780,18 @@ var DotEnvFileDataSource = class extends FileBasedDataSource {
2730
3780
  static validFileExtensions = [];
2731
3781
  // no extension for dotenv files!
2732
3782
  parsedFile;
2733
- convertParserValueToResolvers(value) {
2734
- if (!this.graph) throw new Error("expected graph to be set");
2735
- if (value === void 0) {
2736
- return void 0;
2737
- } else if (value instanceof ParsedEnvSpecStaticValue) {
2738
- return new StaticValueResolver(value.unescapedValue);
2739
- } else if (value instanceof ParsedEnvSpecFunctionCall) {
2740
- const ResolverFnClass = this.graph.registeredResolverFunctions[value.name];
2741
- if (!ResolverFnClass) {
2742
- return new ErrorResolver(new SchemaError(`Unknown resolver function: ${value.name}()`));
2743
- }
2744
- const argsFromParser = value.data.args.values;
2745
- let keyValueArgs;
2746
- const argsAsResolversArray = [];
2747
- for (const arg of argsFromParser) {
2748
- if (arg instanceof ParsedEnvSpecKeyValuePair) {
2749
- keyValueArgs ??= {};
2750
- const valResolver = this.convertParserValueToResolvers(arg.value);
2751
- if (!valResolver) throw new Error("Did not expect to find undefined resolver in key-value arg");
2752
- keyValueArgs[arg.key] = valResolver;
2753
- } else {
2754
- if (keyValueArgs) {
2755
- return new ErrorResolver(new SchemaError("After switching to key-value function args, cannot switch back"));
2756
- }
2757
- const argResolver = this.convertParserValueToResolvers(arg);
2758
- if (!argResolver) throw new Error("Did not expect to find undefined resolver in array arg");
2759
- argsAsResolversArray.push(argResolver);
2760
- }
2761
- }
2762
- if (keyValueArgs) argsAsResolversArray.push(keyValueArgs);
2763
- return new ResolverFnClass(argsAsResolversArray);
2764
- } else {
2765
- throw new Error("Unknown value type");
2766
- }
2767
- }
2768
3783
  async _parseContents() {
2769
3784
  const rawContents = this.rawContents;
2770
3785
  this.parsedFile = await tryCatch(
2771
3786
  () => parseEnvSpecDotEnvFile(rawContents),
2772
3787
  (error) => {
2773
- this._loadingError = new EnvSourceParseError(error.message, {
2774
- path: this.fullPath,
2775
- lineNumber: error.location.start.line,
2776
- colNumber: error.location.start.column,
2777
- lineStr: rawContents.split("\n")[error.location.start.line - 1]
3788
+ this._loadingError = new ParseError(`Parse error: ${error.message}`, {
3789
+ location: {
3790
+ id: this.fullPath,
3791
+ lineNumber: error.location.start.line,
3792
+ colNumber: error.location.start.column,
3793
+ lineStr: rawContents.split("\n")[error.location.start.line - 1]
3794
+ }
2778
3795
  });
2779
3796
  this._loadingError.cause = error;
2780
3797
  }
@@ -2782,18 +3799,17 @@ var DotEnvFileDataSource = class extends FileBasedDataSource {
2782
3799
  if (this.loadingError) return;
2783
3800
  if (!this.parsedFile) throw new Error("Failed to parse .env file");
2784
3801
  if (!this.graph) throw new Error("expected graph to be set");
2785
- this.decorators = this.parsedFile.decoratorsArray;
3802
+ this.rootDecorators = this.parsedFile.decoratorsArray.map((d) => new RootDecoratorInstance(this, d));
2786
3803
  for (const item of this.parsedFile.configItems) {
2787
- item.processExpansion();
2788
3804
  this.configItemDefs[item.key] = {
2789
- resolver: this.convertParserValueToResolvers(item.expandedValue),
2790
3805
  description: item.description,
2791
- decorators: item.decoratorsObject
3806
+ parsedValue: item.value,
3807
+ parsedDecorators: item.decoratorsArray
2792
3808
  };
2793
3809
  }
2794
3810
  }
2795
3811
  };
2796
- var DirectoryDataSource = class extends EnvGraphDataSource3 {
3812
+ var DirectoryDataSource = class extends EnvGraphDataSource4 {
2797
3813
  constructor(basePath) {
2798
3814
  super();
2799
3815
  this.basePath = basePath;
@@ -2807,9 +3823,6 @@ var DirectoryDataSource = class extends EnvGraphDataSource3 {
2807
3823
  return `directory - ${this.basePath}`;
2808
3824
  }
2809
3825
  schemaDataSource;
2810
- get loadingError() {
2811
- return this._loadingError || this.schemaDataSource?.loadingError;
2812
- }
2813
3826
  async addAutoLoadedFile(fileName) {
2814
3827
  if (!this.graph) throw new Error("expected graph to be set");
2815
3828
  const filePath = path2.join(this.basePath, fileName);
@@ -2953,100 +3966,8 @@ function getItemSummary(item) {
2953
3966
  return summary.join("\n");
2954
3967
  }
2955
3968
  __name(getItemSummary, "getItemSummary");
2956
- var asyncCallbacks = /* @__PURE__ */ new Set();
2957
- var callbacks = /* @__PURE__ */ new Set();
2958
- var isCalled = false;
2959
- var isRegistered = false;
2960
- async function exit(shouldManuallyExit, isSynchronous, signal) {
2961
- if (isCalled) {
2962
- return;
2963
- }
2964
- isCalled = true;
2965
- if (asyncCallbacks.size > 0 && isSynchronous) {
2966
- console.error([
2967
- "SYNCHRONOUS TERMINATION NOTICE:",
2968
- "When explicitly exiting the process via process.exit or via a parent process,",
2969
- "asynchronous tasks in your exitHooks will not run. Either remove these tasks,",
2970
- "use gracefulExit() instead of process.exit(), or ensure your parent process",
2971
- "sends a SIGINT to the process running this code."
2972
- ].join(" "));
2973
- }
2974
- const exitCode = 128 + signal;
2975
- const done = /* @__PURE__ */ __name((force = false) => {
2976
- if (force === true || shouldManuallyExit === true) {
2977
- process2.exit(exitCode);
2978
- }
2979
- }, "done");
2980
- for (const callback of callbacks) {
2981
- callback(exitCode);
2982
- }
2983
- if (isSynchronous) {
2984
- done();
2985
- return;
2986
- }
2987
- const promises = [];
2988
- let forceAfter = 0;
2989
- for (const [callback, wait] of asyncCallbacks) {
2990
- forceAfter = Math.max(forceAfter, wait);
2991
- promises.push(Promise.resolve(callback(exitCode)));
2992
- }
2993
- const asyncTimer = setTimeout(() => {
2994
- done(true);
2995
- }, forceAfter);
2996
- await Promise.all(promises);
2997
- clearTimeout(asyncTimer);
2998
- done();
2999
- }
3000
- __name(exit, "exit");
3001
- function addHook(options) {
3002
- const { onExit, wait, isSynchronous } = options;
3003
- const asyncCallbackConfig = [onExit, wait];
3004
- if (isSynchronous) {
3005
- callbacks.add(onExit);
3006
- } else {
3007
- asyncCallbacks.add(asyncCallbackConfig);
3008
- }
3009
- if (!isRegistered) {
3010
- isRegistered = true;
3011
- process2.once("beforeExit", exit.bind(void 0, true, false, -128));
3012
- process2.once("SIGINT", exit.bind(void 0, true, false, 2));
3013
- process2.once("SIGTERM", exit.bind(void 0, true, false, 15));
3014
- process2.once("exit", exit.bind(void 0, false, true, 0));
3015
- process2.on("message", (message) => {
3016
- if (message === "shutdown") {
3017
- exit(true, true, -128);
3018
- }
3019
- });
3020
- }
3021
- return () => {
3022
- if (isSynchronous) {
3023
- callbacks.delete(onExit);
3024
- } else {
3025
- asyncCallbacks.delete(asyncCallbackConfig);
3026
- }
3027
- };
3028
- }
3029
- __name(addHook, "addHook");
3030
- function asyncExitHook(onExit, options = {}) {
3031
- if (typeof onExit !== "function") {
3032
- throw new TypeError("onExit must be a function");
3033
- }
3034
- if (!(typeof options.wait === "number" && options.wait > 0)) {
3035
- throw new TypeError("wait must be set to a positive numeric value");
3036
- }
3037
- return addHook({
3038
- onExit,
3039
- wait: options.wait,
3040
- isSynchronous: false
3041
- });
3042
- }
3043
- __name(asyncExitHook, "asyncExitHook");
3044
- function gracefulExit(signal = 0) {
3045
- exit(true, false, -128 + signal);
3046
- }
3047
- __name(gracefulExit, "gracefulExit");
3048
3969
  //! these are probably not relevant anymore, or needs to move to a plugin layer?
3049
3970
 
3050
- export { CoercionError, ConfigLoadError, DotEnvFileDataSource, EnvGraph2 as EnvGraph, EnvSourceParseError, FileBasedDataSource, ResolutionError, SchemaError, ValidationError, ansis_default, asyncExitHook, checkIsFileGitIgnored, getItemSummary, gracefulExit, joinAndCompact, loadEnvGraph, my_dash_default, pathExists, pathExistsSync, tryCatch };
3051
- //# sourceMappingURL=chunk-FCVBOYES.js.map
3052
- //# sourceMappingURL=chunk-FCVBOYES.js.map
3971
+ export { CoercionError, ConfigLoadError, DotEnvFileDataSource, EnvGraph2 as EnvGraph, FileBasedDataSource, ResolutionError, SchemaError, ValidationError, VarlockError, ansis_default, asyncExitHook, checkIsFileGitIgnored, getItemSummary, gracefulExit, joinAndCompact, loadEnvGraph, my_dash_default, pathExists, pathExistsSync, tryCatch };
3972
+ //# sourceMappingURL=chunk-MLIGQWID.js.map
3973
+ //# sourceMappingURL=chunk-MLIGQWID.js.map