varlock 0.1.5 → 0.2.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 (40) hide show
  1. package/dist/{chunk-4LIQGKEE.js → chunk-FPQYEKFF.js} +13 -8
  2. package/dist/chunk-FPQYEKFF.js.map +1 -0
  3. package/dist/{chunk-ARMP7LS5.js → chunk-L5REVVXG.js} +3 -3
  4. package/dist/{chunk-ARMP7LS5.js.map → chunk-L5REVVXG.js.map} +1 -1
  5. package/dist/{chunk-QYL63H5X.js → chunk-L5USEQO6.js} +97 -7
  6. package/dist/chunk-L5USEQO6.js.map +1 -0
  7. package/dist/{chunk-D2V7SDAQ.js → chunk-NDRSG3XS.js} +44 -17
  8. package/dist/chunk-NDRSG3XS.js.map +1 -0
  9. package/dist/{chunk-OOBWRTIS.js → chunk-RD44SH5U.js} +143 -103
  10. package/dist/chunk-RD44SH5U.js.map +1 -0
  11. package/dist/{chunk-N4HZJLL3.js → chunk-RFRTLWK3.js} +16 -5
  12. package/dist/chunk-RFRTLWK3.js.map +1 -0
  13. package/dist/{chunk-N6YMZ3HA.js → chunk-XVVLI2E7.js} +28 -7
  14. package/dist/chunk-XVVLI2E7.js.map +1 -0
  15. package/dist/cli/cli-executable.js +12 -12
  16. package/dist/cli/cli-executable.js.map +1 -1
  17. package/dist/{env-graph-eF0B8G0j.d.ts → env-graph-BZwrHQbb.d.ts} +0 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +2 -2
  20. package/dist/init.command-AVNYY5CK.js +8 -0
  21. package/dist/{init.command-RZ3LEK7W.js.map → init.command-AVNYY5CK.js.map} +1 -1
  22. package/dist/load.command-7CCTFAYS.js +8 -0
  23. package/dist/{load.command-6Z3QLGY2.js.map → load.command-7CCTFAYS.js.map} +1 -1
  24. package/dist/plugin-lib.d.ts +2 -2
  25. package/dist/run.command-NGRKCLWP.js +9 -0
  26. package/dist/{run.command-GUUY5BP4.js.map → run.command-NGRKCLWP.js.map} +1 -1
  27. package/dist/runtime/env.d.ts +1 -1
  28. package/dist/telemetry.command-756WXWYK.js +8 -0
  29. package/dist/{telemetry.command-XKHQ3QFE.js.map → telemetry.command-756WXWYK.js.map} +1 -1
  30. package/package.json +2 -2
  31. package/dist/chunk-4LIQGKEE.js.map +0 -1
  32. package/dist/chunk-D2V7SDAQ.js.map +0 -1
  33. package/dist/chunk-N4HZJLL3.js.map +0 -1
  34. package/dist/chunk-N6YMZ3HA.js.map +0 -1
  35. package/dist/chunk-OOBWRTIS.js.map +0 -1
  36. package/dist/chunk-QYL63H5X.js.map +0 -1
  37. package/dist/init.command-RZ3LEK7W.js +0 -8
  38. package/dist/load.command-6Z3QLGY2.js +0 -8
  39. package/dist/run.command-GUUY5BP4.js +0 -9
  40. package/dist/telemetry.command-XKHQ3QFE.js +0 -8
@@ -1,6 +1,6 @@
1
1
  import { define } from './chunk-33ROL4J5.js';
2
- import { loadVarlockEnvGraph, checkForSchemaErrors, checkForConfigErrors } from './chunk-ARMP7LS5.js';
3
- import { gracefulExit } from './chunk-OOBWRTIS.js';
2
+ import { loadVarlockEnvGraph, checkForSchemaErrors, checkForConfigErrors } from './chunk-L5REVVXG.js';
3
+ import { gracefulExit } from './chunk-RD44SH5U.js';
4
4
  import { resetRedactionMap, redactSensitiveConfig } from './chunk-MSRPV5WH.js';
5
5
  import { __name } from './chunk-XN24GZXQ.js';
6
6
  import { execa } from 'execa';
