varlock 1.1.0 → 1.3.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 (137) hide show
  1. package/dist/audit.command-LLD5UIAW.js +16 -0
  2. package/dist/audit.command-LLD5UIAW.js.map +1 -0
  3. package/dist/auto-load.js +6 -6
  4. package/dist/{chunk-QSYH5IDD.js → chunk-5DRCCFKV.js} +3 -3
  5. package/dist/{chunk-QSYH5IDD.js.map → chunk-5DRCCFKV.js.map} +1 -1
  6. package/dist/{chunk-E3F6QKDZ.js → chunk-C5LW5EET.js} +6 -6
  7. package/dist/{chunk-E3F6QKDZ.js.map → chunk-C5LW5EET.js.map} +1 -1
  8. package/dist/chunk-CESFJIM4.js +198 -0
  9. package/dist/chunk-CESFJIM4.js.map +1 -0
  10. package/dist/{chunk-5DUWGI2N.js → chunk-DIPEXEIL.js} +3 -3
  11. package/dist/{chunk-5DUWGI2N.js.map → chunk-DIPEXEIL.js.map} +1 -1
  12. package/dist/{chunk-SDN53OAC.js → chunk-F6ZYIWAR.js} +160 -72
  13. package/dist/chunk-F6ZYIWAR.js.map +1 -0
  14. package/dist/{chunk-2PFIYNFA.js → chunk-FA5SNEKN.js} +30 -13
  15. package/dist/chunk-FA5SNEKN.js.map +1 -0
  16. package/dist/{chunk-XWYFSG46.js → chunk-GKN3UJNE.js} +651 -821
  17. package/dist/chunk-GKN3UJNE.js.map +1 -0
  18. package/dist/{chunk-TQXYC3G3.js → chunk-HH647LSU.js} +5 -5
  19. package/dist/{chunk-TQXYC3G3.js.map → chunk-HH647LSU.js.map} +1 -1
  20. package/dist/{chunk-6RF54KKR.js → chunk-HMWAOBZR.js} +78 -24
  21. package/dist/chunk-HMWAOBZR.js.map +1 -0
  22. package/dist/{chunk-H6NILU2I.js → chunk-INGOLNLE.js} +4 -4
  23. package/dist/{chunk-H6NILU2I.js.map → chunk-INGOLNLE.js.map} +1 -1
  24. package/dist/{chunk-JIUWL2NT.js → chunk-IO2OGZQU.js} +9 -9
  25. package/dist/chunk-IO2OGZQU.js.map +1 -0
  26. package/dist/chunk-IRXBCLL2.js +2045 -0
  27. package/dist/chunk-IRXBCLL2.js.map +1 -0
  28. package/dist/{chunk-QP7TS4SU.js → chunk-JOGGSYT2.js} +6 -6
  29. package/dist/chunk-JOGGSYT2.js.map +1 -0
  30. package/dist/{chunk-F6RTQ5QX.js → chunk-KFALDUEO.js} +3 -3
  31. package/dist/{chunk-F6RTQ5QX.js.map → chunk-KFALDUEO.js.map} +1 -1
  32. package/dist/{chunk-VN4LKYXR.js → chunk-KI5QLKPU.js} +6 -6
  33. package/dist/{chunk-VN4LKYXR.js.map → chunk-KI5QLKPU.js.map} +1 -1
  34. package/dist/{chunk-JUPAI2X4.js → chunk-M6QE3D2O.js} +7 -7
  35. package/dist/{chunk-JUPAI2X4.js.map → chunk-M6QE3D2O.js.map} +1 -1
  36. package/dist/{chunk-CDLU5P62.js → chunk-MPHVA4WC.js} +3 -3
  37. package/dist/{chunk-CDLU5P62.js.map → chunk-MPHVA4WC.js.map} +1 -1
  38. package/dist/{chunk-U2O3AUM2.js → chunk-NW4KR67N.js} +8 -8
  39. package/dist/{chunk-U2O3AUM2.js.map → chunk-NW4KR67N.js.map} +1 -1
  40. package/dist/{chunk-S5O4AAVX.js → chunk-OGGTDFVX.js} +8 -8
  41. package/dist/{chunk-S5O4AAVX.js.map → chunk-OGGTDFVX.js.map} +1 -1
  42. package/dist/chunk-P33JXOU6.js +523 -0
  43. package/dist/chunk-P33JXOU6.js.map +1 -0
  44. package/dist/{chunk-R73FENLU.js → chunk-QDEAHBCB.js} +3 -3
  45. package/dist/{chunk-R73FENLU.js.map → chunk-QDEAHBCB.js.map} +1 -1
  46. package/dist/{chunk-RBFS2QGC.js → chunk-RQZZDYWL.js} +8 -8
  47. package/dist/{chunk-RBFS2QGC.js.map → chunk-RQZZDYWL.js.map} +1 -1
  48. package/dist/{chunk-MGWUDHT5.js → chunk-UUJK65RS.js} +11 -3
  49. package/dist/chunk-UUJK65RS.js.map +1 -0
  50. package/dist/{chunk-A6THM3IR.js → chunk-WJLMLKSG.js} +5 -5
  51. package/dist/{chunk-A6THM3IR.js.map → chunk-WJLMLKSG.js.map} +1 -1
  52. package/dist/{chunk-YO6WHPM4.js → chunk-WTBUNHUJ.js} +5 -5
  53. package/dist/{chunk-YO6WHPM4.js.map → chunk-WTBUNHUJ.js.map} +1 -1
  54. package/dist/chunk-XUY3HAO2.js +171 -0
  55. package/dist/chunk-XUY3HAO2.js.map +1 -0
  56. package/dist/{chunk-ZJNDICC4.js → chunk-XXSPHSF7.js} +6 -6
  57. package/dist/{chunk-ZJNDICC4.js.map → chunk-XXSPHSF7.js.map} +1 -1
  58. package/dist/{chunk-GURKQO4J.js → chunk-YWTIKDGU.js} +7 -2
  59. package/dist/chunk-YWTIKDGU.js.map +1 -0
  60. package/dist/{chunk-F5H5MJ6U.js → chunk-ZTFQ7ZVH.js} +2 -5
  61. package/dist/chunk-ZTFQ7ZVH.js.map +1 -0
  62. package/dist/cli/cli-executable.js +54 -51
  63. package/dist/cli/cli-executable.js.map +1 -1
  64. package/dist/config-item-SQFJ2BJ2.js +7 -0
  65. package/dist/{config-item-6LTV4PNH.js.map → config-item-SQFJ2BJ2.js.map} +1 -1
  66. package/dist/dist-ZBZ52DPW.js +4 -0
  67. package/dist/{dist-WGIHRGBZ.js.map → dist-ZBZ52DPW.js.map} +1 -1
  68. package/dist/dotenv-compat.js +6 -6
  69. package/dist/encrypt.command-WISNYCTG.js +14 -0
  70. package/dist/{encrypt.command-F2OTB6HD.js.map → encrypt.command-WISNYCTG.js.map} +1 -1
  71. package/dist/{env-graph-iNQyTcya.d.ts → env-graph-DImkUkjl.d.ts} +30 -19
  72. package/dist/explain.command-THO6CRHD.js +15 -0
  73. package/dist/{explain.command-TEIPRC7Q.js.map → explain.command-THO6CRHD.js.map} +1 -1
  74. package/dist/index.d.ts +2 -2
  75. package/dist/index.js +14 -15
  76. package/dist/index.js.map +1 -1
  77. package/dist/init.command-3EDACW36.js +14 -0
  78. package/dist/{init.command-5LP3UFKD.js.map → init.command-3EDACW36.js.map} +1 -1
  79. package/dist/install-plugin.command-MXBZTBTE.js +13 -0
  80. package/dist/{install-plugin.command-X7RSLPUJ.js.map → install-plugin.command-MXBZTBTE.js.map} +1 -1
  81. package/dist/lib/exec-sync-varlock.js +1 -1
  82. package/dist/load.command-XRABTXAE.js +15 -0
  83. package/dist/{load.command-7SQRDQ3E.js.map → load.command-XRABTXAE.js.map} +1 -1
  84. package/dist/lock.command-O5MPBQ2I.js +7 -0
  85. package/dist/{lock.command-4LTGMJA3.js.map → lock.command-O5MPBQ2I.js.map} +1 -1
  86. package/dist/plugin-lib.d.ts +2 -2
  87. package/dist/plugin-lib.js +2 -2
  88. package/dist/printenv.command-DLCI4IPZ.js +15 -0
  89. package/dist/{printenv.command-ON7RMFEU.js.map → printenv.command-DLCI4IPZ.js.map} +1 -1
  90. package/dist/reveal.command-6BTK3FJZ.js +15 -0
  91. package/dist/{reveal.command-BW6XYVXH.js.map → reveal.command-6BTK3FJZ.js.map} +1 -1
  92. package/dist/run.command-5CIHZECD.js +16 -0
  93. package/dist/{run.command-5QADABYL.js.map → run.command-5CIHZECD.js.map} +1 -1
  94. package/dist/runtime/env.d.ts +1 -1
  95. package/dist/runtime/env.js +1 -1
  96. package/dist/runtime/init-edge.cjs +9 -1
  97. package/dist/runtime/init-server.cjs +9 -1
  98. package/dist/runtime/patch-console.js +2 -2
  99. package/dist/runtime/patch-response.js +2 -2
  100. package/dist/runtime/patch-server-response.js +2 -2
  101. package/dist/scan.command-PW3OOLQY.js +16 -0
  102. package/dist/{scan.command-ZVW3XAUG.js.map → scan.command-PW3OOLQY.js.map} +1 -1
  103. package/dist/telemetry.command-TZDNG2WR.js +13 -0
  104. package/dist/{telemetry.command-PY6E4QSH.js.map → telemetry.command-TZDNG2WR.js.map} +1 -1
  105. package/dist/typegen.command-QD26Q3MP.js +14 -0
  106. package/dist/{typegen.command-KZ4O5IKQ.js.map → typegen.command-QD26Q3MP.js.map} +1 -1
  107. package/native-bins/darwin/VarlockEnclave.app/Contents/CodeResources +0 -0
  108. package/native-bins/darwin/VarlockEnclave.app/Contents/MacOS/varlock-local-encrypt +0 -0
  109. package/native-bins/win32-x64/varlock-local-encrypt.exe +0 -0
  110. package/package.json +2 -2
  111. package/dist/chunk-2PFIYNFA.js.map +0 -1
  112. package/dist/chunk-6RF54KKR.js.map +0 -1
  113. package/dist/chunk-7GFD2ATN.js +0 -136
  114. package/dist/chunk-7GFD2ATN.js.map +0 -1
  115. package/dist/chunk-F5H5MJ6U.js.map +0 -1
  116. package/dist/chunk-GURKQO4J.js.map +0 -1
  117. package/dist/chunk-HDKXXS2X.js +0 -1959
  118. package/dist/chunk-HDKXXS2X.js.map +0 -1
  119. package/dist/chunk-JIUWL2NT.js.map +0 -1
  120. package/dist/chunk-MGWUDHT5.js.map +0 -1
  121. package/dist/chunk-QP7TS4SU.js.map +0 -1
  122. package/dist/chunk-SDN53OAC.js.map +0 -1
  123. package/dist/chunk-XWYFSG46.js.map +0 -1
  124. package/dist/config-item-6LTV4PNH.js +0 -7
  125. package/dist/dist-WGIHRGBZ.js +0 -4
  126. package/dist/encrypt.command-F2OTB6HD.js +0 -14
  127. package/dist/explain.command-TEIPRC7Q.js +0 -15
  128. package/dist/init.command-5LP3UFKD.js +0 -13
  129. package/dist/install-plugin.command-X7RSLPUJ.js +0 -13
  130. package/dist/load.command-7SQRDQ3E.js +0 -15
  131. package/dist/lock.command-4LTGMJA3.js +0 -7
  132. package/dist/printenv.command-ON7RMFEU.js +0 -15
  133. package/dist/reveal.command-BW6XYVXH.js +0 -15
  134. package/dist/run.command-5QADABYL.js +0 -16
  135. package/dist/scan.command-ZVW3XAUG.js +0 -16
  136. package/dist/telemetry.command-PY6E4QSH.js +0 -13
  137. package/dist/typegen.command-KZ4O5IKQ.js +0 -15