@@ -15,7 +15,26 @@ var commandSpec = define({
15
15
  // short: 'w',
16
16
  // description: 'Watch mode',
17
17
  // },
18
- }
18
+ "no-redact-stdout": {
19
+ type: "boolean",
20
+ description: "Disable stdout/stderr redaction to preserve TTY detection for interactive tools"
21
+ }
22
+ },
23
+ examples: `
24
+ Executes a command in a child process, injecting your resolved and validated environment
25
+ variables from your .env files. Useful when a code-level integration is not possible.
26
+
27
+ Examples:
28
+ varlock run -- node app.js # Run a Node.js application
29
+ varlock run -- python script.py # Run a Python script
30
+ varlock run -- sh -c 'echo $MY_VAR' # Use shell expansion for env vars
31
+ varlock run --no-redact-stdout -- psql # Preserve TTY for interactive tools
32
+
33
+ \u{1F4CD} Important: Use -- to separate varlock options from your command
34
+
35
+ \u{1F4A1} Tip: For shell expansion of env vars, use: sh -c 'your command here'
36
+ \u{1F4A1} Tip: Use --no-redact-stdout for interactive tools (psql, claude, etc.)
37
+ `.trim()
19
38
  });
20
39
  var commandProcess;
21
40
  var childCommandKilledFromRestart = false;
@@ -47,21 +66,29 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
47
66
  __VARLOCK_ENV: JSON.stringify(serializedGraph)
48
67
  };
49
68
  const redactLogs = serializedGraph.settings?.redactLogs ?? true;
69
+ const noRedactStdout = ctx.values["no-redact-stdout"] ?? false;
50
70
  if (redactLogs) {
51
71
  resetRedactionMap(serializedGraph);
52
72
  }
53
- const writeRedacted = /* @__PURE__ */ __name((stream, chunk) => {
54
- const str = chunk.toString();
55
- stream.write(redactLogs ? redactSensitiveConfig(str) : str);
56
- }, "writeRedacted");
57
- commandProcess = execa(pathAwareCommand || rawCommand, commandArgsOnly, {
58
- stdin: "inherit",
59
- stdout: "pipe",
60
- stderr: "pipe",
61
- env: fullInjectedEnv
62
- });
63
- commandProcess.stdout?.on("data", (chunk) => writeRedacted(process.stdout, chunk));
64
- commandProcess.stderr?.on("data", (chunk) => writeRedacted(process.stderr, chunk));
73
+ if (noRedactStdout) {
74
+ commandProcess = execa(pathAwareCommand || rawCommand, commandArgsOnly, {
75
+ stdio: "inherit",
76
+ env: fullInjectedEnv
77
+ });
78
+ } else {
79
+ const writeRedacted = /* @__PURE__ */ __name((stream, chunk) => {
80
+ const str = chunk.toString();
81
+ stream.write(redactLogs ? redactSensitiveConfig(str) : str);
82
+ }, "writeRedacted");
83
+ commandProcess = execa(pathAwareCommand || rawCommand, commandArgsOnly, {
84
+ stdin: "inherit",
85
+ stdout: "pipe",
86
+ stderr: "pipe",
87
+ env: fullInjectedEnv
88
+ });
89
+ commandProcess.stdout?.on("data", (chunk) => writeRedacted(process.stdout, chunk));
90
+ commandProcess.stderr?.on("data", (chunk) => writeRedacted(process.stderr, chunk));
91
+ }
65
92
  {
66
93
  process.on("exit", (_code, _signal) => {
67
94
  commandProcess?.kill(9);
@@ -95,5 +122,5 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
95
122
  }, "commandFn");
96
123
 
97
124
  export { commandFn, commandSpec };
98
- //# sourceMappingURL=chunk-D2V7SDAQ.js.map
99
- //# sourceMappingURL=chunk-D2V7SDAQ.js.map
125
+ //# sourceMappingURL=chunk-NDRSG3XS.js.map
126
+ //# sourceMappingURL=chunk-NDRSG3XS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/run.command.ts"],"names":[],"mappings":"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","file":"chunk-NDRSG3XS.js","sourcesContent":["import { execa, type ResultPromise } from 'execa';\nimport which from 'which';\nimport { define } from 'gunshi';\nimport { gracefulExit } from 'exit-hook';\n\nimport { loadVarlockEnvGraph } from '../../lib/load-graph';\nimport { checkForConfigErrors, checkForSchemaErrors } from '../helpers/error-checks';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { resetRedactionMap, redactSensitiveConfig } from '../../runtime/env';\n\n\nexport const commandSpec = define({\n name: 'run',\n description: 'Run a command with your environment variables injected',\n args: {\n // watch: {\n // type: 'boolean',\n // short: 'w',\n // description: 'Watch mode',\n // },\n 'no-redact-stdout': {\n type: 'boolean',\n description: 'Disable stdout/stderr redaction to preserve TTY detection for interactive tools',\n },\n },\n examples: `\nExecutes a command in a child process, injecting your resolved and validated environment\nvariables from your .env files. Useful when a code-level integration is not possible.\n\nExamples:\n varlock run -- node app.js # Run a Node.js application\n varlock run -- python script.py # Run a Python script\n varlock run -- sh -c 'echo $MY_VAR' # Use shell expansion for env vars\n varlock run --no-redact-stdout -- psql # Preserve TTY for interactive tools\n\n📍 Important: Use -- to separate varlock options from your command\n\n💡 Tip: For shell expansion of env vars, use: sh -c 'your command here'\n💡 Tip: Use --no-redact-stdout for interactive tools (psql, claude, etc.)\n `.trim(),\n});\n\nlet commandProcess: ResultPromise | undefined;\nlet childCommandKilledFromRestart = false;\nconst isWatchModeRestart = false; // TODO: re-enable watch mode\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n // if \"--\" is present, split the args into our command and the rest, which will be another external command\n const argv = process.argv.slice(2);\n let restCommandArgs: Array<string> = [];\n if (argv.includes('--')) {\n const doubleDashIndex = argv.indexOf('--');\n restCommandArgs = argv.slice(doubleDashIndex + 1);\n } else {\n throw new Error('No command to run! Your command should look like `varlock run -- <your-command>`');\n }\n const commandToRunAsArgs = restCommandArgs;\n const commandToRunStr = restCommandArgs.join(' ');\n\n const rawCommand = commandToRunAsArgs[0];\n const commandArgsOnly = commandToRunAsArgs.slice(1);\n const pathAwareCommand = which.sync(rawCommand, { nothrow: true });\n\n // const isWatchEnabled = ctx.values.watch;\n const isWatchEnabled = false;\n\n // console.log('running command', pathAwareCommand || rawCommand, commandArgsOnly);\n\n\n const envGraph = await loadVarlockEnvGraph();\n checkForSchemaErrors(envGraph);\n await envGraph.resolveEnvValues();\n checkForConfigErrors(envGraph);\n\n // will fail above if there are any errors\n\n const resolvedEnv = envGraph.getResolvedEnvObject();\n const serializedGraph = envGraph.getSerializedGraph();\n // console.log(resolvedEnv);\n\n // needs more thought here\n const fullInjectedEnv = {\n ...process.env,\n ...resolvedEnv,\n __VARLOCK_RUN: '1', // flag for a child process to detect it is runnign via `varlock run`\n __VARLOCK_ENV: JSON.stringify(serializedGraph),\n };\n\n const redactLogs = serializedGraph.settings?.redactLogs ?? true;\n const noRedactStdout = ctx.values['no-redact-stdout'] ?? false;\n\n // Initialize the redaction map if redaction is enabled\n if (redactLogs) {\n resetRedactionMap(serializedGraph);\n }\n\n // When --no-redact-stdout is set, use stdio: 'inherit' to preserve TTY detection\n // Otherwise, pipe stdout/stderr through redaction\n if (noRedactStdout) {\n commandProcess = execa(pathAwareCommand || rawCommand, commandArgsOnly, {\n stdio: 'inherit',\n env: fullInjectedEnv,\n });\n } else {\n // Helper to redact and write output\n const writeRedacted = (stream: NodeJS.WriteStream, chunk: Buffer | string) => {\n const str = chunk.toString();\n stream.write(redactLogs ? redactSensitiveConfig(str) : str);\n };\n\n commandProcess = execa(pathAwareCommand || rawCommand, commandArgsOnly, {\n stdin: 'inherit',\n stdout: 'pipe',\n stderr: 'pipe',\n env: fullInjectedEnv,\n });\n\n // Pipe stdout and stderr through redaction\n commandProcess.stdout?.on('data', (chunk) => writeRedacted(process.stdout, chunk));\n commandProcess.stderr?.on('data', (chunk) => writeRedacted(process.stderr, chunk));\n }\n // console.log('PARENT PID = ', process.pid);\n // console.log('CHILD PID = ', commandProcess.pid);\n\n // if first run, we need to attach some extra exit handling\n if (!isWatchModeRestart) {\n // try to make sure we shut down cleanly and kill the child process\n process.on('exit', (_code: any, _signal: any) => {\n // if (childCommandKilledFromRestart) {\n // childCommandKilledFromRestart = false;\n // return;\n // }\n // console.log('exit!', code, signal);\n commandProcess?.kill(9);\n });\n\n ['SIGTERM', 'SIGINT'].forEach((signal) => {\n process.on(signal, () => {\n // console.log('SIGNAL = ', signal);\n commandProcess?.kill(9);\n gracefulExit(1);\n });\n });\n // TODO: handle other signals?\n }\n\n\n let exitCode: any; // TODO: fix this any\n try {\n const commandResult = await commandProcess;\n exitCode = commandResult.exitCode;\n } catch (error) {\n // console.log('child command error!', error);\n if ((error as any).signal === 'SIGINT' && childCommandKilledFromRestart) {\n // console.log('child command failed due to being killed form restart');\n childCommandKilledFromRestart = false;\n return;\n }\n\n // console.log('child command result error', error);\n if ((error as any).signal === 'SIGINT' || (error as any).signal === 'SIGKILL') {\n gracefulExit(1);\n } else {\n console.log((error as Error).message);\n console.log(`command [${commandToRunStr}] failed`);\n console.log('try running the same command without dmno');\n console.log('if you get a different result, dmno may be the problem...');\n // console.log(`Please report issue here: <${REPORT_ISSUE_LINK}>`);\n }\n exitCode = (error as any).exitCode || 1;\n }\n\n if (isWatchEnabled) {\n if (!childCommandKilledFromRestart) {\n if (exitCode === 0) {\n console.log('\\n✅ command completed successfully');\n } else {\n console.log(`\\n💥 command failed - exit code = ${exitCode}`);\n }\n }\n }\n\n if (!isWatchEnabled) {\n return gracefulExit(exitCode);\n } else {\n console.log('... watching for changes ...');\n }\n};\n"]}
@@ -1,13 +1,13 @@
1
1
  import { redactString } from './chunk-FGMXIEFA.js';
2
2
  import { __commonJS, __name, __toESM } from './chunk-XN24GZXQ.js';
3
3
  import process2 from 'process';
4
- import { exec } from 'child_process';
5
- import { promisify } from 'util';
6
4
  import fs, { accessSync } from 'fs';
7
5
  import fs2, { access } from 'fs/promises';
6
+ import os from 'os';
8
7
  import path2 from 'path';
9
8
  import { ParsedEnvSpecFunctionCall, ParsedEnvSpecStaticValue, ParsedEnvSpecFunctionArgs, ParsedEnvSpecKeyValuePair, parseEnvSpecDotEnvFile } from '@env-spec/parser';
10
- import os from 'os';
9
+ import { exec } from 'child_process';
10
+ import { promisify } from 'util';
11
11
  import crypto from 'crypto';
12
12
  import https from 'https';
13
13
  import semver from 'semver';
@@ -1097,30 +1097,6 @@ async function tryCatch(tryFn, catchFn) {
1097
1097
  }
1098
1098
  }