@@ -1,8 +1,9 @@
1
- import { detectJsPackageManager, logLines, fmt, installJsDependency } from './chunk-H6NILU2I.js';
2
- import { define } from './chunk-4A54P4EM.js';
1
+ import { scanCodeForEnvVars } from './chunk-P33JXOU6.js';
2
+ import { detectJsPackageManager, logLines, fmt, installJsDependency } from './chunk-INGOLNLE.js';
3
3
  import { gracefulExit } from './chunk-CHQDS2PI.js';
4
- import { spawnAsync, envSpecUpdater, ParsedEnvSpecStaticValue, tryCatch, parseEnvSpecDotEnvFile, ansis_default, prompts_default, pathExists } from './chunk-XWYFSG46.js';
5
- import { _t, q } from './chunk-HDKXXS2X.js';
4
+ import { define } from './chunk-4A54P4EM.js';
5
+ import { spawnAsync, envSpecUpdater, ParsedEnvSpecStaticValue, ansis_default, tryCatch, parseEnvSpecDotEnvFile, prompts_default, pathExists } from './chunk-GKN3UJNE.js';
6
+ import { Ee, q } from './chunk-IRXBCLL2.js';
6
7
  import { __name } from './chunk-6PEHRAEP.js';
7
8
  import path2, { dirname } from 'path';
8
9
  import fs3 from 'fs/promises';
@@ -57,7 +58,7 @@ function isValidUrl(val) {
57
58
  __name(isValidUrl, "isValidUrl");
58
59
  var EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
59
60
  var VALID_NUMBER_REGEX = /^(0|([1-9][0-9]*))?(\.[0-9]+)?$/;
60
- function inferItemDecorators(file, itemKey, valueStr) {
61
+ function inferItemDecorators(file, itemKey, valueStr = "") {
61
62
  let itemIsPublic = false;
62
63
  if (PUBLIC_PREFIXES.some((prefix) => itemKey.startsWith(prefix))) itemIsPublic = true;
63
64
  if (PUBLIC_KEYWORDS.some((keyword) => itemKey.includes(keyword))) itemIsPublic = true;
@@ -164,7 +165,12 @@ __name(findEnvFiles, "findEnvFiles");
164
165
  var commandSpec = define({
165
166
  name: "init",
166
167
  description: "Set up varlock in the current project",
167
- args: {},
168
+ args: {
169
+ agent: {
170
+ type: "boolean",
171
+ description: "Run in non-interactive mode for agent/automation workflows"
172
+ }
173
+ },
168
174
  examples: `
169
175
  This command starts an interactive onboarding process to help you get started with Varlock.
170
176
  It will:
@@ -176,14 +182,19 @@ It will:
176
182
 
177
183
  Examples:
178
184
  varlock init # Run in the current directory
185
+ varlock init --agent # Run non-interactively (agent/automation friendly)
179
186
  cd path/to/your/project && varlock init
180
187
 
181
188
  For more information, visit https://varlock.dev/getting-started/installation
182
189
  `.trim()
183
190
  });
184
191
  var commandFn = /* @__PURE__ */ __name(async (ctx) => {
192
+ const agentMode = Boolean(ctx.values.agent);
185
193
  const jsPackageManager = detectJsPackageManager();
186
194
  console.log("\u{1F9D9} Hello and welcome to Varlock \u{1F512}\u{1F525}\u2728");
195
+ if (agentMode) {
196
+ logLines([ansis_default.dim("Agent mode enabled: running init non-interactively with deterministic defaults.")]);
197
+ }
187
198
  const envFilePaths = await findEnvFiles();
188
199
  const parsedEnvFiles = {};
189
200
  for (const filePath of envFilePaths) {
@@ -221,16 +232,31 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
221
232
  if (allExampleFileNames.length === 1) {
222
233
  exampleFileToConvert = parsedEnvFiles[allExampleFileNames[0]];
223
234
  } else if (allExampleFileNames.length > 1) {
224
- console.log("");
225
- const selectedExample = await _t({
226
- message: `We detected more than one example .env file. Which one should we use to create your new ${fmt.fileName(".env.schema")}?`,
227
- options: allExampleFileNames.map((fileName) => ({
228
- label: fileName,
229
- value: parsedEnvFiles[fileName]
230
- }))
231
- });
232
- if (q(selectedExample)) return gracefulExit(0);
233
- exampleFileToConvert = selectedExample;
235
+ if (agentMode) {
236
+ const sortedFileNames = [...allExampleFileNames].sort((a, b) => a.localeCompare(b));
237
+ const preferredFileName = sortedFileNames.find((name) => name === ".env.example") ?? sortedFileNames.find((name) => name.startsWith(".env.example.")) ?? sortedFileNames.find((name) => name === ".env.sample") ?? sortedFileNames.find((name) => name.startsWith(".env.sample.")) ?? sortedFileNames[0];
238
+ exampleFileToConvert = parsedEnvFiles[preferredFileName];
239
+ logLines([
240
+ "",
241
+ ansis_default.dim(`Agent mode: auto-selected ${fmt.fileName(preferredFileName)} to generate ${fmt.fileName(".env.schema")}.`)
242
+ ]);
243
+ } else {
244
+ console.log("");
245
+ const selectedExample = await Ee({
246
+ message: `We detected more than one example .env file. Which one should we use to create your new ${fmt.fileName(".env.schema")}?`,
247
+ options: allExampleFileNames.map((fileName) => ({
248
+ label: fileName,
249
+ value: parsedEnvFiles[fileName]
250
+ }))
251
+ });
252
+ if (q(selectedExample)) return gracefulExit(0);
253
+ exampleFileToConvert = selectedExample;
254
+ }
255
+ }
256
+ let scannedCodeEnvKeys = [];
257
+ if (!exampleFileToConvert) {
258
+ const scanResult = await scanCodeForEnvVars();
259
+ scannedCodeEnvKeys = scanResult.keys;
234
260
  }
235
261
  const parsedEnvSchemaFile = exampleFileToConvert?.parsedFile || parseEnvSpecDotEnvFile("");
236
262
  if (!parsedEnvSchemaFile) throw new Error("expected parsed .env example file");
@@ -251,6 +277,21 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
251
277
  ].join("\n"), { location: "after_header" });
252
278
  inferSchemaUpdates(parsedEnvSchemaFile);
253
279
  ensureAllItemsExist(parsedEnvSchemaFile, Object.values(parsedEnvFiles));
280
+ const scannedCodeKeysToAdd = !exampleFileToConvert ? scannedCodeEnvKeys.filter((key) => !parsedEnvSchemaFile.configItems.find((i) => i.key === key)) : [];
281
+ if (scannedCodeKeysToAdd.length > 0) {
282
+ envSpecUpdater.injectFromStr(parsedEnvSchemaFile, [
283
+ "",
284
+ "# items added to schema by `varlock init`",
285
+ "# detected by scanning your source code for env var references",
286
+ "# PLEASE REVIEW THESE!",
287
+ "# ---",
288
+ ""
289
+ ].join("\n"), { location: "end" });
290
+ for (const key of scannedCodeKeysToAdd) {
291
+ envSpecUpdater.injectFromStr(parsedEnvSchemaFile, `${key}=`);
292
+ inferItemDecorators(parsedEnvSchemaFile, key, "");
293
+ }
294
+ }
254
295
  const schemaFilePath = path2.join(process.cwd(), ".env.schema");
255
296
  await fs3.writeFile(schemaFilePath, parsedEnvSchemaFile.toString());
256
297
  if (exampleFileToConvert) {
@@ -259,6 +300,13 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
259
300
  `Your ${fmt.fileName(exampleFileToConvert.fileName)} has been used to generate your new ${fmt.fileName(".env.schema")}:`,
260
301
  fmt.filePath(schemaFilePath)
261
302
  ]);
303
+ } else if (scannedCodeKeysToAdd.length > 0) {
304
+ logLines([
305
+ "",
306
+ `Your new ${fmt.fileName(".env.schema")} file has been created from scanned source code references:`,
307
+ fmt.filePath(schemaFilePath),
308
+ ansis_default.dim(`Detected ${scannedCodeEnvKeys.length} env var key${scannedCodeEnvKeys.length === 1 ? "" : "s"} in your codebase.`)
309
+ ]);
262
310
  } else {
263
311
  logLines([
264
312
  "",
@@ -270,78 +318,118 @@ var commandFn = /* @__PURE__ */ __name(async (ctx) => {
270
318
  logLines([ansis_default.dim(`(and updated ${fmt.fileName(".gitignore")} to ensure it will be tracked by git)`)]);
271
319
  await fs3.appendFile(".gitignore", "\n!.env.schema");
272
320
  }
273
- logLines([
274
- "",
275
- ansis_default.bold(`\u{1F6A7} Please review and update your new ${fmt.fileName(".env.schema")} file! \u{1F6A7}`),
276
- `We've done our best to get you started, but you must review and make sure it is correct!`,
277
- "",
278
- `\u{1F449} Some helpful pointers to get you started:`,
279
- `- add a description to each item when the name is not self explanatory - it will come through in generated types`,
280
- `- use ${fmt.decorator("@required")} (or ${fmt.decorator("@optional")}) to tag items that should fail validation when empty`,
281
- `- use ${fmt.decorator("@sensitive")} to tag items that contain sensitive secrets, and must be handled accordingly`,
282
- `- use ${fmt.decorator("@type")} to set an item's data type (if not a basic string), which affects validation and coercion logic`,
283
- `- if an item value is a ${ansis_default.italic("useful example")} rather than a default, use ${fmt.decorator("@example")}`,
284
- `- if an item value is just a dummy placeholder, delete it`
285
- ]);
286
- const confirmReviewed = await prompts_default.confirm({
287
- message: `Have you reviewed and updated your new ${fmt.fileName(".env.schema")} file?`
288
- });
289
- if (q(confirmReviewed)) return gracefulExit(0);
290
- const reloadedSchemaFile = await parseEnvSpecDotEnvFile(await fs3.readFile(schemaFilePath, "utf-8"));
291
- if (reloadedSchemaFile.configItems.find((i) => i.key === "EXAMPLE_ITEM")) {
321
+ if (agentMode) {
322
+ logLines([
323
+ "",
324
+ ansis_default.bold("Agent setup instructions:"),
325
+ "- Initial schema generation uses heuristics, and must be reviewed and confirmed explicitly with the user",
326
+ "- Schema writing guide: https://varlock.dev/guides/schema",
327
+ "- Confirm/add `@type` on items, default is string, so no `@type=string` necessary",
328
+ "- Add `@required`/`@optional`, can adjust `@defaultRequired` root decorator to change default behavior",
329
+ "- Confirm with user which items are `@sensitive` (secrets, private keys, etc) - see https://varlock.dev/guides/secrets/",
330
+ "- Remove placeholder example values, move useful ones to `@example`",
331
+ "- Add description comments when key itself is not self-explanitory",
332
+ "- Add `@docs()` to attach docs links to items",
333
+ "",
334
+ "Help user review and update .env.schema file for them, validating that config is resolving correctly and valid.",
335
+ "Schema file is safe to read, do not look directly at values in .env / .env.local files - tell user to edit those files if necessary.",
336
+ `Validate the resolved config any time using ${fmt.command("varlock load --agent", { jsPackageManager: true })}. It prints JSON with sensitive values redacted so you can safely inspect output in logs or transcripts. Or drop the \`--agent\` flag to get human-readable output to show the user.`,
337
+ "",
338
+ "Advanced setup:",
339
+ "- Can use multiple .env files or functions to manage variation per environment, see https://varlock.dev/guides/environments/",
340
+ "- Complex/large files can be broken up and use `@import`, see https://varlock.dev/guides/import/",
341
+ "- If user wants to load secrets from external sources, help install and configure plugins - see https://varlock.dev/guides/plugins/",
342
+ "- If user has any sensitive values in plaintext, can use local encryption, see `https://varlock.dev/guides/local-encryption/",
343
+ ""
344
+ ]);
345
+ } else {
292
346
  logLines([
293
347
  "",
294
- ansis_default.bold(`\u{1F6A8} Really? ${ansis_default.red("You didn't remove the EXAMPLE_ITEM!")}`),
295
- `Please make sure your schema is all correct before using it...`
348
+ ansis_default.bold(`\u{1F6A7} Please review and update your new ${fmt.fileName(".env.schema")} file! \u{1F6A7}`),
349
+ `We've done our best to get you started, but you must review and make sure it is correct!`,
350
+ "",
351
+ `\u{1F449} Some helpful pointers to get you started:`,
352
+ `- add a description to each item when the name is not self explanatory - it will come through in generated types`,
353
+ `- use ${fmt.decorator("@required")} (or ${fmt.decorator("@optional")}) to tag items that should fail validation when empty`,
354
+ `- use ${fmt.decorator("@sensitive")} to tag items that contain sensitive secrets, and must be handled accordingly`,
355
+ `- use ${fmt.decorator("@type")} to set an item's data type (if not a basic string), which affects validation and coercion logic`,
356
+ `- if an item value is a ${ansis_default.italic("useful example")} rather than a default, use ${fmt.decorator("@example")}`,
357
+ `- if an item value is just a dummy placeholder, delete it`
296
358
  ]);
359
+ const confirmReviewed = await prompts_default.confirm({
360
+ message: `Have you reviewed and updated your new ${fmt.fileName(".env.schema")} file?`
361
+ });
362
+ if (q(confirmReviewed)) return gracefulExit(0);
363
+ const reloadedSchemaFile = await parseEnvSpecDotEnvFile(await fs3.readFile(schemaFilePath, "utf-8"));
364
+ if (reloadedSchemaFile.configItems.find((i) => i.key === "EXAMPLE_ITEM")) {
365
+ logLines([
366
+ "",
367
+ ansis_default.bold(`\u{1F6A8} Really? ${ansis_default.red("You didn't remove the EXAMPLE_ITEM!")}`),
368
+ `Please make sure your schema is all correct before using it...`
369
+ ]);
370
+ }
297
371
  }
298
372
  if (exampleFileToConvert) {
299
- const confirmDeleteExample = await prompts_default.confirm({
300
- message: `Should we delete your ${fmt.fileName(exampleFileToConvert.fileName)} file? ${ansis_default.italic.gray("(you can always do this yourself later)")}`
301
- });
302
- if (q(confirmDeleteExample)) return gracefulExit(0);
303
- if (confirmDeleteExample) {
304
- await fs3.unlink(exampleFileToConvert.fullPath);
373
+ if (agentMode) {
374
+ logLines([`- left ${exampleFileToConvert.fileName} in place (no destructive prompts) - confirm with user and remove for them`]);
375
+ } else {
376
+ const confirmDeleteExample = await prompts_default.confirm({
377
+ message: `Should we delete your ${fmt.fileName(exampleFileToConvert.fileName)} file? ${ansis_default.italic.gray("(you can always do this yourself later)")}`
378
+ });
379
+ if (q(confirmDeleteExample)) return gracefulExit(0);
380
+ if (confirmDeleteExample) {
381
+ await fs3.unlink(exampleFileToConvert.fullPath);
382
+ }
305
383
  }
306
384
  }
307
385
  const defaultsFile = Object.values(parsedEnvFiles).find((f) => {
308
386
  return f.fileName.startsWith(".env.default");
309
387
  });
310
388
  if (defaultsFile) {
311
- logLines([
312
- "",
313
- `\u{1F6A7} We detected a ${fmt.fileName(defaultsFile.fileName)} file in your project`,
314
- `You should migrate these default values into ${fmt.fileName(".env.schema")} and delete it.`
315
- ]);
389
+ if (agentMode) {
390
+ logLines([`- found ${defaultsFile.fileName} in project - tell user to migrate defaults to .env.schema and delete it`]);
391
+ } else {
392
+ logLines([
393
+ "",
394
+ `\u{1F6A7} We detected a ${fmt.fileName(defaultsFile.fileName)} file in your project`,
395
+ `You should migrate these default values into ${fmt.fileName(".env.schema")} and delete it.`
396
+ ]);
397
+ }
316
398
  }
317
399
  const redundantInfo = await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles);
318
400
  if (Object.keys(redundantInfo).length > 0) {
401
+ if (agentMode) {
402
+ logLines([`- found redundant values in other .env files - tell user to review and delete them`]);
403
+ } else {
404
+ logLines([
405
+ "",
406
+ ansis_default.bold("\u203C\uFE0F Now that your schema contains defaults, some values in your other .env files are redundant:")
407
+ ]);
408
+ for (const [sourcePath, itemKeys] of Object.entries(redundantInfo)) {
409
+ console.log(fmt.filePath(sourcePath));
410
+ console.log(" ", itemKeys.map((k) => ansis_default.italic(k)).join(", "));
411
+ }
412
+ const confirmDeleteRedundant = await prompts_default.confirm({
413
+ message: "Should we delete these redundant values from your other .env files?"
414
+ });
415
+ if (q(confirmDeleteRedundant)) return gracefulExit(0);
416
+ if (confirmDeleteRedundant) {
417
+ await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles, { delete: true });
418
+ }
419
+ }
420
+ }
421
+ if (!agentMode) {
319
422
  logLines([
320
423
  "",
321
- ansis_default.bold("\u203C\uFE0F Now that your schema contains defaults, some values in your other .env files are redundant:")
424
+ ansis_default.bold("\u{1F389} Great!"),
425
+ `You can run ${fmt.command("varlock load", { jsPackageManager })} to attempt loading your env vars validate against your new schema.`,
426
+ "",
427
+ "Check out our docs for more info about integrating into your application.",
428
+ "",
429
+ "\u{1F4D6} https://varlock.dev \u{1F448}",
430
+ ""
322
431
  ]);
323
- for (const [sourcePath, itemKeys] of Object.entries(redundantInfo)) {
324
- console.log(fmt.filePath(sourcePath));
325
- console.log(" ", itemKeys.map((k) => ansis_default.italic(k)).join(", "));
326
- }
327
- const confirmDeleteRedundant = await prompts_default.confirm({
328
- message: "Should we delete these redundant values from your other .env files?"
329
- });
330
- if (q(confirmDeleteRedundant)) return gracefulExit(0);
331
- if (confirmDeleteRedundant) {
332
- await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles, { delete: true });
333
- }
334
432
  }
335
- logLines([
336
- "",
337
- ansis_default.bold("\u{1F389} Great!"),
338
- `You can run ${fmt.command("varlock load", { jsPackageManager })} to attempt loading your env vars validate against your new schema.`,
339
- "",
340
- "Check out our docs for more info about integrating into your application.",
341
- "",
342
- "\u{1F4D6} https://varlock.dev \u{1F448}",
343
- ""
344
- ]);
345
433
  }
346
434
  if (jsPackageManager && await pathExists(path2.join(process.cwd(), "package.json"))) {
347
435
  const installResult = installJsDependency({
@@ -383,5 +471,5 @@ ${bunfigContents}`);
383
471
  }, "commandFn");
384
472
 
385
473
  export { commandFn, commandSpec };
386
- //# sourceMappingURL=chunk-SDN53OAC.js.map
387
- //# sourceMappingURL=chunk-SDN53OAC.js.map
474
+ //# sourceMappingURL=chunk-F6ZYIWAR.js.map
475
+ //# sourceMappingURL=chunk-F6ZYIWAR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../utils/src/git-utils.ts","../src/cli/helpers/infer-schema.ts","../src/cli/helpers/find-env-files.ts","../src/cli/commands/init.command.ts"],"names":["path","fs"],"mappings":"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","file":"chunk-F6ZYIWAR.js","sourcesContent":["import { spawnAsync } from './exec-helpers';\nimport { dirname } from 'node:path';\n\nexport async function checkIsFileGitIgnored(path: string, warnIfNotGitRepo = false) {\n try {\n // Use spawnAsync with array arguments to properly handle paths with spaces\n // Pass cwd to run git from the file's directory\n await spawnAsync('git', ['check-ignore', path, '-q'], { cwd: dirname(path) });\n return true;\n } catch (err) {\n // git binary not found (not installed or not in PATH) - check this first\n // before accessing err.data which won't exist on native spawn ENOENT errors\n if ((err as any).code === 'ENOENT') return undefined;\n\n const errorOutput = (err as any).data as string | undefined;\n // git is not installed, so we can't check\n if (\n (err as any).exitCode === 127\n || errorOutput?.includes('not found')\n || errorOutput?.includes('not recognized') // windows\n ) {\n return undefined;\n }\n // `git check-ignore -q` exits with code 1 but no other error if is not ignored\n if (errorOutput === '') return false;\n if (errorOutput?.includes('not a git repository')) {\n if (warnIfNotGitRepo) {\n // eslint-disable-next-line no-console\n console.log('🔶 Your code is not currently in a git repository - run `git init` to initialize a new repo.');\n }\n return false;\n }\n // file is outside the current git repository (e.g., importing from home directory)\n if (errorOutput?.includes('is outside repository')) {\n return undefined;\n }\n // otherwise we'll let it throw since something else is happening\n throw err;\n }\n}\n","import fs from 'node:fs/promises';\nimport {\n envSpecUpdater, ParsedEnvSpecFile, ParsedEnvSpecStaticValue,\n} from '@env-spec/parser';\n\n\nexport type DetectedEnvFile = {\n fileName: string,\n fullPath: string,\n parsedFile: ParsedEnvSpecFile\n};\n\nconst PUBLIC_PREFIXES = [\n 'PUBLIC',\n 'VITE',\n 'NEXT_PUBLIC',\n 'NUXT_PUBLIC',\n];\nconst PUBLIC_KEYWORDS = ['PUBLIC'];\nconst SENSITIVE_KEYWORDS = [\n 'SECRET',\n 'API_KEY',\n 'PASSWORD',\n 'TOKEN',\n 'PRIVATE',\n 'CREDENTIALS',\n];\n\nfunction isValidUrl(val: string) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const u = new URL(val);\n return true;\n } catch (err) {\n return false;\n }\n}\n\nconst EMAIL_REGEX = /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\nconst VALID_NUMBER_REGEX = /^(0|([1-9][0-9]*))?(\\.[0-9]+)?$/;\n\n\nexport function inferItemDecorators(file: ParsedEnvSpecFile, itemKey: string, valueStr = '') {\n // infer @sensitive\n let itemIsPublic = false;\n if (PUBLIC_PREFIXES.some((prefix) => itemKey.startsWith(prefix))) itemIsPublic = true;\n if (PUBLIC_KEYWORDS.some((keyword) => itemKey.includes(keyword))) itemIsPublic = true;\n\n let itemIsSensitive = false;\n if (SENSITIVE_KEYWORDS.some((keyword) => itemKey.includes(keyword))) itemIsSensitive = true;\n\n if (itemIsPublic) {\n // not marking these for now, since we've already made the default not sensitive\n // envSpecUpdater.setItemDecorator(file, itemKey, 'sensitive', 'false');\n } else if (itemIsSensitive) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'sensitive', 'true');\n }\n\n // infer @type\n // > from key\n if (itemKey === 'PORT' || itemKey.endsWith('_PORT')) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'port');\n } else if (itemKey.endsWith('_EMAIL')) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'email');\n } else if (itemKey.endsWith('_URL') || itemKey.endsWith('_URI')) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'url');\n\n\n // > from value\n } else if (valueStr) {\n // move obvious examples to @example\n if (valueStr.startsWith('<') && valueStr.endsWith('>')) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'example', valueStr);\n // remove example from value\n }\n\n if (valueStr === 'true' || valueStr === 'false') {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'boolean');\n } else if (EMAIL_REGEX.test(valueStr)) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'email');\n } else if (valueStr !== '0' && valueStr !== '1' && VALID_NUMBER_REGEX.test(valueStr)) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'number');\n } else if (isValidUrl(valueStr)) {\n envSpecUpdater.setItemDecorator(file, itemKey, 'type', 'url');\n }\n // TODO: more...\n }\n}\n\nexport function inferSchemaUpdates(file: ParsedEnvSpecFile) {\n for (const item of file.configItems) {\n const valueStr = (\n item.value instanceof ParsedEnvSpecStaticValue && item.value.value?.toString()\n ) || '';\n // console.log(item.key, '-', valueStr);\n inferItemDecorators(file, item.key, valueStr);\n }\n}\n\n\nexport function ensureAllItemsExist(schemaFile: ParsedEnvSpecFile, otherFiles: Array<DetectedEnvFile>) {\n const addedItemKeys: Array<string> = [];\n for (const otherFile of otherFiles) {\n for (const item of otherFile.parsedFile.configItems) {\n const itemInSchema = schemaFile.configItems.find((i) => i.key === item.key);\n if (itemInSchema) continue;\n\n if (addedItemKeys.length === 0) {\n envSpecUpdater.injectFromStr(schemaFile, [\n '',\n '# items added to schema by `varlock init`',\n '# that were missing in example, but detected in other .env files',\n '# PLEASE REVIEW THESE!',\n '# ---',\n '',\n ].join('\\n'), { location: 'end' });\n }\n addedItemKeys.push(item.key);\n envSpecUpdater.injectFromStr(schemaFile, `${item.key}=`);\n const itemValue = (\n item.value instanceof ParsedEnvSpecStaticValue && item.value.value?.toString()\n ) || '';\n inferItemDecorators(schemaFile, item.key, String(itemValue));\n }\n }\n}\n\nexport async function detectRedundantValues(\n schemaFile: ParsedEnvSpecFile,\n otherFiles: Record<string, DetectedEnvFile>,\n opts: { delete?: boolean } = {},\n) {\n const redundantItemsBySourcePath: Record<string, Array<string>> = {};\n const schemaValues = schemaFile.toSimpleObj();\n for (const otherFile of Object.values(otherFiles)) {\n if (\n otherFile.fileName.startsWith('.env.schema')\n || otherFile.fileName.startsWith('.env.example')\n || otherFile.fileName.startsWith('.env.sample')\n || otherFile.fileName.startsWith('.env.default')\n ) continue;\n\n const otherFileValues = otherFile.parsedFile.toSimpleObj();\n for (const itemKey in otherFileValues) {\n if (!(itemKey in schemaValues)) continue;\n if (otherFileValues[itemKey] !== schemaValues[itemKey]) continue;\n\n redundantItemsBySourcePath[otherFile.fullPath] ||= [];\n redundantItemsBySourcePath[otherFile.fullPath].push(itemKey);\n if (opts.delete) {\n envSpecUpdater.deleteItem(otherFile.parsedFile, itemKey);\n }\n }\n\n if (opts.delete) {\n await fs.writeFile(otherFile.fullPath, otherFile.parsedFile.toString(), 'utf8');\n }\n }\n\n return redundantItemsBySourcePath;\n}\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\n\n// our tool may generate some additional files which we want to ignore\nconst SKIP_FILE_TYPES = ['.md', '.d.ts'];\n\nexport async function findEnvFiles(opts?: {\n cwd?: string,\n}) {\n const cwd = opts?.cwd || process.cwd();\n\n const envFiles = [];\n\n const filesWithinDir = await fs.readdir(cwd);\n\n // Filter for files starting with .env and check if they exist\n for (const fileName of filesWithinDir) {\n if (fileName === '.env' || fileName.startsWith('.env.')) { // this ignores `.envrc` files\n let skip = false;\n for (const fileType of SKIP_FILE_TYPES) {\n if (fileName.endsWith(fileType)) skip = true;\n }\n if (skip) continue;\n envFiles.push(path.join(cwd, fileName));\n }\n }\n\n // TODO: we may want to look up or down the folder tree?\n // TODO: we could support looking within specific directories (\"config\", \"env\", etc)\n\n return envFiles;\n}\n","/* eslint-disable @stylistic/quotes */\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport ansis from 'ansis';\nimport { isCancel, select } from '@clack/prompts';\nimport { define } from 'gunshi';\nimport { gracefulExit } from 'exit-hook';\n\nimport { envSpecUpdater, parseEnvSpecDotEnvFile } from '@env-spec/parser';\nimport { checkIsFileGitIgnored } from '@env-spec/utils/git-utils';\nimport { pathExists } from '@env-spec/utils/fs-utils';\nimport _ from '@env-spec/utils/my-dash';\n\nimport prompts from '../helpers/prompts';\nimport { fmt, logLines } from '../helpers/pretty-format';\nimport {\n detectRedundantValues, ensureAllItemsExist, inferSchemaUpdates, type DetectedEnvFile,\n inferItemDecorators,\n} from '../helpers/infer-schema';\nimport { detectJsPackageManager, installJsDependency } from '../helpers/js-package-manager-utils';\nimport { type TypedGunshiCommandFn } from '../helpers/gunshi-type-utils';\nimport { findEnvFiles } from '../helpers/find-env-files';\nimport { tryCatch } from '@env-spec/utils/try-catch';\nimport { scanCodeForEnvVars } from '../helpers/env-var-scanner';\n\nexport const commandSpec = define({\n name: 'init',\n description: 'Set up varlock in the current project',\n args: {\n agent: {\n type: 'boolean',\n description: 'Run in non-interactive mode for agent/automation workflows',\n },\n },\n examples: `\nThis command starts an interactive onboarding process to help you get started with Varlock.\nIt will:\n - Scan for existing .env files in your project\n - Help create a .env.schema file from your .env.example or .env.sample file\n - Install varlock as a dependency in package.json (if applicable)\n\n📍 Run this command in directories that contain .env or .env.* files\n\nExamples:\n varlock init # Run in the current directory\n varlock init --agent # Run non-interactively (agent/automation friendly)\n cd path/to/your/project && varlock init\n\nFor more information, visit https://varlock.dev/getting-started/installation\n `.trim(),\n});\n\nexport const commandFn: TypedGunshiCommandFn<typeof commandSpec> = async (ctx) => {\n const agentMode = Boolean(ctx.values.agent);\n const jsPackageManager = detectJsPackageManager();\n\n console.log('🧙 Hello and welcome to Varlock 🔒🔥✨');\n if (agentMode) {\n logLines([ansis.dim('Agent mode enabled: running init non-interactively with deterministic defaults.')]);\n }\n\n // scan for all .env files within current directory\n const envFilePaths = await findEnvFiles();\n const parsedEnvFiles: Record<string, DetectedEnvFile> = {};\n for (const filePath of envFilePaths) {\n const fileContents = await fs.readFile(filePath, 'utf-8');\n const fileName = path.basename(filePath);\n const parsedFile = await tryCatch(async () => parseEnvSpecDotEnvFile(fileContents), () => {\n logLines([\n '',\n `Unable to parse ${fmt.filePath(filePath)}`,\n 'This file will be skipped.',\n ]);\n });\n if (!parsedFile) {\n continue;\n }\n parsedEnvFiles[fileName] = {\n fileName,\n fullPath: filePath,\n parsedFile,\n };\n }\n\n const existingSchemaFile = parsedEnvFiles['.env.schema'];\n\n // * SET UP SCHEMA ---------------------------------------------\n if (existingSchemaFile) {\n // for now - we don't do anything if they already have a schema set up\n // in the future, we may want to add more tools for projects that are already set up\n logLines([\n `It looks like you already have a ${fmt.fileName('.env.schema')} file 🎉`,\n 'This init helper is meant to help you get a new project set up.',\n 'If you need to make changes to your schema or values, you can update your files directly.',\n 'See more docs at https://varlock.dev/guides/schema',\n ]);\n } else {\n const allExampleFileNames = Object.keys(parsedEnvFiles).filter((fileName) => {\n return fileName.startsWith('.env.example') || fileName.startsWith('.env.sample');\n });\n let exampleFileToConvert: typeof parsedEnvFiles[keyof typeof parsedEnvFiles] | undefined;\n\n if (allExampleFileNames.length === 1) {\n exampleFileToConvert = parsedEnvFiles[allExampleFileNames[0]];\n } else if (allExampleFileNames.length > 1) {\n if (agentMode) {\n const sortedFileNames = [...allExampleFileNames].sort((a, b) => a.localeCompare(b));\n const preferredFileName = sortedFileNames.find((name) => name === '.env.example')\n ?? sortedFileNames.find((name) => name.startsWith('.env.example.'))\n ?? sortedFileNames.find((name) => name === '.env.sample')\n ?? sortedFileNames.find((name) => name.startsWith('.env.sample.'))\n ?? sortedFileNames[0];\n exampleFileToConvert = parsedEnvFiles[preferredFileName];\n logLines([\n '',\n ansis.dim(`Agent mode: auto-selected ${fmt.fileName(preferredFileName)} to generate ${fmt.fileName('.env.schema')}.`),\n ]);\n } else {\n console.log('');\n // not quite sure about this, but we'll just let them select one\n const selectedExample = await select({\n message: `We detected more than one example .env file. Which one should we use to create your new ${fmt.fileName('.env.schema')}?`,\n options: allExampleFileNames.map((fileName) => ({\n label: fileName,\n value: parsedEnvFiles[fileName],\n })),\n });\n if (isCancel(selectedExample)) return gracefulExit(0);\n exampleFileToConvert = selectedExample;\n }\n }\n\n let scannedCodeEnvKeys: Array<string> = [];\n if (!exampleFileToConvert) {\n const scanResult = await scanCodeForEnvVars();\n scannedCodeEnvKeys = scanResult.keys;\n }\n\n // update the schema\n const parsedEnvSchemaFile = exampleFileToConvert?.parsedFile || parseEnvSpecDotEnvFile('');\n if (!parsedEnvSchemaFile) throw new Error('expected parsed .env example file');\n envSpecUpdater.ensureHeader(parsedEnvSchemaFile, [\n 'This env file uses @env-spec - see https://varlock.dev/env-spec for more info',\n '',\n // TODO: add env spec version? real links?\n ].join('\\n'));\n envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, 'defaultRequired', 'infer', { explicitTrue: true });\n envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, 'defaultSensitive', 'false', { explicitTrue: true });\n // TODO: detect js/ts project before adding this\n envSpecUpdater.setRootDecorator(parsedEnvSchemaFile, 'generateTypes', 'lang=ts, path=env.d.ts', { bareFnArgs: true });\n // envSpecUpdater.setRootDecorator(parsedEnvFile, 'envFlag', 'APP_ENV', { comment: 'controls automatic loading of env-specific files (e.g. .env.test, .env.prod, etc.)' });\n\n // add example item\n envSpecUpdater.injectFromStr(parsedEnvSchemaFile, [\n '',\n '# example env variable injected by `varlock init` ⚠️ DELETE THIS ITEM! ⚠️',\n '# @required @sensitive @example=\"example value\"',\n 'EXAMPLE_ITEM=\"delete me!\"',\n '',\n ].join('\\n'), { location: 'after_header' });\n // update some decorators based on some simple heuristics\n inferSchemaUpdates(parsedEnvSchemaFile);\n // add items we find in other env files, but are missing in the schema/example\n ensureAllItemsExist(parsedEnvSchemaFile, Object.values(parsedEnvFiles));\n\n const scannedCodeKeysToAdd = !exampleFileToConvert\n ? scannedCodeEnvKeys.filter((key) => !parsedEnvSchemaFile.configItems.find((i) => i.key === key))\n : [];\n\n // add items we detect in source code if no sample/example file was provided\n if (scannedCodeKeysToAdd.length > 0) {\n envSpecUpdater.injectFromStr(parsedEnvSchemaFile, [\n '',\n '# items added to schema by `varlock init`',\n '# detected by scanning your source code for env var references',\n '# PLEASE REVIEW THESE!',\n '# ---',\n '',\n ].join('\\n'), { location: 'end' });\n\n for (const key of scannedCodeKeysToAdd) {\n envSpecUpdater.injectFromStr(parsedEnvSchemaFile, `${key}=`);\n inferItemDecorators(parsedEnvSchemaFile, key, '');\n }\n }\n\n // write new updated schema file\n const schemaFilePath = path.join(process.cwd(), '.env.schema');\n await fs.writeFile(schemaFilePath, parsedEnvSchemaFile.toString());\n\n // log new schema file path\n if (exampleFileToConvert) {\n logLines([\n '',\n `Your ${fmt.fileName(exampleFileToConvert.fileName)} has been used to generate your new ${fmt.fileName('.env.schema')}:`,\n fmt.filePath(schemaFilePath),\n ]);\n } else if (scannedCodeKeysToAdd.length > 0) {\n logLines([\n '',\n `Your new ${fmt.fileName('.env.schema')} file has been created from scanned source code references:`,\n fmt.filePath(schemaFilePath),\n ansis.dim(`Detected ${scannedCodeEnvKeys.length} env var key${scannedCodeEnvKeys.length === 1 ? '' : 's'} in your codebase.`),\n ]);\n } else {\n logLines([\n '',\n `Your new ${fmt.fileName('.env.schema')} file has been created:`,\n fmt.filePath(schemaFilePath),\n ]);\n }\n\n // make sure .env.schema is not gitignored\n if (await checkIsFileGitIgnored(schemaFilePath)) {\n // maybe could do this silently? it's relatively harmless\n logLines([ansis.dim(`(and updated ${fmt.fileName('.gitignore')} to ensure it will be tracked by git)`)]);\n await fs.appendFile('.gitignore', '\\n!.env.schema');\n }\n\n if (agentMode) {\n logLines([\n '',\n ansis.bold('Agent setup instructions:'),\n '- Initial schema generation uses heuristics, and must be reviewed and confirmed explicitly with the user',\n '- Schema writing guide: https://varlock.dev/guides/schema',\n '- Confirm/add `@type` on items, default is string, so no `@type=string` necessary',\n '- Add `@required`/`@optional`, can adjust `@defaultRequired` root decorator to change default behavior',\n '- Confirm with user which items are `@sensitive` (secrets, private keys, etc) - see https://varlock.dev/guides/secrets/',\n '- Remove placeholder example values, move useful ones to `@example`',\n '- Add description comments when key itself is not self-explanitory',\n '- Add `@docs()` to attach docs links to items',\n '',\n 'Help user review and update .env.schema file for them, validating that config is resolving correctly and valid.',\n 'Schema file is safe to read, do not look directly at values in .env / .env.local files - tell user to edit those files if necessary.',\n `Validate the resolved config any time using ${fmt.command('varlock load --agent', { jsPackageManager: true })}. It prints JSON with sensitive values redacted so you can safely inspect output in logs or transcripts. Or drop the \\`--agent\\` flag to get human-readable output to show the user.`,\n '',\n 'Advanced setup:',\n '- Can use multiple .env files or functions to manage variation per environment, see https://varlock.dev/guides/environments/',\n '- Complex/large files can be broken up and use `@import`, see https://varlock.dev/guides/import/',\n '- If user wants to load secrets from external sources, help install and configure plugins - see https://varlock.dev/guides/plugins/',\n '- If user has any sensitive values in plaintext, can use local encryption, see `https://varlock.dev/guides/local-encryption/',\n '',\n ]);\n } else {\n // ask them to review and confirm\n logLines([\n '',\n ansis.bold(`🚧 Please review and update your new ${fmt.fileName('.env.schema')} file! 🚧`),\n `We've done our best to get you started, but you must review and make sure it is correct!`,\n '',\n `👉 Some helpful pointers to get you started:`,\n `- add a description to each item when the name is not self explanatory - it will come through in generated types`,\n `- use ${fmt.decorator('@required')} (or ${fmt.decorator('@optional')}) to tag items that should fail validation when empty`,\n `- use ${fmt.decorator('@sensitive')} to tag items that contain sensitive secrets, and must be handled accordingly`,\n `- use ${fmt.decorator('@type')} to set an item's data type (if not a basic string), which affects validation and coercion logic`,\n `- if an item value is a ${ansis.italic('useful example')} rather than a default, use ${fmt.decorator('@example')}`,\n `- if an item value is just a dummy placeholder, delete it`,\n ]);\n const confirmReviewed = await prompts.confirm({\n message: `Have you reviewed and updated your new ${fmt.fileName('.env.schema')} file?`,\n });\n if (isCancel(confirmReviewed)) return gracefulExit(0);\n\n // reload the graph\n const reloadedSchemaFile = await parseEnvSpecDotEnvFile(await fs.readFile(schemaFilePath, 'utf-8'));\n // check if they removed the EXAMPLE_ITEM and warn them\n if (reloadedSchemaFile.configItems.find((i) => i.key === 'EXAMPLE_ITEM')) {\n logLines([\n '',\n ansis.bold(`🚨 Really? ${ansis.red(\"You didn't remove the EXAMPLE_ITEM!\")}`),\n `Please make sure your schema is all correct before using it...`,\n ]);\n }\n }\n\n // delete the example file if they want us to\n if (exampleFileToConvert) {\n if (agentMode) {\n logLines([`- left ${exampleFileToConvert.fileName} in place (no destructive prompts) - confirm with user and remove for them`]);\n } else {\n const confirmDeleteExample = await prompts.confirm({\n message: `Should we delete your ${fmt.fileName(exampleFileToConvert.fileName)} file? ${ansis.italic.gray('(you can always do this yourself later)')}`,\n });\n if (isCancel(confirmDeleteExample)) return gracefulExit(0);\n if (confirmDeleteExample) {\n await fs.unlink(exampleFileToConvert.fullPath);\n }\n }\n }\n\n // recommendation to delete defaults file\n const defaultsFile = Object.values(parsedEnvFiles).find((f) => {\n return f.fileName.startsWith('.env.default'); // also covers \".env.defaults\"\n });\n if (defaultsFile) {\n if (agentMode) {\n logLines([`- found ${defaultsFile.fileName} in project - tell user to migrate defaults to .env.schema and delete it`]);\n } else {\n logLines([\n '',\n `🚧 We detected a ${fmt.fileName(defaultsFile.fileName)} file in your project`,\n `You should migrate these default values into ${fmt.fileName('.env.schema')} and delete it.`,\n ]);\n }\n }\n\n // detect and remove redundant defaults that are now in the schema\n const redundantInfo = await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles);\n if (Object.keys(redundantInfo).length > 0) {\n if (agentMode) {\n logLines([`- found redundant values in other .env files - tell user to review and delete them`]);\n } else {\n logLines([\n '',\n ansis.bold('‼️ Now that your schema contains defaults, some values in your other .env files are redundant:'),\n ]);\n for (const [sourcePath, itemKeys] of Object.entries(redundantInfo)) {\n console.log(fmt.filePath(sourcePath));\n console.log(' ', itemKeys.map((k) => ansis.italic(k)).join(', '));\n }\n\n const confirmDeleteRedundant = await prompts.confirm({\n message: 'Should we delete these redundant values from your other .env files?',\n });\n if (isCancel(confirmDeleteRedundant)) return gracefulExit(0);\n if (confirmDeleteRedundant) {\n await detectRedundantValues(parsedEnvSchemaFile, parsedEnvFiles, { delete: true });\n }\n }\n }\n\n // final success!\n if (!agentMode) {\n logLines([\n '',\n ansis.bold('🎉 Great!'),\n `You can run ${fmt.command('varlock load', { jsPackageManager })} to attempt loading your env vars validate against your new schema.`,\n '',\n 'Check out our docs for more info about integrating into your application.',\n '',\n '📖 https://varlock.dev 👈',\n '',\n ]);\n }\n }\n\n // * MAKE SURE VARLOCK IS INSTALLED ------------------------------------------\n if (jsPackageManager && await pathExists(path.join(process.cwd(), 'package.json'))) {\n const installResult = installJsDependency({\n packageManager: jsPackageManager.name,\n packageName: 'varlock',\n });\n if (installResult) {\n logLines([\n '',\n `✅ Added ${fmt.packageName('varlock')} as a dependency in your package.json`,\n ]);\n }\n }\n\n // * CONFIGURE BUNFIG.TOML FOR BUN PROJECTS ----------------------------------\n if (jsPackageManager?.name === 'bun') {\n const bunfigPath = path.join(process.cwd(), 'bunfig.toml');\n const bunfigExists = await pathExists(bunfigPath);\n\n if (bunfigExists) {\n const bunfigContents = await fs.readFile(bunfigPath, 'utf-8');\n // check if `env = false` is already set (allowing for whitespace variations)\n if (!/^\\s*env\\s*=\\s*false\\s*$/m.test(bunfigContents)) {\n await fs.writeFile(bunfigPath, `env = false\\n${bunfigContents}`);\n logLines([\n '',\n `✅ Added ${ansis.bold('env = false')} to your existing ${fmt.fileName('bunfig.toml')}`,\n ansis.dim('This disables Bun\\'s automatic .env loading, which conflicts with Varlock.'),\n ansis.dim(`See ${ansis.underline('https://varlock.dev/integrations/bun')} for more info.`),\n ]);\n }\n } else {\n await fs.writeFile(bunfigPath, 'env = false\\n');\n logLines([\n '',\n `✅ Created ${fmt.fileName('bunfig.toml')} with ${ansis.bold('env = false')}`,\n ansis.dim('This disables Bun\\'s automatic .env loading, which conflicts with Varlock.'),\n ansis.dim(`See ${ansis.underline('https://varlock.dev/integrations/bun')} for more info.`),\n ]);\n }\n }\n};\n"]}
@@ -809,10 +809,13 @@ var VarlockError = class extends Error {
809
809
  }
810
810
  if (my_dash_default.isArray(more?.tip)) more.tip = more.tip.join("\n");
811
811
  this.name = this.constructor.name;
812
- if (more?.isWarning) this.isWarning = true;
812
+ if (more?.severity) {
813
+ this.severity = more.severity;
814
+ } else if (more?.isWarning) {
815
+ this.severity = "warning";
816
+ }
813
817
  this.icon ||= this.constructor.defaultIcon;
814
818
  }
815
- more;
816
819
  static {
817
820
  __name(this, "VarlockError");
818
821
  }
@@ -825,7 +828,7 @@ var VarlockError = class extends Error {
825
828
  }
826
829
  static defaultIcon = "\u274C";
827
830
  icon;
828
- _isWarning = false;
831
+ _severity = "error";
829
832
  get tip() {
830
833
  if (!this.more?.tip) return void 0;
831
834
  if (my_dash_default.isArray(this.more.tip)) return this.more.tip.join("\n");
@@ -840,14 +843,21 @@ var VarlockError = class extends Error {
840
843
  get extraMetadata() {
841
844
  return this.more?.extraMetadata;
842
845
  }
843
- set isWarning(w) {
844
- this._isWarning = w;
845
- if (this._isWarning) {
846
- this.icon = "\u{1F9D0}";
847
- }
846
+ get severity() {
847
+ return this._severity;
848
+ }
849
+ set severity(s) {
850
+ this._severity = s;
851
+ if (s === "warning") this.icon = "\u{1F9D0}";
848
852
  }
849
853
  get isWarning() {
850
- return this._isWarning;
854
+ return this._severity === "warning";
855
+ }
856
+ set isWarning(w) {
857
+ this.severity = w ? "warning" : "error";
858
+ }
859
+ get isFatal() {
860
+ return this._severity === "fatal";
851
861
  }
852
862
  toJSON() {
853
863
  return {
@@ -855,9 +865,10 @@ var VarlockError = class extends Error {
855
865
  type: this.type,
856
866
  name: this.name,
857
867
  message: this.message,
868
+ severity: this.severity,
858
869
  isUnexpected: this.isUnexpected,
859
870
  ...this.tip && { tip: this.tip },
860
- ...this.isWarning && { isWarning: this.isWarning }
871
+ ...this.isWarning && { isWarning: true }
861
872
  };
862
873
  }
863
874
  };
@@ -884,6 +895,12 @@ var ConfigLoadError = class extends VarlockError {
884
895
  };
885
896
  }
886
897
  };
898
+ var LoadingError = class extends VarlockError {
899
+ static {
900
+ __name(this, "LoadingError");
901
+ }
902
+ static defaultIcon = "\u{1F4C2}";
903
+ };
887
904
  var ParseError = class extends VarlockError {
888
905
  static {
889
906
  __name(this, "ParseError");
@@ -1047,6 +1064,6 @@ var pluginProxy = new Proxy({}, {
1047
1064
  });
1048
1065
  //! these are probably not relevant anymore, or needs to move to a plugin layer?
1049
1066
 
1050
- export { CoercionError, ConfigLoadError, EmptyRequiredValueError, ParseError, ResolutionError, SchemaError, ValidationError, VarlockError, activatePlugin, createDebug, deactivatePlugin, my_dash_default, pluginProxy };
1051
- //# sourceMappingURL=chunk-2PFIYNFA.js.map
1052
- //# sourceMappingURL=chunk-2PFIYNFA.js.map
1067
+ export { CoercionError, ConfigLoadError, EmptyRequiredValueError, LoadingError, ParseError, ResolutionError, SchemaError, ValidationError, VarlockError, activatePlugin, createDebug, deactivatePlugin, my_dash_default, pluginProxy };
1068
+ //# sourceMappingURL=chunk-FA5SNEKN.js.map
1069
+ //# sourceMappingURL=chunk-FA5SNEKN.js.map