1099
1099
  __name(tryCatch, "tryCatch");
1100
- var asyncExec = promisify(exec);
1101
-
1102
- // ../utils/src/git-utils.ts
1103
- async function checkIsFileGitIgnored(path4, warnIfNotGitRepo = false) {
1104
- try {
1105
- await asyncExec(`git check-ignore ${path4} -q`);
1106
- return true;
1107
- } catch (err) {
1108
- const stderr = err.stderr;
1109
- if (err.status === 127 || stderr.includes("not found") || stderr.includes("not recognized")) {
1110
- return void 0;
1111
- }
1112
- if (err.code === "ENOENT") return void 0;
1113
- if (stderr === "") return false;
1114
- if (stderr.includes("not a git repository")) {
1115
- if (warnIfNotGitRepo) {
1116
- console.log("\u{1F536} Your code is not currently in a git repository - run `git init` to initialize a new repo.");
1117
- }
1118
- return false;
1119
- }
1120
- throw err;
1121
- }
1122
- }
1123
- __name(checkIsFileGitIgnored, "checkIsFileGitIgnored");
1124
1100
  async function pathExists(p) {
1125
1101
  try {
1126
1102
  await access(p);
@@ -1713,6 +1689,10 @@ var builtInItemDecorators = [
1713
1689
  {
1714
1690
  name: "sensitive"
1715
1691
  },
1692
+ {
1693
+ name: "public",
1694
+ incompatibleWith: ["sensitive"]
1695
+ },
1716
1696
  {
1717
1697
  name: "type",
1718
1698
  useFnArgsResolver: true
@@ -2976,17 +2956,19 @@ var ConfigItem = class {
2976
2956
  async processSensitive() {
2977
2957
  const sensitiveFromDataType = this.dataType?.isSensitive;
2978
2958
  for (const def of this.defs) {
2979
- const sensitiveDec = def.itemDef.decorators?.find((d) => d.name === "sensitive");
2959
+ const sensitiveDecs = def.itemDef.decorators?.filter((d) => d.name === "sensitive" || d.name === "public") || [];
2960
+ const sensitiveDec = sensitiveDecs[0];
2980
2961
  if (sensitiveDec) {
2962
+ const usingPublic = sensitiveDec.name === "public";
2981
2963
  const sensitiveDecValue = await sensitiveDec.resolve();
2982
2964
  if (sensitiveDec.schemaErrors.length) {
2983
2965
  return;
2984
2966
  }
2985
2967
  if (![true, false, void 0].includes(sensitiveDecValue)) {
2986
- throw new SchemaError("@sensitive must resolve to a boolean or undefined");
2968
+ throw new SchemaError("@sensitive/@public must resolve to a boolean or undefined");
2987
2969
  }
2988
2970
  if (sensitiveDecValue !== void 0) {
2989
- this._isSensitive = sensitiveDecValue;
2971
+ this._isSensitive = usingPublic ? !sensitiveDecValue : sensitiveDecValue;
2990
2972
  return;
2991
2973
  }
2992
2974
  }
@@ -3301,7 +3283,7 @@ async function registerPluginInGraph(graph, plugin, pluginDecorator) {
3301
3283
  }
3302
3284
  __name(registerPluginInGraph, "registerPluginInGraph");
3303
3285
  async function downloadPlugin(url) {
3304
- const exec3 = promisify(exec);
3286
+ const exec2 = promisify(exec);
3305
3287
  const cacheDir = path2.join(os.homedir(), ".varlock", "plugins-cache");
3306
3288
  const indexPath = path2.join(cacheDir, "index.json");
3307
3289
  await fs2.mkdir(cacheDir, { recursive: true });
@@ -3332,7 +3314,7 @@ async function downloadPlugin(url) {
3332
3314
  });
3333
3315
  const tmpExtractDir = path2.join(cacheDir, `tmp-extract-${crypto.randomBytes(8).toString("hex")}`);
3334
3316
  await fs2.mkdir(tmpExtractDir);
3335
- await exec3(`tar -xzf ${tmpTgz} -C ${tmpExtractDir}`);
3317
+ await exec2(`tar -xzf ${tmpTgz} -C ${tmpExtractDir}`);
3336
3318
  let pkgJsonPath = path2.join(tmpExtractDir, "package", "package.json");
3337
3319
  let pluginRoot = path2.join(tmpExtractDir, "package");
3338
3320
  if (!await fs2.stat(pkgJsonPath).then(() => true, () => false)) {
@@ -3594,19 +3576,27 @@ var EnvGraphDataSource4 = class {
3594
3576
  this._loadingError = new Error("Cannot use both @currentEnv and @envFlag decorators");
3595
3577
  }
3596
3578
  let envFlagItemKey;
3579
+ let skipCurrentEnvProcessing = false;
3597
3580
  if (currentEnvDec) {
3598
- await currentEnvDec.process();
3599
- if (!currentEnvDec.decValueResolver) {
3600
- throw new Error("No resolver found for @currentEnv decorator");
3601
- }
3602
- if (currentEnvDec.decValueResolver.fnName !== "ref") {
3603
- throw new Error("Expected @currentEnv decorator to be set to direct reference - ie `$APP_ENV`");
3581
+ const parsedValue = currentEnvDec.parsedDecorator.value;
3582
+ if (parsedValue instanceof ParsedEnvSpecFunctionCall && parsedValue.name === "ref") {
3583
+ const args = parsedValue.simplifiedArgs;
3584
+ if (Array.isArray(args) && args.length > 0 && typeof args[0] === "string") {
3585
+ envFlagItemKey = args[0];
3586
+ if (this.isPartialImport && !this.importKeys?.includes(envFlagItemKey)) {
3587
+ skipCurrentEnvProcessing = true;
3588
+ }
3589
+ }
3604
3590
  }
3605
- const refArgValue = currentEnvDec.decValueResolver.arrArgs?.[0]?.staticValue;
3606
- if (!refArgValue || !my_dash_default.isString(refArgValue)) {
3607
- throw new Error("@currentEnv ref must be set to a string");
3591
+ if (!skipCurrentEnvProcessing) {
3592
+ await currentEnvDec.process();
3593
+ if (!currentEnvDec.decValueResolver) {
3594
+ throw new Error("No resolver found for @currentEnv decorator");
3595
+ }
3596
+ if (currentEnvDec.decValueResolver.fnName !== "ref") {
3597
+ throw new Error("Expected @currentEnv decorator to be set to direct reference - ie `$APP_ENV`");
3598
+ }
3608
3599
  }
3609
- envFlagItemKey = refArgValue;
3610
3600
  } else if (envFlagDec) {
3611
3601
  await envFlagDec.process();
3612
3602
  if (!envFlagDec.decValueResolver) throw new Error("@envFlag resolver not set");
@@ -3631,74 +3621,112 @@ var EnvGraphDataSource4 = class {
3631
3621
  const importDecs = this.getRootDecFns("import");
3632
3622
  if (importDecs.length) {
3633
3623
  for (const importDec of importDecs) {
3634
- const importArgs = await importDec.resolve();
3635
- const importPath = importArgs.arr[0];
3636
- const importKeys = importArgs.arr.slice(1);
3637
- if (!importKeys.every(my_dash_default.isString)) {
3638
- throw new Error("expected @import keys to all be strings");
3639
- }
3640
- if (importPath.startsWith("./") || importPath.startsWith("../")) {
3641
- if (!(this instanceof FileBasedDataSource)) {
3642
- throw new Error("@import of files can only be used from a file-based data source");
3643
- }
3644
- const fullImportPath = path2.resolve(this.fullPath, "..", importPath);
3645
- const fileName = path2.basename(fullImportPath);
3646
- if (this.graph.virtualImports) {
3647
- if (importPath.endsWith("/")) {
3648
- if (!Object.keys(this.graph.virtualImports).some((p) => p.startsWith(fullImportPath))) {
3649
- this._loadingError = new Error(`Virtual directory import ${fullImportPath} not found`);
3650
- return;
3651
- }
3652
- await this.addChild(new DirectoryDataSource(fullImportPath), {
3653
- isImport: true,
3654
- importKeys
3655
- });
3656
- } else {
3657
- if (!this.graph.virtualImports[fullImportPath]) {
3658
- this._loadingError = new Error(`Virtual import ${fullImportPath} not found`);
3659
- return;
3624
+ try {
3625
+ await importDec.process();
3626
+ if (importDec.decValueResolver?.objArgs?.enabled) {
3627
+ const enabledResolver = importDec.decValueResolver.objArgs.enabled;
3628
+ const enabledDeps = enabledResolver.deps;
3629
+ for (const depKey of enabledDeps) {
3630
+ const depItem = this.graph.configSchema[depKey];
3631
+ if (!depItem) {
3632
+ throw new Error(`@import enabled parameter depends on non-existent item: ${depKey}`);
3660
3633
  }
3661
- const source = new DotEnvFileDataSource(fullImportPath, {
3662
- overrideContents: this.graph.virtualImports[fullImportPath]
3663
- });
3664
- await this.addChild(source, { isImport: true, importKeys });
3634
+ await depItem.earlyResolve();
3665
3635
  }
3666
- } else {
3667
- const fsStat = await tryCatch(async () => fs2.stat(fullImportPath), (_err) => {
3668
- });
3669
- if (!fsStat) {
3670
- this._loadingError = new Error(`Import path does not exist: ${fullImportPath}`);
3671
- return;
3636
+ }
3637
+ const importArgs = await importDec.resolve();
3638
+ const importPath = importArgs.arr[0];
3639
+ const importKeys = importArgs.arr.slice(1);
3640
+ if (!importKeys.every(my_dash_default.isString)) {
3641
+ throw new Error("expected @import keys to all be strings");
3642
+ }
3643
+ let fullImportPath;
3644
+ if (importPath.startsWith("./") || importPath.startsWith("../")) {
3645
+ if (!(this instanceof FileBasedDataSource)) {
3646
+ throw new Error("@import of files can only be used from a file-based data source");
3672
3647
  }
3673
- if (importPath.endsWith("/")) {
3674
- if (fsStat.isDirectory()) {
3648
+ fullImportPath = path2.resolve(this.fullPath, "..", importPath);
3649
+ } else if (importPath.startsWith("~/") || importPath === "~") {
3650
+ fullImportPath = path2.join(os.homedir(), importPath.slice(1));
3651
+ } else if (importPath.startsWith("/")) {
3652
+ fullImportPath = importPath;
3653
+ }
3654
+ const enabledValue = importArgs.obj.enabled ?? true;
3655
+ if (!my_dash_default.isBoolean(enabledValue)) {
3656
+ throw new Error("expected @import enabled parameter to be a boolean");
3657
+ }
3658
+ if (!enabledValue) continue;
3659
+ const allowMissing = importArgs.obj.allowMissing ?? false;
3660
+ if (!my_dash_default.isBoolean(allowMissing)) {
3661
+ throw new Error("expected @import allowMissing parameter to be a boolean");
3662
+ }
3663
+ if (fullImportPath) {
3664
+ const fileName = path2.basename(fullImportPath);
3665
+ if (this.graph.virtualImports) {
3666
+ if (importPath.endsWith("/")) {
3667
+ const dirExists = Object.keys(this.graph.virtualImports).some((p) => p.startsWith(fullImportPath));
3668
+ if (!dirExists && allowMissing) continue;
3669
+ if (!dirExists) {
3670
+ this._loadingError = new Error(`Virtual directory import ${fullImportPath} not found`);
3671
+ return;
3672
+ }
3675
3673
  await this.addChild(new DirectoryDataSource(fullImportPath), {
3676
3674
  isImport: true,
3677
3675
  importKeys
3678
3676
  });
3679
3677
  } else {
3680
- this._loadingError = new Error(`Imported path ending with "/" is not a directory: ${fullImportPath}`);
3681
- return;
3678
+ const fileExists = this.graph.virtualImports[fullImportPath];
3679
+ if (!fileExists && allowMissing) continue;
3680
+ if (!fileExists) {
3681
+ this._loadingError = new Error(`Virtual import ${fullImportPath} not found`);
3682
+ return;
3683
+ }
3684
+ const source = new DotEnvFileDataSource(fullImportPath, {
3685
+ overrideContents: this.graph.virtualImports[fullImportPath]
3686
+ });
3687
+ await this.addChild(source, { isImport: true, importKeys });
3682
3688
  }
3683
3689
  } else {
3684
- if (fsStat.isDirectory()) {
3685
- this._loadingError = new Error('Imported path is a directory, add trailing "/" to import');
3686
- return;
3687
- } else if (!fileName.startsWith(".env.")) {
3688
- this._loadingError = new Error("imported file must be a .env.* file");
3690
+ const fsStat = await tryCatch(async () => fs2.stat(fullImportPath), (_err) => {
3691
+ });
3692
+ if (!fsStat && allowMissing) continue;
3693
+ if (!fsStat) {
3694
+ this._loadingError = new Error(`Import path does not exist: ${fullImportPath}`);
3689
3695
  return;
3690
3696
  }
3691
- await this.addChild(new DotEnvFileDataSource(fullImportPath), { isImport: true, importKeys });
3697
+ if (importPath.endsWith("/")) {
3698
+ if (fsStat.isDirectory()) {
3699
+ await this.addChild(new DirectoryDataSource(fullImportPath), {
3700
+ isImport: true,
3701
+ importKeys
3702
+ });
3703
+ } else {
3704
+ this._loadingError = new Error(`Imported path ending with "/" is not a directory: ${fullImportPath}`);
3705
+ return;
3706
+ }
3707
+ } else {
3708
+ if (fsStat.isDirectory()) {
3709
+ this._loadingError = new Error('Imported path is a directory, add trailing "/" to import');
3710
+ return;
3711
+ } else if (!fileName.startsWith(".env.")) {
3712
+ this._loadingError = new Error("imported file must be a .env.* file");
3713
+ return;
3714
+ }
3715
+ await this.addChild(new DotEnvFileDataSource(fullImportPath), { isImport: true, importKeys });
3716
+ }
3692
3717
  }
3718
+ } else if (importPath.startsWith("http://") || importPath.startsWith("https://")) {
3719
+ this._loadingError = new Error("http imports not supported yet");
3720
+ return;
3721
+ } else if (importPath.startsWith("npm:")) {
3722
+ this._loadingError = new Error("npm imports not supported yet");
3723
+ return;
3724
+ } else {
3725
+ this._loadingError = new Error("unsupported import type");
3726
+ return;
3693
3727
  }
3694
- } else if (importPath.startsWith("http://") || importPath.startsWith("https://")) {
3695
- this._loadingError = new Error("http imports not supported yet");
3696
- return;
3697
- } else if (importPath.startsWith("npm:")) {
3698
- this._loadingError = new Error("npm imports not supported yet");
3699
- return;
3700
- } else {
3701
- this._loadingError = new Error("unsupported import type");
3728
+ } catch (err) {
3729
+ this._loadingError = err;
3702
3730
  return;
3703
3731
  }
3704
3732
  }
@@ -3758,7 +3786,6 @@ var FileBasedDataSource = class extends EnvGraphDataSource4 {
3758
3786
  static {
3759
3787
  __name(this, "FileBasedDataSource");
3760
3788
  }
3761
- isGitIgnored;
3762
3789
  fullPath;
3763
3790
  fileName;
3764
3791
  rawContents;
@@ -3782,7 +3809,6 @@ var FileBasedDataSource = class extends EnvGraphDataSource4 {
3782
3809
  this.relativePath = path2.relative(process.cwd(), fullPath);
3783
3810
  if (opts?.overrideContents) {
3784
3811
  this.rawContents = opts.overrideContents;
3785
- this.isGitIgnored = opts.overrideGitIgnored;
3786
3812
  }
3787
3813
  if (this.fileName.startsWith(".env")) {
3788
3814
  const fileNameParts = this.fileName.substring(1).split(".");
@@ -3813,7 +3839,6 @@ var FileBasedDataSource = class extends EnvGraphDataSource4 {
3813
3839
  this._loadingError = new Error(`File does not exist: ${this.fullPath}`);
3814
3840
  return;
3815
3841
  }
3816
- this.isGitIgnored = await checkIsFileGitIgnored(this.fullPath);
3817
3842
  this.rawContents = await fs2.readFile(this.fullPath, "utf8");
3818
3843
  }
3819
3844
  if (this.rawContents) await this._parseContents();
@@ -3894,7 +3919,22 @@ var DirectoryDataSource = class extends EnvGraphDataSource4 {
3894
3919
  this.schemaDataSource = this.children[this.children.length - 1];
3895
3920
  }
3896
3921
  await this.addAutoLoadedFile(".env.local");
3897
- const currentEnv = await this.resolveCurrentEnv() || this.envFlagValue;
3922
+ let currentEnv;
3923
+ if (this.schemaDataSource?._envFlagKey) {
3924
+ const envFlagKey = this.schemaDataSource._envFlagKey;
3925
+ if (this.isPartialImport && !this.importKeys?.includes(envFlagKey)) {
3926
+ this._loadingError = new Error(
3927
+ `Imported directory has @currentEnv set to $${envFlagKey}, but "${envFlagKey}" is not included in the import list. Add "${envFlagKey}" to the @import() arguments.`
3928
+ );
3929
+ return;
3930
+ }
3931
+ const envFlagItem = this.graph.configSchema[envFlagKey];
3932
+ if (envFlagItem) {
3933
+ if (!envFlagItem.resolvedValue) await envFlagItem.earlyResolve();
3934
+ currentEnv = envFlagItem.resolvedValue?.toString();
3935
+ }
3936
+ }
3937
+ currentEnv ||= (await this.resolveCurrentEnv())?.toString() || this.envFlagValue?.toString();
3898
3938
  if (currentEnv) {
3899
3939
  await this.addAutoLoadedFile(`.env.${currentEnv}`);
3900
3940
  await this.addAutoLoadedFile(`.env.${currentEnv}.local`);
@@ -4007,6 +4047,6 @@ function getItemSummary(item) {
4007
4047
  __name(getItemSummary, "getItemSummary");
4008
4048
  //! these are probably not relevant anymore, or needs to move to a plugin layer?
4009
4049
 
4010
- 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 };
4011
- //# sourceMappingURL=chunk-OOBWRTIS.js.map
4012
- //# sourceMappingURL=chunk-OOBWRTIS.js.map
4050
+ export { CoercionError, ConfigLoadError, DotEnvFileDataSource, EnvGraph2 as EnvGraph, FileBasedDataSource, ResolutionError, SchemaError, ValidationError, VarlockError, ansis_default, asyncExitHook, getItemSummary, gracefulExit, joinAndCompact, loadEnvGraph, my_dash_default, pathExists, pathExistsSync, tryCatch };
4051
+ //# sourceMappingURL=chunk-RD44SH5U.js.map
4052
+ //# sourceMappingURL=chunk-RD44SH5U.js.map